mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Major screwed up s_lock patches...need to be fixed...
This commit is contained in:
parent
f8b4a25fd7
commit
1d36bdcfa6
@ -4,7 +4,7 @@
|
|||||||
# Makefile for storage/buffer
|
# Makefile for storage/buffer
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/storage/buffer/Makefile,v 1.8 1998/04/29 12:37:51 scrappy Exp $
|
# $Header: /cvsroot/pgsql/src/backend/storage/buffer/Makefile,v 1.9 1998/05/04 15:44:39 scrappy Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -24,11 +24,11 @@ depend dep:
|
|||||||
$(CC) -MM $(CFLAGS) *.c >depend
|
$(CC) -MM $(CFLAGS) *.c >depend
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f SUBSYS.o $(OBJS) tas_test
|
rm -f SUBSYS.o $(OBJS) s_lock_test
|
||||||
|
|
||||||
tas_test: s_lock.c
|
s_lock_test: s_lock.c
|
||||||
$(CC) $(CFLAGS) -DTAS_TEST=1 -g s_lock.c -o tas_test
|
$(CC) $(CFLAGS) -DS_LOCK_TEST=1 -g s_lock.c -o s_lock_test
|
||||||
./tas_test
|
./s_lock_test
|
||||||
|
|
||||||
ifeq (depend,$(wildcard depend))
|
ifeq (depend,$(wildcard depend))
|
||||||
include depend
|
include depend
|
||||||
|
@ -7,46 +7,97 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.4 1998/04/27 14:43:15 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.5 1998/05/04 15:44:41 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "c.h"
|
||||||
|
#include "storage/s_lock.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* S_LOCK() -- Implements the S_LOCK function for the Linux/Alpha platform.
|
* Each time we busy spin we select the next element of this array as the
|
||||||
* This function is usually an inlined macro for all other platforms,
|
* number of microseconds to wait. This accomplishes pseudo random back-off.
|
||||||
* but must be a seperate function for the Linux/Alpha platform, due
|
* Values are not critical and are weighted to the low end of the range. They
|
||||||
* to the assembly code involved.
|
* were chosen to work even with different select() timer resolutions on
|
||||||
|
* different platforms.
|
||||||
|
* note: total time to cycle through all 16 entries might be about .1 second.
|
||||||
|
*/
|
||||||
|
int s_spincycle[S_NSPINCYCLE] =
|
||||||
|
{0, 0, 0, 1000, 5000, 0, 10000, 3000,
|
||||||
|
0, 10000, 0, 15000, 9000, 21000, 6000, 30000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(S_LOCK_DEBUG)
|
||||||
|
/*
|
||||||
|
* s_lock(lock) - take a spinlock
|
||||||
|
* add intrumentation code to this and define S_LOCK_DEBUG
|
||||||
|
* instead of hacking up the macro in s_lock.h
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
s_lock(slock_t *lock, char *file, int line)
|
||||||
|
{
|
||||||
|
int spins = 0;
|
||||||
|
|
||||||
|
while (TAS(lock))
|
||||||
|
{
|
||||||
|
struct timeval delay;
|
||||||
|
|
||||||
|
delay.tv_sec = 0;
|
||||||
|
delay.tv_usec = s_spincycle[spins++ % S_NSPINCYCLE];
|
||||||
|
(void) select(0, NULL, NULL, NULL, &delay);
|
||||||
|
if (spins > S_MAX_BUSY)
|
||||||
|
{
|
||||||
|
/* It's been well over a minute... */
|
||||||
|
s_lock_stuck(lock, file, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* S_LOCK_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_lock_stuck(lock) - deal with stuck spinlock
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
s_lock_stuck(slock_t *lock, char *file, int line)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nFATAL: s_lock(%08x) at %s:%d, stuck spinlock. Aborting.\n",
|
||||||
|
(unsigned int) lock, file, line);
|
||||||
|
fprintf(stdout,
|
||||||
|
"\nFATAL: s_lock(%08x) at %s:%d, stuck spinlock. Aborting.\n",
|
||||||
|
(unsigned int) lock, file, line);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various TAS implementations moved from s_lock.h to avoid redundant
|
||||||
|
* definitions of the same routine.
|
||||||
|
* RESOLVE: move this to tas.c. Alternatively get rid of tas.[cso] and fold
|
||||||
|
* all that into this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#if defined(linux)
|
||||||
#include <sys/file.h>
|
/*************************************************************************
|
||||||
#include <stdio.h>
|
* All the Linux flavors
|
||||||
#include <string.h>
|
*/
|
||||||
#include <math.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
/* declarations split between these three files */
|
#if defined(__alpha__)
|
||||||
#include "storage/buf.h"
|
int
|
||||||
#include "storage/buf_internals.h"
|
tas(slock_t *lock)
|
||||||
#include "storage/bufmgr.h"
|
|
||||||
|
|
||||||
#include "storage/fd.h"
|
|
||||||
#include "storage/ipc.h"
|
|
||||||
#include "storage/s_lock.h"
|
|
||||||
|
|
||||||
#if defined(__alpha) && defined(linux)
|
|
||||||
void
|
|
||||||
S_LOCK(slock_t *lock)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
slock_t _res;
|
slock_t _res;
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
__asm__(" ldq $0, %0 \n\
|
__asm__(" ldq $0, %0 \n\
|
||||||
bne $0, already_set \n\
|
bne $0, already_set \n\
|
||||||
ldq_l $0, %0 \n\
|
ldq_l $0, %0 \n\
|
||||||
@ -60,8 +111,230 @@ S_LOCK(slock_t *lock)
|
|||||||
stqc_fail: or $31, 1, $0 \n\
|
stqc_fail: or $31, 1, $0 \n\
|
||||||
already_set: bis $0, $0, %1 \n\
|
already_set: bis $0, $0, %1 \n\
|
||||||
end: nop ": "=m"(*lock), "=r"(_res): :"0");
|
end: nop ": "=m"(*lock), "=r"(_res): :"0");
|
||||||
} while (_res != 0);
|
|
||||||
} while (0);
|
return (_res != 0);
|
||||||
|
}
|
||||||
|
#endif /* __alpha__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(i386)
|
||||||
|
int
|
||||||
|
tas(slock_t *lock)
|
||||||
|
{
|
||||||
|
slock_t _res = 1;
|
||||||
|
|
||||||
|
__asm__("lock; xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1));
|
||||||
|
return (_res != 0);
|
||||||
|
}
|
||||||
|
#endif /* i386 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(sparc)
|
||||||
|
|
||||||
|
int
|
||||||
|
tas(slock_t *lock)
|
||||||
|
{
|
||||||
|
slock_t _res;
|
||||||
|
slock_t *tmplock = lock;
|
||||||
|
|
||||||
|
__asm__("ldstub [%1], %0" \
|
||||||
|
: "=&r"(_res), "=r"(tmplock) \
|
||||||
|
: "1"(tmplock));
|
||||||
|
return (_res != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* sparc */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(PPC)
|
||||||
|
|
||||||
|
static int
|
||||||
|
tas_dummy()
|
||||||
|
{
|
||||||
|
__asm__(" \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 /* PPC */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else /* defined(linux) */
|
||||||
|
/***************************************************************************
|
||||||
|
* All Non-Linux
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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)
|
||||||
|
/*
|
||||||
|
* bsd and bsdi sparc machines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* if we're using -ansi w/ gcc, use __asm__ instead of asm */
|
||||||
|
#if defined(__STRICT_ANSI__)
|
||||||
|
#define asm(x) __asm__(x)
|
||||||
|
#endif /* __STRICT_ANSI__ */
|
||||||
|
|
||||||
|
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_VAX_TAS_ASM)
|
||||||
|
/*
|
||||||
|
* VAXen -- even multiprocessor ones
|
||||||
|
* (thanks to Tom Ivar Helbekkmo)
|
||||||
|
*/
|
||||||
|
typedef unsigned char slock_t;
|
||||||
|
|
||||||
|
int
|
||||||
|
tas(slock_t *lock)
|
||||||
|
{
|
||||||
|
register ret;
|
||||||
|
|
||||||
|
asm(" movl $1, r0
|
||||||
|
bbssi $0, (%1), 1f
|
||||||
|
clrl r0
|
||||||
|
1: movl r0, %0 "
|
||||||
|
: "=r"(ret) /* return value, in register */
|
||||||
|
: "r"(lock) /* argument, 'lock pointer', in register */
|
||||||
|
: "r0"); /* inline code uses this register */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NEED_VAX_TAS_ASM */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(NEED_I386_TAS_ASM)
|
||||||
|
/*
|
||||||
|
* i386 based things
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(USE_UNIVEL_CC)
|
||||||
|
asm int
|
||||||
|
tas(slock_t *s_lock)
|
||||||
|
{
|
||||||
|
%lab locked;
|
||||||
|
/* Upon entry, %eax will contain the pointer to the lock byte */
|
||||||
|
pushl % ebx
|
||||||
|
xchgl % eax, %ebx
|
||||||
|
xor % eax, %eax
|
||||||
|
movb $255, %al
|
||||||
|
lock
|
||||||
|
xchgb % al, (%ebx)
|
||||||
|
popl % ebx
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else /* USE_UNIVEL_CC */
|
||||||
|
|
||||||
|
int
|
||||||
|
tas(slock_t *lock)
|
||||||
|
{
|
||||||
|
slock_t _res = 1;
|
||||||
|
|
||||||
|
__asm__("lock; xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1));
|
||||||
|
return (_res != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_UNIVEL_CC */
|
||||||
|
|
||||||
|
#endif /* NEED_I386_TAS_ASM */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* linux */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(S_LOCK_TEST)
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
printf("S_LOCK_TEST: failed, lock not locked~\n");
|
||||||
|
exit(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* S_LOCK_TEST */
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#if defined(PPC)
|
#if defined(PPC)
|
||||||
typedef unsigned int slock_t;
|
typedef unsigned int slock_t;
|
||||||
|
|
||||||
#elif defined(__alpha)
|
#elif defined(__alpha__)
|
||||||
typedef long int slock_t;
|
typedef long int slock_t;
|
||||||
|
|
||||||
#else /* i386 probably */
|
#else /* i386 probably */
|
||||||
@ -33,14 +33,6 @@ typedef unsigned char slock_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PPC)
|
#if defined(PPC)
|
||||||
#undef NEED_I386_TAS_ASM
|
|
||||||
#undef HAVE_INT_TIMEZONE
|
#undef HAVE_INT_TIMEZONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(sparc)
|
|
||||||
#undef NEED_I386_TAS_ASM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__alpha)
|
|
||||||
#undef NEED_I386_TAS_ASM
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user