Tom Lane wrote:

Andrew Dunstan <[EMAIL PROTECTED]> writes:


I wrote:


There are a couple of other places where [select()] is used for small sleeps (storage/lmgr/s_lock.c and access/transam/xact.c) -





What is the preferred way to handle these 2 cases? We could handle them with #ifdef'd code inline, or create a new function pg_usleep(), or possibly handle it with conditional macros inline. If a new function or macro, where should they go?



I'd go with a new function. There is no reason to try to "optimize" this code by putting it inline; if you're trying to delay, another few nanoseconds to enter a subroutine doesn't matter.

As for where, maybe make a new file in src/port/.  That would make it
relatively easy to use the same function in client-side code if we
needed to.



patch + new file attached. Haven't tested on Windows, but should be fine.

cheers

andrew
/*-------------------------------------------------------------------------
 *
 * pg_usleep.c
 *    platform independent version of usleep
 *
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 *
 *  Uses select() everywhere except for Windows, where it doesn't work
 *
 * IDENTIFICATION
 *    $PostgreSQL$
 *
 *-------------------------------------------------------------------------
 */


#include "postgres.h"

#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/time.h>
#endif

void
pg_usleep (unsigned int usecs)
{

#ifdef WIN32
        Sleep(usecs < 500 : 1 : (usecs+500)/ 1000);
#else
        struct timeval tv;

        tv.tv_sec = usecs / 1000000;
        tv.tv_usec = usecs % 1000000;
        select(0,NULL,NULL,NULL,&tv);
        
#endif

}
Index: src/Makefile.global.in
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/Makefile.global.in,v
retrieving revision 1.172
diff -c -w -r1.172 Makefile.global.in
*** src/Makefile.global.in      19 Dec 2003 23:29:15 -0000      1.172
--- src/Makefile.global.in      30 Dec 2003 18:50:56 -0000
***************
*** 342,348 ****
  #
  # substitute implementations of the C library
  
! LIBOBJS = @LIBOBJS@ path.o sprompt.o thread.o
  
  ifneq (,$(LIBOBJS))
  LIBS += -lpgport
--- 342,348 ----
  #
  # substitute implementations of the C library
  
! LIBOBJS = @LIBOBJS@ path.o sprompt.o thread.o pg_usleep.o
  
  ifneq (,$(LIBOBJS))
  LIBS += -lpgport
Index: src/backend/access/transam/xact.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/access/transam/xact.c,v
retrieving revision 1.158
diff -c -w -r1.158 xact.c
*** src/backend/access/transam/xact.c   2 Dec 2003 19:26:47 -0000       1.158
--- src/backend/access/transam/xact.c   30 Dec 2003 18:50:56 -0000
***************
*** 562,572 ****
                        if (CommitDelay > 0 && enableFsync &&
                                CountActiveBackends() >= CommitSiblings)
                        {
!                               struct timeval delay;
! 
!                               delay.tv_sec = 0;
!                               delay.tv_usec = CommitDelay;
!                               (void) select(0, NULL, NULL, NULL, &delay);
                        }
  
                        XLogFlush(recptr);
--- 562,569 ----
                        if (CommitDelay > 0 && enableFsync &&
                                CountActiveBackends() >= CommitSiblings)
                        {
!                               /* call platform independent usleep */
!                               pg_usleep(CommitDelay);
                        }
  
                        XLogFlush(recptr);
Index: src/backend/storage/lmgr/s_lock.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/storage/lmgr/s_lock.c,v
retrieving revision 1.23
diff -c -w -r1.23 s_lock.c
*** src/backend/storage/lmgr/s_lock.c   27 Dec 2003 20:58:58 -0000      1.23
--- src/backend/storage/lmgr/s_lock.c   30 Dec 2003 18:50:56 -0000
***************
*** 46,52 ****
  s_lock(volatile slock_t *lock, const char *file, int line)
  {
        /*
!        * We loop tightly for awhile, then delay using select() and try
         * again. Preferably, "awhile" should be a small multiple of the
         * maximum time we expect a spinlock to be held.  100 iterations seems
         * about right.  In most multi-CPU scenarios, the spinlock is probably
--- 46,52 ----
  s_lock(volatile slock_t *lock, const char *file, int line)
  {
        /*
!        * We loop tightly for awhile, then delay using pg_usleep() and try
         * again. Preferably, "awhile" should be a small multiple of the
         * maximum time we expect a spinlock to be held.  100 iterations seems
         * about right.  In most multi-CPU scenarios, the spinlock is probably
***************
*** 84,90 ****
        int                     spins = 0;
        int                     delays = 0;
        int                     cur_delay = MIN_DELAY_CSEC;
-       struct timeval delay;
  
        while (TAS(lock))
        {
--- 84,89 ----
***************
*** 97,105 ****
                        if (++delays > NUM_DELAYS)
                                s_lock_stuck(lock, file, line);
  
!                       delay.tv_sec = cur_delay / 100;
!                       delay.tv_usec = (cur_delay % 100) * 10000;
!                       (void) select(0, NULL, NULL, NULL, &delay);
  
  #if defined(S_LOCK_TEST)
                        fprintf(stdout, "*");
--- 96,102 ----
                        if (++delays > NUM_DELAYS)
                                s_lock_stuck(lock, file, line);
  
!                       pg_usleep(cur_delay * 10000);
  
  #if defined(S_LOCK_TEST)
                        fprintf(stdout, "*");
Index: src/include/port.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.15
diff -c -w -r1.15 port.h
*** src/include/port.h  29 Nov 2003 22:40:53 -0000      1.15
--- src/include/port.h  30 Dec 2003 18:50:56 -0000
***************
*** 122,124 ****
--- 122,127 ----
                                char *buffer, size_t buflen,
                                struct hostent **result,
                                int *herrno);
+ 
+ extern void pg_usleep(unsigned int usecs);
+ 
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])

Reply via email to