dbTalk Databases Forums  

pg_usleep

comp.databases.postgresql.patches comp.databases.postgresql.patches


Discuss pg_usleep in the comp.databases.postgresql.patches forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Andrew Dunstan
 
Posts: n/a

Default pg_usleep - 12-30-2003 , 12:58 PM






Tom Lane wrote:

Quote:
Andrew Dunstan <andrew (AT) dunslane (DOT) net> 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 majordomo (AT) postgresql (DOT) org)



Reply With Quote
  #2  
Old   
Claudio Natoli
 
Posts: n/a

Default Re: pg_usleep - 12-30-2003 , 08:33 PM








Quote:
patch + new file attached. Haven't tested on Windows, but
should be fine.
Would be, except for a small typo (conditional operator has an additional :
instead of a ?). Also, we might want to change to SleepEx, depending on how
we eventually get signals implemented, but that's a story for another day.

This, + the pipe() patch from a couple days ago, means we can just about
tick off the "Problems with select()" item on the Win32 TODO list :-)

Cheers,
Claudio


---
Certain disclaimers and policies apply to all email sent from Memetrics.
For the full text of these disclaimers and policies see
<a
href="http://www.memetrics.com/emailpolicy.html">http://www.memetrics.com/em
ailpolicy.html</a>

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org



Reply With Quote
  #3  
Old   
Andrew Dunstan
 
Posts: n/a

Default Re: pg_usleep - 12-31-2003 , 08:12 AM



Claudio Natoli said:
Quote:

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

Would be, except for a small typo (conditional operator has an
additional : instead of a ?).
Darnit. please fix when applying.

Quote:
Also, we might want to change to SleepEx,
depending on how we eventually get signals implemented, but that's a
story for another day.

Yes. If we use a separate thread to catch signal events then only calls in
that thread would need to use SleepEx, no? Anyway, as you say if necessary
it can be adjusted later.

Quote:
This, + the pipe() patch from a couple days ago, means we can just
about tick off the "Problems with select()" item on the Win32 TODO list
:-)

That was the intention :-)

cheers

andrew





---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faqs/FAQ.html



Reply With Quote
  #4  
Old   
Bruce Momjian
 
Posts: n/a

Default Re: pg_usleep - 01-09-2004 , 03:08 PM



Andrew Dunstan wrote:
Quote:
Claudio Natoli said:


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

Would be, except for a small typo (conditional operator has an
additional : instead of a ?).

Darnit. please fix when applying.

Also, we might want to change to SleepEx,
depending on how we eventually get signals implemented, but that's a
story for another day.


Yes. If we use a separate thread to catch signal events then only calls in
that thread would need to use SleepEx, no? Anyway, as you say if necessary
it can be adjusted later.

This, + the pipe() patch from a couple days ago, means we can just
about tick off the "Problems with select()" item on the Win32 TODO list
:-)


That was the intention :-)
OK, Sleep() win32 patch attached and applied. We already had PG_DELAY
in milliseconds, and no one was going anywhere near 2000 seconds
(overflow), so I just converted it to PG_USLEEP and used it consistenly,
with the Win32 Sleep() call added.

--
Bruce Momjian | http://candle.pha.pa.us
pgman (AT) candle (DOT) pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

Index: src/backend/access/transam/xact.c
================================================== =================
RCS file: /cvsroot/pgsql-server/src/backend/access/transam/xact.c,v
retrieving revision 1.159
diff -c -c -r1.159 xact.c
*** src/backend/access/transam/xact.c 7 Jan 2004 18:56:24 -0000 1.159
--- src/backend/access/transam/xact.c 9 Jan 2004 20:59:04 -0000
***************
*** 561,573 ****
*/
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);
}
--- 561,567 ----
*/
if (CommitDelay > 0 && enableFsync &&
CountActiveBackends() >= CommitSiblings)
! PG_USLEEP(CommitDelay);

