1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* sinval.c--
|
1997-09-07 07:04:48 +02:00
|
|
|
* POSTGRES shared cache invalidation communication code.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1998-09-01 06:40:42 +02:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.12 1998/09/01 04:31:52 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
/* #define INVALIDDEBUG 1 */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1996-11-03 06:08:01 +01:00
|
|
|
#include <sys/types.h>
|
1996-10-31 06:58:01 +01:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
|
1996-11-06 07:52:23 +01:00
|
|
|
#include "storage/backendid.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "storage/sinval.h"
|
|
|
|
#include "storage/sinvaladt.h"
|
|
|
|
#include "storage/spin.h"
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by */
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/* SISegmentAttach() */
|
|
|
|
extern BackendId MyBackendId;
|
|
|
|
extern BackendTag MyBackendTag;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
SPINLOCK SInvalLock = (SPINLOCK) NULL;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/****************************************************************************/
|
1997-09-07 07:04:48 +02:00
|
|
|
/* CreateSharedInvalidationState(key) Create a buffer segment */
|
|
|
|
/* */
|
|
|
|
/* should be called only by the POSTMASTER */
|
1996-07-09 08:22:35 +02:00
|
|
|
/****************************************************************************/
|
|
|
|
void
|
|
|
|
CreateSharedInvalidationState(IPCKey key)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int status;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* REMOVED SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
|
|
|
|
* SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* SInvalLock gets set in spin.c, during spinlock init */
|
|
|
|
status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
|
|
|
|
|
|
|
|
if (status == -1)
|
|
|
|
elog(FATAL, "CreateSharedInvalidationState: failed segment init");
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/****************************************************************************/
|
1997-09-07 07:04:48 +02:00
|
|
|
/* AttachSharedInvalidationState(key) Attach a buffer segment */
|
|
|
|
/* */
|
|
|
|
/* should be called only by the POSTMASTER */
|
1996-07-09 08:22:35 +02:00
|
|
|
/****************************************************************************/
|
|
|
|
void
|
|
|
|
AttachSharedInvalidationState(IPCKey key)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int status;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (key == PrivateIPCKey)
|
|
|
|
{
|
|
|
|
CreateSharedInvalidationState(key);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* SInvalLock gets set in spin.c, during spinlock init */
|
|
|
|
status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
|
|
|
|
|
|
|
|
if (status == -1)
|
|
|
|
elog(FATAL, "AttachSharedInvalidationState: failed segment init");
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1996-11-10 04:06:38 +01:00
|
|
|
InitSharedInvalidationState(void)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
SpinAcquire(SInvalLock);
|
|
|
|
if (!SIBackendInit(shmInvalBuffer))
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
SpinRelease(SInvalLock);
|
|
|
|
elog(FATAL, "Backend cache invalidation initialization failed");
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
SpinRelease(SInvalLock);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* RegisterSharedInvalid --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns a new local cache invalidation state containing a new entry.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Note:
|
1997-09-07 07:04:48 +02:00
|
|
|
* Assumes hash index is valid.
|
|
|
|
* Assumes item pointer is valid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
/****************************************************************************/
|
1997-09-07 07:04:48 +02:00
|
|
|
/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
|
|
|
|
/* */
|
|
|
|
/* register a message in the buffer */
|
|
|
|
/* should be called by a backend */
|
1996-07-09 08:22:35 +02:00
|
|
|
/****************************************************************************/
|
|
|
|
void
|
1997-09-07 07:04:48 +02:00
|
|
|
RegisterSharedInvalid(int cacheId, /* XXX */
|
|
|
|
Index hashIndex,
|
|
|
|
ItemPointer pointer)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
SharedInvalidData newInvalid;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This code has been hacked to accept two types of messages. This
|
|
|
|
* might be treated more generally in the future.
|
|
|
|
*
|
|
|
|
* (1) cacheId= system cache id hashIndex= system cache hash index for a
|
|
|
|
* (possibly) cached tuple pointer= pointer of (possibly) cached tuple
|
|
|
|
*
|
|
|
|
* (2) cacheId= special non-syscache id hashIndex= object id contained in
|
|
|
|
* (possibly) cached relation descriptor pointer= null
|
|
|
|
*/
|
|
|
|
|
|
|
|
newInvalid.cacheId = cacheId;
|
|
|
|
newInvalid.hashIndex = hashIndex;
|
|
|
|
|
|
|
|
if (ItemPointerIsValid(pointer))
|
|
|
|
ItemPointerCopy(pointer, &newInvalid.pointerData);
|
|
|
|
else
|
|
|
|
ItemPointerSetInvalid(&newInvalid.pointerData);
|
|
|
|
|
|
|
|
SpinAcquire(SInvalLock);
|
|
|
|
if (!SISetDataEntry(shmInvalBuffer, &newInvalid))
|
|
|
|
{
|
|
|
|
/* buffer full */
|
|
|
|
/* release a message, mark process cache states to be invalid */
|
|
|
|
SISetProcStateInvalid(shmInvalBuffer);
|
|
|
|
|
|
|
|
if (!SIDelDataEntry(shmInvalBuffer))
|
|
|
|
{
|
|
|
|
/* inconsistent buffer state -- shd never happen */
|
|
|
|
SpinRelease(SInvalLock);
|
|
|
|
elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write again */
|
|
|
|
SISetDataEntry(shmInvalBuffer, &newInvalid);
|
|
|
|
}
|
|
|
|
SpinRelease(SInvalLock);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* InvalidateSharedInvalid --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Processes all entries in a shared cache invalidation state.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
/****************************************************************************/
|
1997-09-07 07:04:48 +02:00
|
|
|
/* InvalidateSharedInvalid(invalFunction, resetFunction) */
|
|
|
|
/* */
|
|
|
|
/* invalidate a message in the buffer (read and clean up) */
|
|
|
|
/* should be called by a backend */
|
1996-07-09 08:22:35 +02:00
|
|
|
/****************************************************************************/
|
|
|
|
void
|
1998-09-01 06:40:42 +02:00
|
|
|
InvalidateSharedInvalid(void (*invalFunction) (),
|
|
|
|
void (*resetFunction) ())
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
SpinAcquire(SInvalLock);
|
|
|
|
SIReadEntryData(shmInvalBuffer, MyBackendId,
|
|
|
|
invalFunction, resetFunction);
|
|
|
|
|
|
|
|
SIDelExpiredDataEntries(shmInvalBuffer);
|
|
|
|
SpinRelease(SInvalLock);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|