Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance - Mailing list pgsql-hackers

From Qingqing Zhou
Subject Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance
Date
Msg-id Pine.LNX.4.58.0510222325400.17162@eon.cs
Whole thread Raw
In response to Re: [PATCHES] Win32 CHECK_FOR_INTERRUPTS() performance  (Qingqing Zhou <zhouqq@cs.toronto.edu>)
List pgsql-hackers
Here is the full patch of the timer implemenation with threading safty
added. Basic test is by several rounds of "make check"  and threading
safty test is by a SQL file with many lines of "set statement_timeout =
x". I don't know if there are any corner cases that I should consider, if
any, let me know.

Regards,
Qingqing

---

Index: timer.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/port/win32/timer.c,v
retrieving revision 1.5
diff -c -r1.5 timer.c
*** timer.c    31 Dec 2004 22:00:37 -0000    1.5
--- timer.c    23 Oct 2005 03:04:53 -0000
***************
*** 15,22 ****
--- 15,31 ----
 #include "libpq/pqsignal.h"

+ /* Communication area of timer settings */
+ typedef struct timerCA{
+     int which;
+     struct itimerval value;
+     HANDLE event;
+     CRITICAL_SECTION crit_sec;
+ }timerCA;

+ static timerCA timerCommArea; static HANDLE timerHandle = INVALID_HANDLE_VALUE;
+ static HANDLE timerThreadHandle = INVALID_HANDLE_VALUE;
 static VOID CALLBACK timer_completion(LPVOID arg, DWORD timeLow, DWORD timeHigh)
***************
*** 24,43 ****     pg_queue_signal(SIGALRM); }

- /*  * Limitations of this implementation:  *
-  * - Does not support setting ovalue  * - Does not support interval timer (value->it_interval)  * - Only supports
ITIMER_REAL */
 
! int
! setitimer(int which, const struct itimerval * value, struct itimerval * ovalue) {     LARGE_INTEGER dueTime;

-     Assert(ovalue == NULL);     Assert(value != NULL);     Assert(value->it_interval.tv_sec == 0 &&
value->it_interval.tv_usec== 0);     Assert(which == ITIMER_REAL);
 
--- 33,49 ----     pg_queue_signal(SIGALRM); }
 /*  * Limitations of this implementation:  *  * - Does not support interval timer (value->it_interval)  * - Only
supportsITIMER_REAL  */
 
! static int
! do_setitimer(int which, const struct itimerval * value) {     LARGE_INTEGER dueTime;
     Assert(value != NULL);     Assert(value->it_interval.tv_sec == 0 && value->it_interval.tv_usec == 0);
Assert(which== ITIMER_REAL);
 
***************
*** 69,71 ****
--- 75,136 ----
     return 0; }
+
+ /* Timer ticking thread */
+ static DWORD WINAPI
+ pg_timer_thread(LPVOID param)
+ {
+     Assert(param == NULL);
+
+     for (;;)
+     {
+         if (WaitForSingleObjectEx(timerCommArea.event, INFINITE, TRUE) == WAIT_OBJECT_0)
+         {
+             EnterCriticalSection(&timerCommArea.crit_sec);
+             do_setitimer(timerCommArea.which,
+                         &timerCommArea.value);
+             ResetEvent(timerCommArea.event);
+             LeaveCriticalSection(&timerCommArea.crit_sec);
+         }
+     }
+
+     return 0;
+ }
+
+ /*
+  * Win32 setitimer emulation by creating a persistent thread
+  * to handle the timer setting and notification upon timeout.
+  */
+ int
+ setitimer(int which, const struct itimerval * value, struct itimerval * ovalue)
+ {
+     Assert(value != NULL);
+
+     if (timerThreadHandle == INVALID_HANDLE_VALUE)
+     {
+         /* First call in this backend, create event and the timer thread */
+         timerCommArea.event = CreateEvent(NULL, TRUE, FALSE, NULL);
+         if (timerCommArea.event == NULL)
+             ereport(FATAL,
+                 (errmsg_internal("failed to create timer event: %d", (int) GetLastError())));
+         MemSet(&timerCommArea.value, 0, sizeof(struct itimerval));
+         InitializeCriticalSection(&timerCommArea.crit_sec);
+
+         timerThreadHandle = CreateThread(NULL, 0, pg_timer_thread, NULL, 0, NULL);
+         if (timerThreadHandle == INVALID_HANDLE_VALUE)
+             ereport(FATAL,
+                 (errmsg_internal("failed to create timer thread: %d", (int) GetLastError())));
+     }
+
+     /* Request the timer thread to change settings */
+     EnterCriticalSection(&timerCommArea.crit_sec);
+     if (ovalue)
+         *ovalue = timerCommArea.value;
+     timerCommArea.which = which;
+     timerCommArea.value = *value;
+     LeaveCriticalSection(&timerCommArea.crit_sec);
+     SetEvent(timerCommArea.event);
+
+     /* Timer thread will handle possible errors */
+     return 0;
+ }


pgsql-hackers by date:

Previous
From: "Marc G. Fournier"
Date:
Subject: 8.1 Beta 4 Bundled ...
Next
From: Andrew - Supernews
Date:
Subject: Re: Differences in UTF8 between 8.0 and 8.1