XLogFlush(recptr);
}
Index: src/backend/storage/buffer/bufmgr.c
================================================== =================
RCS file: /cvsroot/pgsql-server/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.151
diff -c -c -r1.151 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c 7 Jan 2004 18:56:27 -0000 1.151
--- src/backend/storage/buffer/bufmgr.c 9 Jan 2004 20:59:05 -0000
***************
*** 1031,1039 ****
* there was nothing to do at all.
*/
if (n > 0)
! {
! PG_DELAY(BgWriterDelay);
! }
else
sleep(10);
}
--- 1031,1037 ----
* there was nothing to do at all.
*/
if (n > 0)
! PG_USLEEP(BgWriterDelay * 1000);
else
sleep(10);
}
Index: src/backend/storage/lmgr/s_lock.c
================================================== =================
RCS file: /cvsroot/pgsql-server/src/backend/storage/lmgr/s_lock.c,v
retrieving revision 1.23
diff -c -c -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 9 Jan 2004 20:59:06 -0000
***************
*** 19,25 ****
#include <unistd.h>

#include "storage/s_lock.h"
!

/*
* s_lock_stuck() - complain about a stuck spinlock
--- 19,25 ----
#include <unistd.h>

#include "storage/s_lock.h"
! #include "miscadmin.h"

/*
* s_lock_stuck() - complain about a stuck spinlock
***************
*** 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/miscadmin.h
================================================== =================
RCS file: /cvsroot/pgsql-server/src/include/miscadmin.h,v
retrieving revision 1.142
diff -c -c -r1.142 miscadmin.h
*** src/include/miscadmin.h 6 Jan 2004 23:15:22 -0000 1.142
--- src/include/miscadmin.h 9 Jan 2004 20:59:06 -0000
***************
*** 75,108 ****
extern void ProcessInterrupts(void);

#define CHECK_FOR_INTERRUPTS() \
! do { \
! if (InterruptPending) \
! ProcessInterrupts(); \
! } while(0)

#define HOLD_INTERRUPTS() (InterruptHoldoffCount++)

#define RESUME_INTERRUPTS() \
! do { \
! Assert(InterruptHoldoffCount > 0); \
! InterruptHoldoffCount--; \
! } while(0)

#define START_CRIT_SECTION() (CritSectionCount++)

#define END_CRIT_SECTION() \
! do { \
! Assert(CritSectionCount > 0); \
! CritSectionCount--; \
! } while(0)

! #define PG_DELAY(_msec) \
! { \
struct timeval delay; \
! delay.tv_sec = (_msec) / 1000; \
! delay.tv_usec = ((_msec) % 1000) * 1000; \
(void) select(0, NULL, NULL, NULL, &delay); \
! }

/************************************************** ***************************
* globals.h -- *
--- 75,114 ----
extern void ProcessInterrupts(void);

#define CHECK_FOR_INTERRUPTS() \
! do { \
! if (InterruptPending) \
! ProcessInterrupts(); \
! } while(0)

#define HOLD_INTERRUPTS() (InterruptHoldoffCount++)

#define RESUME_INTERRUPTS() \
! do { \
! Assert(InterruptHoldoffCount > 0); \
! InterruptHoldoffCount--; \
! } while(0)

#define START_CRIT_SECTION() (CritSectionCount++)

#define END_CRIT_SECTION() \
! do { \
! Assert(CritSectionCount > 0); \
! CritSectionCount--; \
! } while(0)

! #define PG_USLEEP(_usec) \
! do { \
! #ifndef WIN32
! /* This will overflow on systems with 32-bit ints for > ~2000 secs */ \
struct timeval delay; \
! \
! delay.tv_sec = (_usec) / 1000000; \
! delay.tv_usec = ((_usec) % 1000000); \
(void) select(0, NULL, NULL, NULL, &delay); \
! #else
! Sleep(_usec < 500) ? 1 : (_usec+500)/ 1000);
! #endif
! } while(0)

/************************************************** ***************************
* globals.h -- *


---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo (AT) postgresql (DOT) org so that your
message can get through to the mailing list cleanly



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.