OSDN Git Service

39c895026b438f5c0583b515ca27c5b84c99b388
[pg-rex/syncrep.git] / src / include / storage / sinvaladt.h
1 /*-------------------------------------------------------------------------
2  *
3  * sinvaladt.h
4  *        POSTGRES shared cache invalidation segment definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * $Id: sinvaladt.h,v 1.33 2002/08/29 21:02:12 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef SINVALADT_H
15 #define SINVALADT_H
16
17 #include "storage/shmem.h"
18 #include "storage/sinval.h"
19
20 /*
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
24  * forgotten.
25  *
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.
33  *
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.
41  *
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.
48  *
49  * The struct type SharedInvalidationMessage, defining the contents of
50  * a single message, is defined in sinval.h.
51  */
52
53
54 /*
55  * Configurable parameters.
56  *
57  * MAXNUMMESSAGES: max number of shared-inval messages we can buffer.
58  * Must be a power of 2 for speed.
59  *
60  * MSGNUMWRAPAROUND: how often to reduce MsgNum variables to avoid overflow.
61  * Must be a multiple of MAXNUMMESSAGES.  Should be large.
62  */
63
64 #define MAXNUMMESSAGES 4096
65 #define MSGNUMWRAPAROUND (MAXNUMMESSAGES * 4096)
66
67
68 /* Per-backend state in shared invalidation structure */
69 typedef struct ProcState
70 {
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 */
75 } ProcState;
76
77 /* Shared cache invalidation memory segment */
78 typedef struct SISeg
79 {
80         /*
81          * General state information
82          */
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,
86                                                                  * +1 */
87         int                     maxBackends;    /* size of procState array */
88         int                     freeBackends;   /* number of empty procState slots */
89
90         /*
91          * Circular buffer holding shared-inval messages
92          */
93         SharedInvalidationMessage buffer[MAXNUMMESSAGES];
94
95         /*
96          * Per-backend state info.
97          *
98          * We declare procState as 1 entry because C wants a fixed-size array,
99          * but actually it is maxBackends entries long.
100          */
101         ProcState       procState[1];   /* reflects the invalidation state */
102 } SISeg;
103
104
105 extern SISeg *shmInvalBuffer;   /* pointer to the shared inval buffer */
106
107
108 /*
109  * prototypes for functions in sinvaladt.c
110  */
111 extern void SIBufferInit(int maxBackends);
112 extern int      SIBackendInit(SISeg *segP);
113
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);
118
119 #endif   /* SINVALADT_H */