1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/*-------------------------------------------------------------------------
*
* bufmgr.h
* POSTGRES buffer manager definitions.
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: bufmgr.h,v 1.47 2000/12/18 00:44:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef BUFMGR_H
#define BUFMGR_H
#include "access/xlogdefs.h"
#include "storage/buf.h"
#include "storage/lock.h"
#include "storage/relfilenode.h"
#include "utils/rel.h"
typedef void *Block;
/* in globals.c ... this duplicates miscadmin.h */
extern int NBuffers;
/* in buf_init.c */
extern Block *BufferBlockPointers;
extern long *PrivateRefCount;
/* in localbuf.c */
extern int NLocBuffer;
extern Block *LocalBufferBlockPointers;
extern long *LocalRefCount;
/* special pageno for bget */
#define P_NEW InvalidBlockNumber /* grow the file to get a new page */
/*
* Buffer context lock modes
*/
#define BUFFER_LOCK_UNLOCK 0
#define BUFFER_LOCK_SHARE 1
#define BUFFER_LOCK_EXCLUSIVE 2
/**********************************************************************
the rest is function defns in the bufmgr that are externally callable
**********************************************************************/
/*
* These routines are beaten on quite heavily, hence the macroization.
*/
#define BAD_BUFFER_ID(bid) ((bid) < 1 || (bid) > NBuffers)
#define INVALID_DESCRIPTOR (-3)
#define UnlockAndReleaseBuffer(buffer) \
( \
LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
ReleaseBuffer(buffer) \
)
#define UnlockAndWriteBuffer(buffer) \
( \
LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
WriteBuffer(buffer) \
)
/*
* BufferIsValid
* True iff the given buffer number is valid (either as a shared
* or local buffer).
*
* Note:
* BufferIsValid(InvalidBuffer) is False.
* BufferIsValid(UnknownBuffer) is False.
*
* Note: For a long time this was defined the same as BufferIsPinned,
* that is it would say False if you didn't hold a pin on the buffer.
* I believe this was bogus and served only to mask logic errors.
* Code should always know whether it has a buffer reference,
* independently of the pin state.
*/
#define BufferIsValid(bufnum) \
( \
BufferIsLocal(bufnum) ? \
((bufnum) >= -NLocBuffer) \
: \
(! BAD_BUFFER_ID(bufnum)) \
)
/*
* BufferIsPinned
* True iff the buffer is pinned (also checks for valid buffer number).
*
* NOTE: what we check here is that *this* backend holds a pin on
* the buffer. We do not care whether some other backend does.
*/
#define BufferIsPinned(bufnum) \
( \
BufferIsLocal(bufnum) ? \
((bufnum) >= -NLocBuffer && LocalRefCount[-(bufnum) - 1] > 0) \
: \
( \
BAD_BUFFER_ID(bufnum) ? \
false \
: \
(PrivateRefCount[(bufnum) - 1] > 0) \
) \
)
/*
* IncrBufferRefCount
* Increment the pin count on a buffer that we have *already* pinned
* at least once.
*
* This macro cannot be used on a buffer we do not have pinned,
* because it doesn't change the shared buffer state. Therefore the
* Assert checks are for refcount > 0. Someone got this wrong once...
*/
#define IncrBufferRefCount(buffer) \
( \
BufferIsLocal(buffer) ? \
( \
(void) AssertMacro((buffer) >= -NLocBuffer), \
(void) AssertMacro(LocalRefCount[-(buffer) - 1] > 0), \
(void) LocalRefCount[-(buffer) - 1]++ \
) \
: \
( \
(void) AssertMacro(!BAD_BUFFER_ID(buffer)), \
(void) AssertMacro(PrivateRefCount[(buffer) - 1] > 0), \
(void) PrivateRefCount[(buffer) - 1]++ \
) \
)
/*
* BufferGetBlock
* Returns a reference to a disk page image associated with a buffer.
*
* Note:
* Assumes buffer is valid.
*/
#define BufferGetBlock(buffer) \
( \
AssertMacro(BufferIsValid(buffer)), \
BufferIsLocal(buffer) ? \
LocalBufferBlockPointers[-(buffer) - 1] \
: \
BufferBlockPointers[(buffer) - 1] \
)
/*
* prototypes for functions in bufmgr.c
*/
extern Buffer RelationGetBufferWithBuffer(Relation relation,
BlockNumber blockNumber, Buffer buffer);
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
extern int WriteBuffer(Buffer buffer);
extern int WriteNoReleaseBuffer(Buffer buffer);
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
BlockNumber blockNum);
extern int FlushBuffer(Buffer buffer, bool sync, bool release);
extern void InitBufferPool(void);
extern void InitBufferPoolAccess(void);
extern void PrintBufferUsage(FILE *statfp);
extern void ResetBufferUsage(void);
extern void ResetBufferPool(bool isCommit);
extern int BufferPoolCheckLeak(void);
extern void FlushBufferPool(void);
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
extern int FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock);
extern void DropRelationBuffers(Relation rel);
extern void DropRelFileNodeBuffers(RelFileNode rnode);
extern void DropBuffers(Oid dbid);
extern void PrintPinnedBufs(void);
extern int BufferShmemSize(void);
extern int ReleaseBuffer(Buffer buffer);
extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode);
extern void AbortBufferIO(void);
extern bool BufferIsUpdatable(Buffer buffer);
extern void MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer));
extern void BufmgrCommit(void);
extern void BufferSync(void);
extern void InitLocalBuffer(void);
#endif
|