]> granicus.if.org Git - postgresql/blob - src/include/storage/bufmgr.h
Fix for TODO item * spinlock stuck problem when elog(FATAL)
[postgresql] / src / include / storage / bufmgr.h
1 /*-------------------------------------------------------------------------
2  *
3  * bufmgr.h
4  *        POSTGRES buffer manager definitions.
5  *
6  *
7  * Copyright (c) 1994, Regents of the University of California
8  *
9  * $Id: bufmgr.h,v 1.33 2000/01/17 01:15:19 inoue Exp $
10  *
11  *-------------------------------------------------------------------------
12  */
13 #ifndef BUFMGR_H
14 #define BUFMGR_H
15
16
17 #include "storage/ipc.h"
18 #include "storage/block.h"
19 #include "storage/buf.h"
20 #include "storage/buf_internals.h"
21 #include "utils/rel.h"
22
23 /*
24  * the maximum size of a disk block for any possible installation.
25  *
26  * in theory this could be anything, but in practice this is actually
27  * limited to 2^13 bytes because we have limited ItemIdData.lp_off and
28  * ItemIdData.lp_len to 13 bits (see itemid.h).
29  *
30  * limit is now 2^15.  Took four bits from ItemIdData.lp_flags and gave
31  * two apiece to ItemIdData.lp_len and lp_off. darrenk 01/06/98
32  *
33  */
34
35 #define MAXBLCKSZ               32768
36
37 typedef void *Block;
38
39 /* special pageno for bget */
40 #define P_NEW   InvalidBlockNumber              /* grow the file to get a new page */
41
42 typedef bits16 BufferLock;
43
44 /**********************************************************************
45
46   the rest is function defns in the bufmgr that are externally callable
47
48  **********************************************************************/
49
50 /*
51  * These routines are beaten on quite heavily, hence the macroization.
52  * See buf_internals.h for a related comment.
53  */
54 #define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1)
55
56 extern int      ShowPinTrace;
57
58 /*
59  * BufferWriteModes (settable via SetBufferWriteMode)
60  */
61 #define BUFFER_FLUSH_WRITE              0               /* immediate write */
62 #define BUFFER_LATE_WRITE               1               /* delayed write: mark as DIRTY */
63
64 /*
65  * Buffer context lock modes
66  */
67 #define BUFFER_LOCK_UNLOCK              0
68 #define BUFFER_LOCK_SHARE               1
69 #define BUFFER_LOCK_EXCLUSIVE   2
70
71
72 /*
73  * BufferIsValid
74  *              True iff the given buffer number is valid (either as a shared
75  *              or local buffer).
76  *
77  * Note:
78  *              BufferIsValid(InvalidBuffer) is False.
79  *              BufferIsValid(UnknownBuffer) is False.
80  *
81  * Note: For a long time this was defined the same as BufferIsPinned,
82  * that is it would say False if you didn't hold a pin on the buffer.
83  * I believe this was bogus and served only to mask logic errors.
84  * Code should always know whether it has a buffer reference,
85  * independently of the pin state.
86  */
87 #define BufferIsValid(bufnum) \
88 ( \
89         BufferIsLocal(bufnum) ? \
90                 ((bufnum) >= -NLocBuffer) \
91         : \
92                 (! BAD_BUFFER_ID(bufnum)) \
93 )
94
95 /*
96  * BufferIsPinned
97  *              True iff the buffer is pinned (also checks for valid buffer number).
98  *
99  *              NOTE: what we check here is that *this* backend holds a pin on
100  *              the buffer.  We do not care whether some other backend does.
101  */
102 #define BufferIsPinned(bufnum) \
103 ( \
104         BufferIsLocal(bufnum) ? \
105                 ((bufnum) >= -NLocBuffer && LocalRefCount[-(bufnum) - 1] > 0) \
106         : \
107         ( \
108                 BAD_BUFFER_ID(bufnum) ? \
109                         false \
110                 : \
111                         (PrivateRefCount[(bufnum) - 1] > 0) \
112         ) \
113 )
114
115 /*
116  * IncrBufferRefCount
117  *              Increment the pin count on a buffer that we have *already* pinned
118  *              at least once.
119  *
120  *              This macro cannot be used on a buffer we do not have pinned,
121  *              because it doesn't change the shared buffer state.  Therefore the
122  *              Assert checks are for refcount > 0.  Someone got this wrong once...
123  */
124 #define IncrBufferRefCount(buffer) \
125 ( \
126         BufferIsLocal(buffer) ? \
127         ( \
128                 (void) AssertMacro((buffer) >= -NLocBuffer), \
129                 (void) AssertMacro(LocalRefCount[-(buffer) - 1] > 0), \
130                 (void) LocalRefCount[-(buffer) - 1]++ \
131         ) \
132         : \
133         ( \
134                 (void) AssertMacro(!BAD_BUFFER_ID(buffer)), \
135                 (void) AssertMacro(PrivateRefCount[(buffer) - 1] > 0), \
136                 (void) PrivateRefCount[(buffer) - 1]++ \
137         ) \
138 )
139
140 /*
141  * BufferGetBlock
142  *              Returns a reference to a disk page image associated with a buffer.
143  *
144  * Note:
145  *              Assumes buffer is valid.
146  */
147 #define BufferGetBlock(buffer) \
148 ( \
149         AssertMacro(BufferIsValid(buffer)), \
150         BufferIsLocal(buffer) ? \
151                 ((Block) MAKE_PTR(LocalBufferDescriptors[-(buffer) - 1].data)) \
152         : \
153                 ((Block) MAKE_PTR(BufferDescriptors[(buffer) - 1].data)) \
154 )
155
156
157 /*
158  * prototypes for functions in bufmgr.c
159  */
160 extern Buffer RelationGetBufferWithBuffer(Relation relation,
161                                                         BlockNumber blockNumber, Buffer buffer);
162 extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
163 extern int      WriteBuffer(Buffer buffer);
164 extern int      WriteNoReleaseBuffer(Buffer buffer);
165 extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
166                                          BlockNumber blockNum);
167
168 extern void InitBufferPool(IPCKey key);
169 extern void PrintBufferUsage(FILE *statfp);
170 extern void ResetBufferUsage(void);
171 extern void ResetBufferPool(void);
172 extern int      BufferPoolCheckLeak(void);
173 extern void FlushBufferPool(void);
174 extern BlockNumber BufferGetBlockNumber(Buffer buffer);
175 extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
176 extern int      FlushRelationBuffers(Relation rel, BlockNumber block,
177                                                                  bool doFlush);
178 extern void ReleaseRelationBuffers(Relation rel);
179 extern void DropBuffers(Oid dbid);
180 extern void PrintPinnedBufs(void);
181 extern int      BufferShmemSize(void);
182 extern int      ReleaseBuffer(Buffer buffer);
183
184 extern int      SetBufferWriteMode(int mode);
185 extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
186
187 extern void UnlockBuffers(void);
188 extern void LockBuffer(Buffer buffer, int mode);
189 extern void AbortBufferIO(void);
190
191 #endif