]> granicus.if.org Git - postgresql/commitdiff
Improve performance of CHECK_FOR_INTERRUPTS() macro on Windows by not doing
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Oct 2005 21:43:46 +0000 (21:43 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Oct 2005 21:43:46 +0000 (21:43 +0000)
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.

src/backend/port/win32/signal.c
src/include/miscadmin.h
src/include/port/win32.h

index a32427f28f58cf668370e694d6c731d7b18cbc45..fa7d8cf6a2c0f5305067ef4fdfcd472afeaf6621 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.12 2005/10/15 02:49:23 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.13 2005/10/21 21:43:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include <libpq/pqsignal.h>
 
+/*
+ * These are exported for use by the UNBLOCKED_SIGNAL_QUEUE() macro.
+ * pg_signal_queue must be volatile since it is changed by the signal
+ * handling thread and inspected without any lock by the main thread.
+ * pg_signal_mask is only changed by main thread so shouldn't need it.
+ */
+volatile int pg_signal_queue;
+int            pg_signal_mask;
 
-/* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
- * variable that can be accessed from the signal sending threads! */
+HANDLE pgwin32_signal_event;
+HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
+
+/*
+ * pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
+ * variable that can be accessed from the signal sending threads!
+ */
 static CRITICAL_SECTION pg_signal_crit_sec;
-static int     pg_signal_queue;
 
 static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];
 static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
-static int     pg_signal_mask;
-
-DLLIMPORT HANDLE pgwin32_signal_event;
-HANDLE         pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
 
 
 /* Signal handling thread function */
@@ -81,21 +89,31 @@ pgwin32_signal_initialize(void)
                                (errmsg_internal("failed to set console control handler")));
 }
 
+/*
+ * Support routine for CHECK_FOR_INTERRUPTS() macro
+ */
+void
+pgwin32_check_queued_signals(void)
+{
+       if (WaitForSingleObjectEx(pgwin32_signal_event, 0, TRUE) == WAIT_OBJECT_0)
+               pgwin32_dispatch_queued_signals();
+}
 
-/* Dispatch all signals currently queued and not blocked
+/*
+ * Dispatch all signals currently queued and not blocked
  * Blocked signals are ignored, and will be fired at the time of
- * the sigsetmask() call. */
+ * the sigsetmask() call.
+ */
 void
 pgwin32_dispatch_queued_signals(void)
 {
        int                     i;
 
        EnterCriticalSection(&pg_signal_crit_sec);
-       while (pg_signal_queue & ~pg_signal_mask)
+       while (UNBLOCKED_SIGNAL_QUEUE())
        {
                /* One or more unblocked signals queued for execution */
-
-               int                     exec_mask = pg_signal_queue & ~pg_signal_mask;
+               int                     exec_mask = UNBLOCKED_SIGNAL_QUEUE();
 
                for (i = 0; i < PG_SIGNAL_COUNT; i++)
                {
index a2a802cacce55db961bccb477a18421e93f81c84..10f75197550f342685f8db5b339b68f495428652 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.180 2005/10/15 02:49:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.181 2005/10/21 21:43:46 tgl Exp $
  *
  * NOTES
  *       some of the information in this file should be moved to other files.
@@ -83,15 +83,17 @@ do { \
        if (InterruptPending) \
                ProcessInterrupts(); \
 } while(0)
+
 #else                                                  /* WIN32 */
 
 #define CHECK_FOR_INTERRUPTS() \
 do { \
-       if (WaitForSingleObjectEx(pgwin32_signal_event,0,TRUE) == WAIT_OBJECT_0) \
-               pgwin32_dispatch_queued_signals(); \
+       if (UNBLOCKED_SIGNAL_QUEUE()) \
+               pgwin32_check_queued_signals(); \
        if (InterruptPending) \
                ProcessInterrupts(); \
 } while(0)
+
 #endif   /* WIN32 */
 
 
index 44c449443a2e75982da63f4e289376e71bfa6775..9d1a6da6c6c23c9c6de3ace4fd2f6bc8b0d4e62d 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.47 2005/10/15 02:49:45 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.48 2005/10/21 21:43:46 tgl Exp $ */
 
 /* undefine and redefine after #include */
 #undef mkdir
@@ -214,11 +214,17 @@ typedef int pid_t;
 
 
 /* In backend/port/win32/signal.c */
-extern DLLIMPORT HANDLE pgwin32_signal_event;
+extern DLLIMPORT volatile int pg_signal_queue;
+extern DLLIMPORT int pg_signal_mask;
+extern HANDLE pgwin32_signal_event;
 extern HANDLE pgwin32_initial_signal_pipe;
 
+#define UNBLOCKED_SIGNAL_QUEUE()       (pg_signal_queue & ~pg_signal_mask)
+
+
 void           pgwin32_signal_initialize(void);
 HANDLE         pgwin32_create_signal_listener(pid_t pid);
+void           pgwin32_check_queued_signals(void);
 void           pgwin32_dispatch_queued_signals(void);
 void           pg_queue_signal(int signum);