8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.94 2006/07/22 23:04:39 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.95 2006/08/01 19:03:11 momjian Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
61
61
* cannot be redistributed to other tables. We could build a simple
62
62
* hash bucket garbage collector if need be. Right now, it seems
63
63
* unnecessary.
64
+ *
65
+ * (e) Add-ins can request their own logical shared memory segments
66
+ * by calling RegisterAddinContext() from the preload-libraries hook.
67
+ * Each call establishes a uniquely named add-in shared memopry
68
+ * context which will be set up as part of postgres intialisation.
69
+ * Memory can be allocated from these contexts using
70
+ * ShmemAllocFromContext(), and can be reset to its initial condition
71
+ * using ShmemResetContext(). Also, RegisterAddinLWLock(LWLockid *lock_ptr)
72
+ * can be used to request that a LWLock be allocated, placed into *lock_ptr.
64
73
*/
65
74
66
75
#include "postgres.h"
@@ -86,6 +95,19 @@ slock_t *ShmemLock; /* spinlock for shared memory and LWLock
86
95
87
96
static HTAB * ShmemIndex = NULL ; /* primary index hashtable for shmem */
88
97
98
+ /* Structures and globals for managing add-in shared memory contexts */
99
+ typedef struct context
100
+ {
101
+ char * name ;
102
+ Size size ;
103
+ PGShmemHeader * seg_hdr ;
104
+ struct context * next ;
105
+ } ContextNode ;
106
+
107
+ static ContextNode * addin_contexts = NULL ;
108
+ static Size addin_contexts_size = 0 ;
109
+
110
+
89
111
90
112
/*
91
113
* InitShmemAccess() --- set up basic pointers to shared memory.
@@ -135,12 +157,104 @@ InitShmemAllocation(void)
135
157
* (This doesn't really belong here, but not worth moving.)
136
158
*/
137
159
ShmemVariableCache = (VariableCache )
138
- ShmemAlloc (sizeof (* ShmemVariableCache ));
160
+ ShmemAlloc (sizeof (* ShmemVariableCache ));
139
161
memset (ShmemVariableCache , 0 , sizeof (* ShmemVariableCache ));
140
162
}
141
163
142
164
/*
143
- * ShmemAlloc -- allocate max-aligned chunk from shared memory
165
+ * RegisterAddinContext -- Register the requirement for a named shared
166
+ * memory context.
167
+ */
168
+ void
169
+ RegisterAddinContext (const char * name , Size size )
170
+ {
171
+ char * newstr = malloc (strlen (name ) + 1 );
172
+ ContextNode * node = malloc (sizeof (ContextNode ));
173
+
174
+ strcpy (newstr , name );
175
+ node -> name = newstr ;
176
+
177
+ /* Round up to typical page size */
178
+ node -> size = add_size (size , 8192 - (size % 8192 ));
179
+ node -> next = addin_contexts ;
180
+
181
+ addin_contexts = node ;
182
+ addin_contexts_size = add_size (addin_contexts_size , node -> size );
183
+ }
184
+
185
+
186
+ /*
187
+ * ContextFromName -- Return the ContextNode for the given named
188
+ * context, or NULL if not found.
189
+ */
190
+ static ContextNode *
191
+ ContextFromName (const char * name )
192
+ {
193
+ ContextNode * context = addin_contexts ;
194
+
195
+ while (context )
196
+ {
197
+ if (strcmp (name , context -> name ) == 0 )
198
+ return context ;
199
+ context = context -> next ;
200
+ }
201
+ return NULL ;
202
+ }
203
+
204
+ /*
205
+ * InitAddinContexts -- Initialise the registered addin shared memory
206
+ * contexts.
207
+ */
208
+ void
209
+ InitAddinContexts (void * start )
210
+ {
211
+ PGShmemHeader * next_segment = (PGShmemHeader * ) start ;
212
+ ContextNode * context = addin_contexts ;
213
+
214
+ while (context )
215
+ {
216
+ context -> seg_hdr = next_segment ;
217
+
218
+ next_segment -> totalsize = context -> size ;
219
+ next_segment -> freeoffset = MAXALIGN (sizeof (PGShmemHeader ));
220
+
221
+ next_segment = (PGShmemHeader * )
222
+ ((char * ) next_segment + context -> size );
223
+ context = context -> next ;
224
+ }
225
+ }
226
+
227
+ /*
228
+ * ShmemResetContext -- Re-initialise the named addin shared memory context.
229
+ */
230
+ void
231
+ ShmemResetContext (const char * name )
232
+ {
233
+ PGShmemHeader * segment ;
234
+ ContextNode * context = ContextFromName (name );
235
+
236
+ if (!context )
237
+ ereport (ERROR ,
238
+ (errcode (ERRCODE_INTERNAL_ERROR ),
239
+ errmsg ("cannot reset unknown shared memory context %s" ,
240
+ name )));
241
+
242
+ segment = context -> seg_hdr ;
243
+ segment -> freeoffset = MAXALIGN (sizeof (PGShmemHeader ));
244
+ }
245
+
246
+ /*
247
+ * AddinShmemSize -- Report how much shared memory has been registered
248
+ * for add-ins.
249
+ */
250
+ Size
251
+ AddinShmemSize (void )
252
+ {
253
+ return addin_contexts_size ;
254
+ }
255
+
256
+ /*
257
+ * ShmemAllocFromContext -- allocate max-aligned chunk from shared memory
144
258
*
145
259
* Assumes ShmemLock and ShmemSegHdr are initialized.
146
260
*
@@ -149,15 +263,30 @@ InitShmemAllocation(void)
149
263
* to be compatible with malloc().
150
264
*/
151
265
void *
152
- ShmemAlloc (Size size )
266
+ ShmemAllocFromContext (Size size , const char * context_name )
153
267
{
154
- Size newStart ;
155
- Size newFree ;
156
- void * newSpace ;
268
+ Size newStart ;
269
+ Size newFree ;
270
+ void * newSpace ;
271
+ ContextNode * context ;
157
272
158
273
/* use volatile pointer to prevent code rearrangement */
159
274
volatile PGShmemHeader * shmemseghdr = ShmemSegHdr ;
160
275
276
+ /*
277
+ * if context_name is provided, allocate from the named context
278
+ */
279
+ if (context_name )
280
+ {
281
+ context = ContextFromName (context_name );
282
+ if (!context )
283
+ ereport (ERROR ,
284
+ (errcode (ERRCODE_INTERNAL_ERROR ),
285
+ errmsg ("cannot reset unknown shared memory context %s" ,
286
+ context_name )));
287
+ shmemseghdr = context -> seg_hdr ;
288
+ }
289
+
161
290
/*
162
291
* ensure all space is adequately aligned.
163
292
*/
@@ -176,7 +305,7 @@ ShmemAlloc(Size size)
176
305
newFree = newStart + size ;
177
306
if (newFree <= shmemseghdr -> totalsize )
178
307
{
179
- newSpace = (void * ) MAKE_PTR ( newStart );
308
+ newSpace = (void * ) MAKE_PTRFROM (( SHMEM_OFFSET ) shmemseghdr , newStart );
180
309
shmemseghdr -> freeoffset = newFree ;
181
310
}
182
311
else
@@ -192,6 +321,22 @@ ShmemAlloc(Size size)
192
321
return newSpace ;
193
322
}
194
323
324
+ /*
325
+ * ShmemAlloc -- allocate max-aligned chunk from shared memory
326
+ *
327
+ * Assumes ShmemLock and ShmemSegHdr are initialized.
328
+ *
329
+ * Returns: real pointer to memory or NULL if we are out
330
+ * of space. Has to return a real pointer in order
331
+ * to be compatible with malloc().
332
+ */
333
+
334
+ void *
335
+ ShmemAlloc (Size size )
336
+ {
337
+ return ShmemAllocFromContext (size , NULL );
338
+ }
339
+
195
340
/*
196
341
* ShmemIsValid -- test if an offset refers to valid shared memory
197
342
*
0 commit comments