1 /*-------------------------------------------------------------------------
4 * POSTGRES shared cache invalidation segment definitions.
7 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Id: sinvaladt.h,v 1.33 2002/08/29 21:02:12 momjian Exp $
12 *-------------------------------------------------------------------------
17 #include "storage/shmem.h"
18 #include "storage/sinval.h"
21 * The shared cache invalidation manager is responsible for transmitting
22 * invalidation messages between backends. Any message sent by any backend
23 * must be delivered to all already-running backends before it can be
26 * Conceptually, the messages are stored in an infinite array, where
27 * maxMsgNum is the next array subscript to store a submitted message in,
28 * minMsgNum is the smallest array subscript containing a message not yet
29 * read by all backends, and we always have maxMsgNum >= minMsgNum. (They
30 * are equal when there are no messages pending.) For each active backend,
31 * there is a nextMsgNum pointer indicating the next message it needs to read;
32 * we have maxMsgNum >= nextMsgNum >= minMsgNum for every backend.
34 * In reality, the messages are stored in a circular buffer of MAXNUMMESSAGES
35 * entries. We translate MsgNum values into circular-buffer indexes by
36 * computing MsgNum % MAXNUMMESSAGES (this should be fast as long as
37 * MAXNUMMESSAGES is a constant and a power of 2). As long as maxMsgNum
38 * doesn't exceed minMsgNum by more than MAXNUMMESSAGES, we have enough space
39 * in the buffer. If the buffer does overflow, we reset it to empty and
40 * force each backend to "reset", ie, discard all its invalidatable state.
42 * We would have problems if the MsgNum values overflow an integer, so
43 * whenever minMsgNum exceeds MSGNUMWRAPAROUND, we subtract MSGNUMWRAPAROUND
44 * from all the MsgNum variables simultaneously. MSGNUMWRAPAROUND can be
45 * large so that we don't need to do this often. It must be a multiple of
46 * MAXNUMMESSAGES so that the existing circular-buffer entries don't need
47 * to be moved when we do it.
49 * The struct type SharedInvalidationMessage, defining the contents of
50 * a single message, is defined in sinval.h.
55 * Configurable parameters.
57 * MAXNUMMESSAGES: max number of shared-inval messages we can buffer.
58 * Must be a power of 2 for speed.
60 * MSGNUMWRAPAROUND: how often to reduce MsgNum variables to avoid overflow.
61 * Must be a multiple of MAXNUMMESSAGES. Should be large.
64 #define MAXNUMMESSAGES 4096
65 #define MSGNUMWRAPAROUND (MAXNUMMESSAGES * 4096)
68 /* Per-backend state in shared invalidation structure */
69 typedef struct ProcState
71 /* nextMsgNum is -1 in an inactive ProcState array entry. */
72 int nextMsgNum; /* next message number to read, or -1 */
73 bool resetState; /* true, if backend has to reset its state */
74 SHMEM_OFFSET procStruct; /* location of backend's PGPROC struct */
77 /* Shared cache invalidation memory segment */
81 * General state information
83 int minMsgNum; /* oldest message still needed */
84 int maxMsgNum; /* next message number to be assigned */
85 int lastBackend; /* index of last active procState entry,
87 int maxBackends; /* size of procState array */
88 int freeBackends; /* number of empty procState slots */
91 * Circular buffer holding shared-inval messages
93 SharedInvalidationMessage buffer[MAXNUMMESSAGES];
96 * Per-backend state info.
98 * We declare procState as 1 entry because C wants a fixed-size array,
99 * but actually it is maxBackends entries long.
101 ProcState procState[1]; /* reflects the invalidation state */
105 extern SISeg *shmInvalBuffer; /* pointer to the shared inval buffer */
109 * prototypes for functions in sinvaladt.c
111 extern void SIBufferInit(int maxBackends);
112 extern int SIBackendInit(SISeg *segP);
114 extern bool SIInsertDataEntry(SISeg *segP, SharedInvalidationMessage *data);
115 extern int SIGetDataEntry(SISeg *segP, int backendId,
116 SharedInvalidationMessage *data);
117 extern void SIDelExpiredDataEntries(SISeg *segP);
119 #endif /* SINVALADT_H */