Skip to content

Commit 6aad07d

Browse files
committed
Improve performance of CHECK_FOR_INTERRUPTS() macro on Windows by not doing
a kernel call unless there's some evidence of a pending signal. This should bring its performance on Windows into line with the Unix version. Problem diagnosis and patch by Qingqing Zhou. Minor stylistic tweaks by moi ... if it's broken, it's my fault.
1 parent fdff883 commit 6aad07d

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

src/backend/port/win32/signal.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.12 2005/10/15 02:49:23 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.13 2005/10/21 21:43:45 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -15,18 +15,26 @@
1515

1616
#include <libpq/pqsignal.h>
1717

18+
/*
19+
* These are exported for use by the UNBLOCKED_SIGNAL_QUEUE() macro.
20+
* pg_signal_queue must be volatile since it is changed by the signal
21+
* handling thread and inspected without any lock by the main thread.
22+
* pg_signal_mask is only changed by main thread so shouldn't need it.
23+
*/
24+
volatile int pg_signal_queue;
25+
int pg_signal_mask;
1826

19-
/* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
20-
* variable that can be accessed from the signal sending threads! */
27+
HANDLE pgwin32_signal_event;
28+
HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
29+
30+
/*
31+
* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
32+
* variable that can be accessed from the signal sending threads!
33+
*/
2134
static CRITICAL_SECTION pg_signal_crit_sec;
22-
static int pg_signal_queue;
2335

2436
static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];
2537
static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
26-
static int pg_signal_mask;
27-
28-
DLLIMPORT HANDLE pgwin32_signal_event;
29-
HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
3038

3139

3240
/* Signal handling thread function */
@@ -81,21 +89,31 @@ pgwin32_signal_initialize(void)
8189
(errmsg_internal("failed to set console control handler")));
8290
}
8391

92+
/*
93+
* Support routine for CHECK_FOR_INTERRUPTS() macro
94+
*/
95+
void
96+
pgwin32_check_queued_signals(void)
97+
{
98+
if (WaitForSingleObjectEx(pgwin32_signal_event, 0, TRUE) == WAIT_OBJECT_0)
99+
pgwin32_dispatch_queued_signals();
100+
}
84101

85-
/* Dispatch all signals currently queued and not blocked
102+
/*
103+
* Dispatch all signals currently queued and not blocked
86104
* Blocked signals are ignored, and will be fired at the time of
87-
* the sigsetmask() call. */
105+
* the sigsetmask() call.
106+
*/
88107
void
89108
pgwin32_dispatch_queued_signals(void)
90109
{
91110
int i;
92111

93112
EnterCriticalSection(&pg_signal_crit_sec);
94-
while (pg_signal_queue & ~pg_signal_mask)
113+
while (UNBLOCKED_SIGNAL_QUEUE())
95114
{
96115
/* One or more unblocked signals queued for execution */
97-
98-
int exec_mask = pg_signal_queue & ~pg_signal_mask;
116+
int exec_mask = UNBLOCKED_SIGNAL_QUEUE();
99117

100118
for (i = 0; i < PG_SIGNAL_COUNT; i++)
101119
{

src/include/miscadmin.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.180 2005/10/15 02:49:41 momjian Exp $
16+
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.181 2005/10/21 21:43:46 tgl Exp $
1717
*
1818
* NOTES
1919
* some of the information in this file should be moved to other files.
@@ -83,15 +83,17 @@ do { \
8383
if (InterruptPending) \
8484
ProcessInterrupts(); \
8585
} while(0)
86+
8687
#else /* WIN32 */
8788

8889
#define CHECK_FOR_INTERRUPTS() \
8990
do { \
90-
if (WaitForSingleObjectEx(pgwin32_signal_event,0,TRUE) == WAIT_OBJECT_0) \
91-
pgwin32_dispatch_queued_signals(); \
91+
if (UNBLOCKED_SIGNAL_QUEUE()) \
92+
pgwin32_check_queued_signals(); \
9293
if (InterruptPending) \
9394
ProcessInterrupts(); \
9495
} while(0)
96+
9597
#endif /* WIN32 */
9698

9799

src/include/port/win32.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.47 2005/10/15 02:49:45 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.48 2005/10/21 21:43:46 tgl Exp $ */
22

33
/* undefine and redefine after #include */
44
#undef mkdir
@@ -214,11 +214,17 @@ typedef int pid_t;
214214

215215

216216
/* In backend/port/win32/signal.c */
217-
extern DLLIMPORT HANDLE pgwin32_signal_event;
217+
extern DLLIMPORT volatile int pg_signal_queue;
218+
extern DLLIMPORT int pg_signal_mask;
219+
extern HANDLE pgwin32_signal_event;
218220
extern HANDLE pgwin32_initial_signal_pipe;
219221

222+
#define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask)
223+
224+
220225
void pgwin32_signal_initialize(void);
221226
HANDLE pgwin32_create_signal_listener(pid_t pid);
227+
void pgwin32_check_queued_signals(void);
222228
void pgwin32_dispatch_queued_signals(void);
223229
void pg_queue_signal(int signum);
224230

0 commit comments

Comments
 (0)