Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance tweak

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance tweak
Дата
Msg-id 26073.1129931207@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance tweak  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance  (Andrew Dunstan <andrew@dunslane.net>)
Список pgsql-hackers
I wrote:
> BTW, expanding on Andrew's comment, ISTM we could move the kernel call
> out of the macro, ie make it look like ...

I've applied the attached version of Qingqing's revised patch.  I'm not
in a position to test it, and am about to go out for the evening, but if
anyone can check the committed version soon and verify that I didn't
break anything ...

(BTW, DLLIMPORT is only needed in extern declarations, not in the actual
definition of the variable.)
        regards, tom lane

*** src/backend/port/win32/signal.c.orig    Fri Oct 14 22:59:56 2005
--- src/backend/port/win32/signal.c    Fri Oct 21 17:36:24 2005
***************
*** 15,32 ****  #include <libpq/pqsignal.h> 
! 
! /* 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 */
--- 15,40 ----  #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;
! 
! 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 pqsigfunc pg_signal_array[PG_SIGNAL_COUNT]; static pqsigfunc
pg_signal_defaults[PG_SIGNAL_COUNT];  /* Signal handling thread function */
 
***************
*** 81,101 ****                 (errmsg_internal("failed to set console control handler"))); }  
! /* Dispatch all signals currently queued and not blocked  * Blocked signals are ignored, and will be fired at the
timeof
 
!  * the sigsetmask() call. */ void pgwin32_dispatch_queued_signals(void) {     int            i;
EnterCriticalSection(&pg_signal_crit_sec);
!     while (pg_signal_queue & ~pg_signal_mask)     {         /* One or more unblocked signals queued for execution */
! 
!         int            exec_mask = pg_signal_queue & ~pg_signal_mask;          for (i = 0; i < PG_SIGNAL_COUNT; i++)
      {
 
--- 89,119 ----                 (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  * Blocked signals are ignored, and will be fired at the
timeof
 
!  * the sigsetmask() call.
!  */ void pgwin32_dispatch_queued_signals(void) {     int            i;
EnterCriticalSection(&pg_signal_crit_sec);
!     while (UNBLOCKED_SIGNAL_QUEUE())     {         /* One or more unblocked signals queued for execution */
!         int            exec_mask = UNBLOCKED_SIGNAL_QUEUE();          for (i = 0; i < PG_SIGNAL_COUNT; i++)
{
*** src/include/miscadmin.h.orig    Fri Oct 14 23:00:22 2005
--- src/include/miscadmin.h    Fri Oct 21 17:36:18 2005
***************
*** 83,97 ****     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 (InterruptPending) \         ProcessInterrupts(); \ } while(0)
#endif  /* WIN32 */  
 
--- 83,99 ----     if (InterruptPending) \         ProcessInterrupts(); \ } while(0)
+  #else                            /* WIN32 */  #define CHECK_FOR_INTERRUPTS() \ do { \
!     if (UNBLOCKED_SIGNAL_QUEUE()) \
!         pgwin32_check_queued_signals(); \     if (InterruptPending) \         ProcessInterrupts(); \ } while(0)
+  #endif   /* WIN32 */  
*** src/include/port/win32.h.orig    Fri Oct 14 23:00:30 2005
--- src/include/port/win32.h    Fri Oct 21 17:36:12 2005
***************
*** 214,224 ****   /* In backend/port/win32/signal.c */
! extern DLLIMPORT HANDLE pgwin32_signal_event; extern HANDLE pgwin32_initial_signal_pipe;  void
pgwin32_signal_initialize(void);HANDLE        pgwin32_create_signal_listener(pid_t pid); void
pgwin32_dispatch_queued_signals(void);void        pg_queue_signal(int signum); 
 
--- 214,230 ----   /* In backend/port/win32/signal.c */
! 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(intsignum); 
 


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Neil Conway
Дата:
Сообщение: Re: [COMMITTERS] pgsql: Do all accesses to shared buffer
Следующее
От: Tom Lane
Дата:
Сообщение: Re: [COMMITTERS] pgsql: Do all accesses to shared buffer