⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_lock.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * s_lock.c *	  buffer manager interface routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/storage/buffer/s_lock.c,v 1.21 1999/06/06 20:19:35 vadim Exp $ * *------------------------------------------------------------------------- */#include <stdio.h>#include <sys/time.h>#include <unistd.h>#include "postgres.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. * Values are not critical but 10 milliseconds is a common platform * granularity. * note: total time to cycle through all 16 entries might be about .07 sec. */#define S_NSPINCYCLE	20#define S_MAX_BUSY		1000 * S_NSPINCYCLEint			s_spincycle[S_NSPINCYCLE] ={0, 0, 0, 0, 10000, 0, 0, 0, 10000, 0,	0, 10000, 0, 0, 10000, 0, 10000, 0, 10000, 10000};/* * s_lock_stuck(lock) - complain about a stuck spinlock */static voids_lock_stuck(volatile slock_t *lock, const char *file, const 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();}voids_lock_sleep(unsigned spin){	struct timeval delay;	delay.tv_sec = 0;	delay.tv_usec = s_spincycle[spin % S_NSPINCYCLE];	(void) select(0, NULL, NULL, NULL, &delay);}/* * s_lock(lock) - take a spinlock with backoff */voids_lock(volatile slock_t *lock, const char *file, const int line){	unsigned	spins = 0;	while (TAS(lock))	{		s_lock_sleep(spins);		if (++spins > S_MAX_BUSY)		{			/* It's been over a minute...  */			s_lock_stuck(lock, file, line);		}	}}/* * 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 voidtas_dummy()						/* really means: extern int tas(slock_t								 * **lock); */{	__asm__("		\n\.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(__powerpc__)/* Note: need a nice gcc constrained asm version so it can be inlined */static voidtas_dummy(){	__asm__("		\n\.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)static voidtas_dummy(){	__asm__("		\n\.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 */#else							/* defined(__GNUC__) *//*************************************************************************** * All non gcc */#if defined(sun3)static voidtas_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 voidtas_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;voidmain(){	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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -