aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/storage/lock.h4
-rw-r--r--src/include/storage/sinvaladt.h152
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 */