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

📄 sinvaladt.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * sinvaladt.c *	  POSTGRES shared cache invalidation segment definitions. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.20 1999/05/28 17:03:28 tgl Exp $ * *------------------------------------------------------------------------- */#include <stdio.h>#include <signal.h>#include <unistd.h>#include "postgres.h"#include "storage/ipc.h"#include "storage/backendid.h"#include "storage/sinvaladt.h"#include "storage/lmgr.h"#include "utils/memutils.h"#include "utils/palloc.h"#include "utils/trace.h"/* ---------------- *		global variable notes * *		SharedInvalidationSemaphore * *		shmInvalBuffer *				the shared buffer segment, set by SISegmentAttach() * *		MyBackendId *				might be removed later, used only for *				debugging in debug routines (end of file) * *		SIDbId *				identification of buffer (disappears) * *		SIRelId			\ *		SIDummyOid		 \	identification of buffer *		SIXidData		 / *		SIXid			/ * *	XXX This file really needs to be cleaned up.  We switched to using *		spinlocks to protect critical sections (as opposed to using fake *		relations and going through the lock manager) and some of the old *		cruft was 'ifdef'ed out, while other parts (now unused) are still *		compiled into the system. -mer 5/24/92 * ---------------- */#ifdef HAS_TEST_AND_SETint			SharedInvalidationLockId;#elseIpcSemaphoreId SharedInvalidationSemaphore;#endifSISeg	   *shmInvalBuffer;extern BackendId MyBackendId;static void CleanupInvalidationState(int status, SISeg *segInOutP);static BackendId SIAssignBackendId(SISeg *segInOutP, BackendTag backendTag);static int	SIGetNumEntries(SISeg *segP);/************************************************************************//* SISetActiveProcess(segP, backendId)	set the backend status active	*//*		should be called only by the postmaster when creating a backend *//************************************************************************//* XXX I suspect that the segP parameter is extraneous. -hirohama */static voidSISetActiveProcess(SISeg *segInOutP, BackendId backendId){	/* mark all messages as read */	/* Assert(segP->procState[backendId - 1].tag == MyBackendTag); */	segInOutP->procState[backendId - 1].resetState = false;	segInOutP->procState[backendId - 1].limit = SIGetNumEntries(segInOutP);}/****************************************************************************//* SIBackendInit()	initializes a backend to operate on the buffer			*//****************************************************************************/intSIBackendInit(SISeg *segInOutP){	LockRelId	LtCreateRelId();	TransactionId LMITransactionIdCopy();	Assert(MyBackendTag > 0);	MyBackendId = SIAssignBackendId(segInOutP, MyBackendTag);	if (MyBackendId == InvalidBackendTag)		return 0;#ifdef	INVALIDDEBUG	elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",		 MyBackendTag, MyBackendId);#endif	 /* INVALIDDEBUG */	SISetActiveProcess(segInOutP, MyBackendId);	on_shmem_exit(CleanupInvalidationState, (caddr_t) segInOutP);	return 1;}/* ---------------- *		SIAssignBackendId * ---------------- */static BackendIdSIAssignBackendId(SISeg *segInOutP, BackendTag backendTag){	Index		index;	ProcState  *stateP = NULL;	for (index = 0; index < segInOutP->maxBackends; index++)	{		if (segInOutP->procState[index].tag == InvalidBackendTag ||			segInOutP->procState[index].tag == backendTag)		{			stateP = &segInOutP->procState[index];			break;		}		if (!PointerIsValid(stateP) ||			(segInOutP->procState[index].resetState &&			 (!stateP->resetState ||			  stateP->tag < backendTag)) ||			(!stateP->resetState &&			 (segInOutP->procState[index].limit <			  stateP->limit ||			  stateP->tag < backendTag)))			stateP = &segInOutP->procState[index];	}	/* verify that all "procState" entries checked for matching tags */	for (index++; index < segInOutP->maxBackends; index++)	{		if (segInOutP->procState[index].tag == backendTag)			elog(FATAL, "SIAssignBackendId: tag %d found twice", backendTag);	}	Assert(stateP);	if (stateP->tag != InvalidBackendTag)	{		if (stateP->tag == backendTag)			elog(NOTICE, "SIAssignBackendId: reusing tag %d", backendTag);		else		{			elog(NOTICE, "SIAssignBackendId: discarding tag %d", stateP->tag);			return InvalidBackendTag;		}	}	stateP->tag = backendTag;	return 1 + stateP - &segInOutP->procState[0];}/************************************************************************//* The following function should be called only by the postmaster !!	*//************************************************************************//************************************************************************//* SISetDeadProcess(segP, backendId)  set the backend status DEAD		*//*		should be called only by the postmaster when a backend died		*//************************************************************************/static voidSISetDeadProcess(SISeg *segP, int backendId){	/* XXX call me.... */	segP->procState[backendId - 1].resetState = false;	segP->procState[backendId - 1].limit = -1;	segP->procState[backendId - 1].tag = InvalidBackendTag;}/* * CleanupInvalidationState * Note: *		This is a temporary hack.  ExitBackend should call this instead *		of exit (via on_shmem_exit). */static voidCleanupInvalidationState(int status,	/* XXX */						 SISeg *segInOutP)		/* XXX style */{	Assert(PointerIsValid(segInOutP));	SISetDeadProcess(segInOutP, MyBackendId);}/************************************************************************//* SIComputeSize()	- compute size and offsets for SI segment			*//************************************************************************/static voidSIComputeSize(SISegOffsets *oP, int maxBackends){	int			A,				B,				a,				b,				totalSize;	A = 0;	/* sizeof(SISeg) includes the first ProcState entry */	a = sizeof(SISeg) + sizeof(ProcState) * (maxBackends - 1);	a = MAXALIGN(a);			/* offset to first data entry */	b = sizeof(SISegEntry) * MAXNUMMESSAGES;	B = A + a + b;	B = MAXALIGN(B);	totalSize = B - A;	oP->startSegment = A;	oP->offsetToFirstEntry = a; /* relative to A */	oP->offsetToEndOfSegment = totalSize;		/* relative to A */}/************************************************************************//* SISetStartEntrySection(segP, offset)		- sets the offset			*//************************************************************************/static voidSISetStartEntrySection(SISeg *segP, Offset offset){	segP->startEntrySection = offset;}/************************************************************************//* SIGetStartEntrySection(segP)		- returnss the offset				*//************************************************************************/static OffsetSIGetStartEntrySection(SISeg *segP){	return segP->startEntrySection;}/************************************************************************//* SISetEndEntrySection(segP, offset)	- sets the offset				*//************************************************************************/static voidSISetEndEntrySection(SISeg *segP, Offset offset){	segP->endEntrySection = offset;}/************************************************************************//* SISetEndEntryChain(segP, offset)		- sets the offset				*//************************************************************************/static voidSISetEndEntryChain(SISeg *segP, Offset offset){	segP->endEntryChain = offset;}/************************************************************************//* SIGetEndEntryChain(segP)		- returnss the offset					*//************************************************************************/static OffsetSIGetEndEntryChain(SISeg *segP){	return segP->endEntryChain;}/************************************************************************//* SISetStartEntryChain(segP, offset)	- sets the offset				*//************************************************************************/static voidSISetStartEntryChain(SISeg *segP, Offset offset){	segP->startEntryChain = offset;}/************************************************************************//* SIGetStartEntryChain(segP)	- returns  the offset					*//************************************************************************/static OffsetSIGetStartEntryChain(SISeg *segP){	return segP->startEntryChain;}/************************************************************************//* SISetNumEntries(segP, num)	sets the current nuber of entries		*//************************************************************************/static boolSISetNumEntries(SISeg *segP, int num){	if (num <= MAXNUMMESSAGES)	{		segP->numEntries = num;		return true;	}	else	{		return false;			/* table full */	}}/************************************************************************//* SIGetNumEntries(segP)	- returns the current nuber of entries		*//************************************************************************/static intSIGetNumEntries(SISeg *segP){	return segP->numEntries;}/************************************************************************//* SISetMaxNumEntries(segP, num)	sets the maximal number of entries	*//************************************************************************/static boolSISetMaxNumEntries(SISeg *segP, int num){	if (num <= MAXNUMMESSAGES)	{		segP->maxNumEntries = num;		return true;	}	else	{		return false;			/* wrong number */	}}/************************************************************************//* SIGetProcStateLimit(segP, i) returns the limit of read messages		*//************************************************************************/#define SIGetProcStateLimit(segP,i) \		((segP)->procState[i].limit)/************************************************************************//* SIIncNumEntries(segP, num)	increments the current nuber of entries *//************************************************************************/static boolSIIncNumEntries(SISeg *segP, int num){	/*	 * Try to prevent table overflow. When the table is 70% full send a	 * SIGUSR2 to the postmaster which will send it back to all the	 * backends. This will be handled by Async_NotifyHandler() with a	 * StartTransactionCommand() which will flush unread SI entries for	 * each backend.									dz - 27 Jan 1998	 */	if (segP->numEntries == (MAXNUMMESSAGES * 70 / 100))	{		TPRINTF(TRACE_VERBOSE,			"SIIncNumEntries: table is 70%% full, signaling postmaster");		kill(getppid(), SIGUSR2);	}	if ((segP->numEntries + num) <= MAXNUMMESSAGES)	{		segP->numEntries = segP->numEntries + num;		return true;	}	else	{		return false;			/* table full */	}}/************************************************************************//* SIDecNumEntries(segP, num)	decrements the current nuber of entries *//************************************************************************/static boolSIDecNumEntries(SISeg *segP, int num){	if ((segP->numEntries - num) >= 0)	{		segP->numEntries = segP->numEntries - num;		return true;	}	else	{		return false;			/* not enough entries in table */	}}/************************************************************************//* SISetStartFreeSpace(segP, offset)  - sets the offset					*//************************************************************************/static voidSISetStartFreeSpace(SISeg *segP, Offset offset){	segP->startFreeSpace = offset;}/************************************************************************//* SIGetStartFreeSpace(segP)  - returns the offset						*//************************************************************************/static OffsetSIGetStartFreeSpace(SISeg *segP){	return segP->startFreeSpace;}/************************************************************************//* SIGetFirstDataEntry(segP)  returns first data entry					*//************************************************************************/static SISegEntry *SIGetFirstDataEntry(SISeg *segP){	SISegEntry *eP;	Offset		startChain;	startChain = SIGetStartEntryChain(segP);

⌨️ 快捷键说明

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