diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-09-27 19:10:02 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-09-27 19:10:02 +0000 |
| commit | 90aebf7f5242b11bc9576f5d9052d755336b1bcc (patch) | |
| tree | dbc549709f897a737f5e799986674c5cea4617b3 /src/backend/storage/buffer | |
| parent | 3d59ad00e8cc6a1bd919280be839fca152149ec2 (diff) | |
Move s_lock.c and spin.c into lmgr subdirectory, which seems a much
more reasonable location for them.
Diffstat (limited to 'src/backend/storage/buffer')
| -rw-r--r-- | src/backend/storage/buffer/Makefile | 10 | ||||
| -rw-r--r-- | src/backend/storage/buffer/s_lock.c | 364 |
2 files changed, 3 insertions, 371 deletions
diff --git a/src/backend/storage/buffer/Makefile b/src/backend/storage/buffer/Makefile index 54bf25e1377..217f2eafb3c 100644 --- a/src/backend/storage/buffer/Makefile +++ b/src/backend/storage/buffer/Makefile @@ -4,7 +4,7 @@ # Makefile for storage/buffer # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/storage/buffer/Makefile,v 1.15 2000/08/31 16:10:30 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/storage/buffer/Makefile,v 1.16 2001/09/27 19:10:02 tgl Exp $ # #------------------------------------------------------------------------- @@ -12,7 +12,7 @@ subdir = src/backend/storage/buffer top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = buf_table.o buf_init.o bufmgr.o freelist.o localbuf.o s_lock.o +OBJS = buf_table.o buf_init.o bufmgr.o freelist.o localbuf.o all: SUBSYS.o @@ -23,11 +23,7 @@ depend dep: $(CC) -MM $(CFLAGS) *.c >depend clean: - rm -f SUBSYS.o $(OBJS) s_lock_test - -s_lock_test: s_lock.c - $(CC) $(CFLAGS) -DS_LOCK_TEST=1 s_lock.c -o s_lock_test - ./s_lock_test + rm -f SUBSYS.o $(OBJS) ifeq (depend,$(wildcard depend)) include depend diff --git a/src/backend/storage/buffer/s_lock.c b/src/backend/storage/buffer/s_lock.c deleted file mode 100644 index f0bfbaa71f1..00000000000 --- a/src/backend/storage/buffer/s_lock.c +++ /dev/null @@ -1,364 +0,0 @@ -/*------------------------------------------------------------------------- - * - * s_lock.c - * Spinlock support routines - * - * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.38 2001/08/29 11:54:12 petere Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include <sys/time.h> -#include <unistd.h> - -#include "miscadmin.h" -#include "storage/s_lock.h" - - -/*---------- - * Each time we busy spin we select the next element of this array as the - * number of microseconds to wait. This accomplishes pseudo random back-off. - * - * Note that on most platforms, specified values will be rounded up to the - * next multiple of a clock tick, which is often ten milliseconds (10000). - * So, we are being way overoptimistic to assume that these different values - * are really different, other than the last. But there are a few platforms - * with better-than-usual timekeeping, and on these we will get pretty good - * pseudo-random behavior. - * - * Total time to cycle through all 20 entries will be at least 100 msec, - * more commonly (10 msec resolution) 220 msec, and on some platforms - * as much as 420 msec (when the remainder of the current tick cycle is - * ignored in deciding when to time out, as on FreeBSD and older Linuxen). - * We use the 100msec figure to figure max_spins, so actual timeouts may - * be as much as four times the nominal value, but will never be less. - *---------- - */ -#define S_NSPINCYCLE 20 - -int s_spincycle[S_NSPINCYCLE] = -{1, 10, 100, 1000, - 10000, 1000, 1000, 1000, - 10000, 1000, 1000, 10000, - 1000, 1000, 10000, 1000, - 10000, 1000, 10000, 30000 -}; - -#define AVG_SPINCYCLE 5000 /* average entry in microsec: 100ms / 20 */ - -#define DEFAULT_TIMEOUT (100*1000000) /* default timeout: 100 sec */ - - -/* - * s_lock_stuck() - complain about a stuck spinlock - */ -static void -s_lock_stuck(volatile slock_t *lock, const char *file, const int line) -{ - fprintf(stderr, - "\nFATAL: s_lock(%p) at %s:%d, stuck spinlock. Aborting.\n", - lock, file, line); - fprintf(stdout, - "\nFATAL: s_lock(%p) at %s:%d, stuck spinlock. Aborting.\n", - lock, file, line); - abort(); -} - - -/* - * s_lock_sleep() - sleep a pseudo-random amount of time, check for timeout - * - * The 'timeout' is given in microsec, or may be 0 for "infinity". Note that - * this will be a lower bound (a fairly loose lower bound, on most platforms). - * - * 'microsec' is the number of microsec to delay per loop. Normally - * 'microsec' is 0, specifying to use the next s_spincycle[] value. - * Some callers may pass a nonzero interval, specifying to use exactly that - * delay value rather than a pseudo-random delay. - */ -void -s_lock_sleep(unsigned spins, int timeout, int microsec, - volatile slock_t *lock, - const char *file, const int line) -{ - struct timeval delay; - - if (microsec > 0) - { - delay.tv_sec = microsec / 1000000; - delay.tv_usec = microsec % 1000000; - } - else - { - delay.tv_sec = 0; - delay.tv_usec = s_spincycle[spins % S_NSPINCYCLE]; - microsec = AVG_SPINCYCLE; /* use average to figure timeout */ - } - - if (timeout > 0) - { - unsigned max_spins = timeout / microsec; - - if (spins > max_spins) - s_lock_stuck(lock, file, line); - } - - (void) select(0, NULL, NULL, NULL, &delay); -} - - -/* - * s_lock(lock) - take a spinlock with backoff - */ -void -s_lock(volatile slock_t *lock, const char *file, const int line) -{ - unsigned spins = 0; - - /* - * If you are thinking of changing this code, be careful. This same - * loop logic is used in other places that call TAS() directly. - * - * While waiting for a lock, we check for cancel/die interrupts (which is - * a no-op if we are inside a critical section). The interrupt check - * can be omitted in places that know they are inside a critical - * section. Note that an interrupt must NOT be accepted after - * acquiring the lock. - */ - while (TAS(lock)) - { - s_lock_sleep(spins++, DEFAULT_TIMEOUT, 0, lock, file, line); - CHECK_FOR_INTERRUPTS(); - } -} - -/* - * Various TAS implementations that cannot live in s_lock.h as no inline - * definition exists (yet). - * In the future, get rid of tas.[cso] and fold it into this file. - */ - - -#if defined(__GNUC__) -/************************************************************************* - * All the gcc flavors that are not inlined - */ - - -#if defined(__m68k__) -static void -tas_dummy() /* really means: extern int tas(slock_t - * **lock); */ -{ - __asm__ __volatile__( - "\ -.global _tas \n\ -_tas: \n\ - movel sp@(0x4),a0 \n\ - tas a0@ \n\ - beq _success \n\ - moveq #-128,d0 \n\ - rts \n\ -_success: \n\ - moveq #0,d0 \n\ - rts \n\ -"); -} - -#endif /* __m68k__ */ - -#if defined(__APPLE__) && defined(__ppc__) -/* used in darwin. */ -/* We key off __APPLE__ here because this function differs from - * the LinuxPPC implementation only in compiler syntax. - */ -static void -tas_dummy() -{ - __asm__ __volatile__( - "\ - .globl tas \n\ - .globl _tas \n\ -_tas: \n\ -tas: \n\ - lwarx r5,0,r3 \n\ - cmpwi r5,0 \n\ - bne fail \n\ - addi r5,r5,1 \n\ - stwcx. r5,0,r3 \n\ - beq success \n\ -fail: li r3,1 \n\ - blr \n\ -success: \n\ - li r3,0 \n\ - blr \n\ -"); -} - -#endif /* __APPLE__ && __ppc__ */ - -#if defined(__powerpc__) -/* Note: need a nice gcc constrained asm version so it can be inlined */ -static void -tas_dummy() -{ - __asm__ __volatile__( - "\ -.global tas \n\ -tas: \n\ - lwarx 5,0,3 \n\ - cmpwi 5,0 \n\ - bne fail \n\ - addi 5,5,1 \n\ - stwcx. 5,0,3 \n\ - beq success \n\ -fail: li 3,1 \n\ - blr \n\ -success: \n\ - li 3,0 \n\ - blr \n\ -"); -} - -#endif /* __powerpc__ */ - -#if defined(__mips__) && !defined(__sgi) -static void -tas_dummy() -{ - __asm__ __volatile__( - "\ -.global tas \n\ -tas: \n\ - .frame $sp, 0, $31 \n\ - ll $14, 0($4) \n\ - or $15, $14, 1 \n\ - sc $15, 0($4) \n\ - beq $15, 0, fail\n\ - bne $14, 0, fail\n\ - li $2, 0 \n\ - .livereg 0x2000FF0E,0x00000FFF \n\ - j $31 \n\ -fail: \n\ - li $2, 1 \n\ - j $31 \n\ -"); -} - -#endif /* __mips__ && !__sgi */ - -#else /* not __GNUC__ */ -/*************************************************************************** - * All non gcc - */ - - - -#if defined(sun3) -static void -tas_dummy() /* really means: extern int tas(slock_t - * *lock); */ -{ - asm("LLA0:"); - asm(" .data"); - asm(" .text"); - asm("|#PROC# 04"); - asm(" .globl _tas"); - asm("_tas:"); - asm("|#PROLOGUE# 1"); - asm(" movel sp@(0x4),a0"); - asm(" tas a0@"); - asm(" beq LLA1"); - asm(" moveq #-128,d0"); - asm(" rts"); - asm("LLA1:"); - asm(" moveq #0,d0"); - asm(" rts"); - asm(" .data"); -} - -#endif /* sun3 */ - - - -#if defined(NEED_SPARC_TAS_ASM) -/* - * sparc machines not using gcc - */ -static void -tas_dummy() /* really means: extern int tas(slock_t - * *lock); */ -{ - asm(".seg \"data\""); - asm(".seg \"text\""); - asm("_tas:"); - - /* - * Sparc atomic test and set (sparc calls it "atomic load-store") - */ - asm("ldstub [%r8], %r8"); - asm("retl"); - asm("nop"); -} - -#endif /* NEED_SPARC_TAS_ASM */ - - - - -#if defined(NEED_I386_TAS_ASM) -/* non gcc i386 based things */ -#endif /* NEED_I386_TAS_ASM */ - - - -#endif /* not __GNUC__ */ - - - - -/*****************************************************************************/ -#if defined(S_LOCK_TEST) - -/* - * test program for verifying a port. - */ - -volatile slock_t test_lock; - -void -main() -{ - S_INIT_LOCK(&test_lock); - - if (!S_LOCK_FREE(&test_lock)) - { - printf("S_LOCK_TEST: failed, lock not initialized.\n"); - exit(1); - } - - S_LOCK(&test_lock); - - if (S_LOCK_FREE(&test_lock)) - { - printf("S_LOCK_TEST: failed, lock not locked\n"); - exit(2); - } - - printf("S_LOCK_TEST: this will hang for a few minutes and then abort\n"); - printf(" with a 'stuck spinlock' message if S_LOCK()\n"); - printf(" and TAS() are working.\n"); - s_lock(&test_lock, __FILE__, __LINE__); - - printf("S_LOCK_TEST: failed, lock not locked~\n"); - exit(3); - -} - -#endif /* S_LOCK_TEST */ |
