diff options
Diffstat (limited to 'src/include/storage')
-rw-r--r-- | src/include/storage/lock.h | 4 | ||||
-rw-r--r-- | src/include/storage/sinvaladt.h | 152 |
2 files changed, 71 insertions, 85 deletions
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 87b8538212f..8f0f834e0f4 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -6,16 +6,16 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: lock.h,v 1.33 1999/07/16 17:07:38 momjian Exp $ + * $Id: lock.h,v 1.34 1999/09/06 19:37:37 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef LOCK_H_ #define LOCK_H_ +#include "storage/ipc.h" #include "storage/itemptr.h" #include "storage/shmem.h" -#include "storage/sinvaladt.h" #include "utils/array.h" extern SPINLOCK LockMgrLock; diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h index e008e52d30f..b9d349a4c57 100644 --- a/src/include/storage/sinvaladt.h +++ b/src/include/storage/sinvaladt.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: sinvaladt.h,v 1.17 1999/09/04 18:36:44 tgl Exp $ + * $Id: sinvaladt.h,v 1.18 1999/09/06 19:37:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,120 +17,106 @@ #include "storage/itemptr.h" /* - * The structure of the shared cache invaidation segment + * The shared cache invalidation manager is responsible for transmitting + * invalidation messages between backends. Any message sent by any backend + * must be delivered to all already-running backends before it can be + * forgotten. * + * Conceptually, the messages are stored in an infinite array, where + * maxMsgNum is the next array subscript to store a submitted message in, + * minMsgNum is the smallest array subscript containing a message not yet + * read by all backends, and we always have maxMsgNum >= minMsgNum. (They + * are equal when there are no messages pending.) For each active backend, + * there is a nextMsgNum pointer indicating the next message it needs to read; + * we have maxMsgNum >= nextMsgNum >= minMsgNum for every backend. + * + * In reality, the messages are stored in a circular buffer of MAXNUMMESSAGES + * entries. We translate MsgNum values into circular-buffer indexes by + * computing MsgNum % MAXNUMMESSAGES (this should be fast as long as + * MAXNUMMESSAGES is a constant and a power of 2). As long as maxMsgNum + * doesn't exceed minMsgNum by more than MAXNUMMESSAGES, we have enough space + * in the buffer. If the buffer does overflow, we reset it to empty and + * force each backend to "reset", ie, discard all its invalidatable state. + * + * We would have problems if the MsgNum values overflow an integer, so + * whenever minMsgNum exceeds MSGNUMWRAPAROUND, we subtract MSGNUMWRAPAROUND + * from all the MsgNum variables simultaneously. MSGNUMWRAPAROUND can be + * large so that we don't need to do this often. It must be a multiple of + * MAXNUMMESSAGES so that the existing circular-buffer entries don't need + * to be moved when we do it. */ -/* -A------------- Header info -------------- - criticalSectionSemaphoreId - generalSemaphoreId - startEntrySection (offset a) - endEntrySection (offset a + b) - startFreeSpace (offset relative to B) - startEntryChain (offset relatiev to B) - endEntryChain (offset relative to B) - numEntries - maxNumEntries - maxBackends - procState[maxBackends] --> limit - resetState (bool) -a tag (POSTID) -B------------- Start entry section ------- - SISegEntry --> entryData --> ... (see SharedInvalidData!) - isfree (bool) - next (offset to next entry in chain ) -b .... (dynamically growing down) -C----------------End shared segment ------- -*/ -/* Parameters (configurable) *******************************************/ -#define MAXNUMMESSAGES 4000 /* maximum number of messages in seg */ +/* + * Configurable parameters. + * + * MAXNUMMESSAGES: max number of shared-inval messages we can buffer. + * Must be a power of 2 for speed. + * + * MSGNUMWRAPAROUND: how often to reduce MsgNum variables to avoid overflow. + * Must be a multiple of MAXNUMMESSAGES. Should be large. + */ +#define MAXNUMMESSAGES 4096 +#define MSGNUMWRAPAROUND (MAXNUMMESSAGES * 4096) -#define InvalidOffset 1000000000 /* a invalid offset (End of - * chain) */ +/* The content of one shared-invalidation message */ +typedef struct SharedInvalidData +{ + int cacheId; /* XXX */ + Index hashIndex; + ItemPointerData pointerData; +} SharedInvalidData; + +typedef SharedInvalidData *SharedInvalid; +/* Per-backend state in shared invalidation structure */ typedef struct ProcState { - int limit; /* the number of read messages */ + /* nextMsgNum is -1 in an inactive ProcState array entry. */ + int nextMsgNum; /* next message number to read, or -1 */ bool resetState; /* true, if backend has to reset its state */ - int tag; /* special tag, recieved from the - * postmaster */ + int tag; /* backend tag received from postmaster */ } ProcState; - +/* Shared cache invalidation memory segment */ typedef struct SISeg { - IpcSemaphoreId criticalSectionSemaphoreId; /* semaphore id */ - IpcSemaphoreId generalSemaphoreId; /* semaphore id */ - Offset startEntrySection; /* (offset a) */ - Offset endEntrySection;/* (offset a + b) */ - Offset startFreeSpace; /* (offset relative to B) */ - Offset startEntryChain;/* (offset relative to B) */ - Offset endEntryChain; /* (offset relative to B) */ - int numEntries; - int maxNumEntries; + /* + * General state information + */ + int minMsgNum; /* oldest message still needed */ + int maxMsgNum; /* next message number to be assigned */ int maxBackends; /* size of procState array */ /* + * Circular buffer holding shared-inval messages + */ + SharedInvalidData buffer[MAXNUMMESSAGES]; + /* + * Per-backend state info. + * * We declare procState as 1 entry because C wants a fixed-size array, * but actually it is maxBackends entries long. */ ProcState procState[1]; /* reflects the invalidation state */ - /* - * The entry section begins after the end of the procState array. - * Everything there is controlled by offsets. - */ } SISeg; -typedef struct SharedInvalidData -{ - int cacheId; /* XXX */ - Index hashIndex; - ItemPointerData pointerData; -} SharedInvalidData; - -typedef SharedInvalidData *SharedInvalid; - - -typedef struct SISegEntry -{ - SharedInvalidData entryData;/* the message data */ - bool isfree; /* entry free? */ - Offset next; /* offset to next entry */ -} SISegEntry; - -typedef struct SISegOffsets -{ - Offset startSegment; /* always 0 (for now) */ - Offset offsetToFirstEntry; /* A + a = B */ - Offset offsetToEndOfSegment; /* A + a + b */ -} SISegOffsets; - - -/****************************************************************************/ -/* synchronization of the shared buffer access */ -/* access to the buffer is synchronized by the lock manager !! */ -/****************************************************************************/ -#define SI_LockStartValue 255 -#define SI_SharedLock (-1) -#define SI_ExclusiveLock (-255) +extern SISeg *shmInvalBuffer; /* pointer to the shared buffer segment, + * set by SISegmentAttach() + */ -extern SISeg *shmInvalBuffer; /* * prototypes for functions in sinvaladt.c */ -extern int SIBackendInit(SISeg *segInOutP); -extern int SISegmentInit(bool killExistingSegment, IPCKey key, +extern int SISegmentInit(bool createNewSegment, IPCKey key, int maxBackends); +extern int SIBackendInit(SISeg *segP); -extern bool SISetDataEntry(SISeg *segP, SharedInvalidData *data); -extern void SISetProcStateInvalid(SISeg *segP); +extern bool SIInsertDataEntry(SISeg *segP, SharedInvalidData *data); extern int SIGetDataEntry(SISeg *segP, int backendId, SharedInvalidData *data); -extern bool SIDelDataEntries(SISeg *segP, int n); extern void SIDelExpiredDataEntries(SISeg *segP); #endif /* SINVALADT_H */ |