Skip to content

Commit e0dece1

Browse files
committed
Redesign the patch for allocation of shmem space and LWLocks for add-on
modules; the first try was not usable in EXEC_BACKEND builds (e.g., Windows). Instead, just provide some entry points to increase the allocation requests during postmaster start, and provide a dedicated LWLock that can be used to synchronize allocation operations performed by backends. Per discussion with Marc Munro.
1 parent a3dff39 commit e0dece1

File tree

6 files changed

+73
-259
lines changed

6 files changed

+73
-259
lines changed

src/backend/storage/ipc/ipci.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.88 2006/10/04 00:29:57 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.89 2006/10/15 22:04:07 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -32,6 +32,30 @@
3232
#include "storage/spin.h"
3333

3434

35+
static Size total_addin_request = 0;
36+
static bool addin_request_allowed = true;
37+
38+
39+
/*
40+
* RequestAddinShmemSpace
41+
* Request that extra shmem space be allocated for use by
42+
* a loadable module.
43+
*
44+
* This is only useful if called from the _PG_init hook of a library that
45+
* is loaded into the postmaster via shared_preload_libraries. Once
46+
* shared memory has been allocated, calls will be ignored. (We could
47+
* raise an error, but it seems better to make it a no-op, so that
48+
* libraries containing such calls can be reloaded if needed.)
49+
*/
50+
void
51+
RequestAddinShmemSpace(Size size)
52+
{
53+
if (IsUnderPostmaster || !addin_request_allowed)
54+
return; /* too late */
55+
total_addin_request = add_size(total_addin_request, size);
56+
}
57+
58+
3559
/*
3660
* CreateSharedMemoryAndSemaphores
3761
* Creates and initializes shared memory and semaphores.
@@ -57,7 +81,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
5781
{
5882
PGShmemHeader *seghdr;
5983
Size size;
60-
Size size_b4addins;
6184
int numSemas;
6285

6386
/*
@@ -91,16 +114,11 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
91114
size = add_size(size, ShmemBackendArraySize());
92115
#endif
93116

94-
/* might as well round it off to a multiple of a typical page size */
95-
size = add_size(size, 8192 - (size % 8192));
117+
/* freeze the addin request size and include it */
118+
addin_request_allowed = false;
119+
size = add_size(size, total_addin_request);
96120

97-
/*
98-
* The shared memory for add-ins is treated as a separate segment, but
99-
* in reality it is not.
100-
*/
101-
size_b4addins = size;
102-
size = add_size(size, AddinShmemSize());
103-
/* round it off again */
121+
/* might as well round it off to a multiple of a typical page size */
104122
size = add_size(size, 8192 - (size % 8192));
105123

106124
elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
@@ -111,16 +129,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
111129
*/
112130
seghdr = PGSharedMemoryCreate(size, makePrivate, port);
113131

114-
/*
115-
* Modify hdr to show segment size before add-ins
116-
*/
117-
seghdr->totalsize = size_b4addins;
118-
119-
/*
120-
* Set up segment header sections in each Addin context
121-
*/
122-
InitAddinContexts((void *) ((char *) seghdr + size_b4addins));
123-
124132
InitShmemAccess(seghdr);
125133

126134
/*

src/backend/storage/ipc/shmem.c

Lines changed: 5 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.97 2006/10/04 00:29:57 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.98 2006/10/15 22:04:07 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -53,23 +53,14 @@
5353
* postmaster. However, this does not work in the EXEC_BACKEND case.
5454
* In ports using EXEC_BACKEND, new backends have to set up their local
5555
* pointers using the method described in (b) above.
56-
56+
*
5757
* (d) memory allocation model: shared memory can never be
5858
* freed, once allocated. Each hash table has its own free list,
5959
* so hash buckets can be reused when an item is deleted. However,
6060
* if one hash table grows very large and then shrinks, its space
6161
* cannot be redistributed to other tables. We could build a simple
6262
* hash bucket garbage collector if need be. Right now, it seems
6363
* 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.
7364
*/
7465

7566
#include "postgres.h"
@@ -95,19 +86,6 @@ slock_t *ShmemLock; /* spinlock for shared memory and LWLock
9586

9687
static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */
9788

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-
11189

11290
/*
11391
* InitShmemAccess() --- set up basic pointers to shared memory.
@@ -162,99 +140,7 @@ InitShmemAllocation(void)
162140
}
163141

164142
/*
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
143+
* ShmemAlloc -- allocate max-aligned chunk from shared memory
258144
*
259145
* Assumes ShmemLock and ShmemSegHdr are initialized.
260146
*
@@ -263,30 +149,15 @@ AddinShmemSize(void)
263149
* to be compatible with malloc().
264150
*/
265151
void *
266-
ShmemAllocFromContext(Size size, const char *context_name)
152+
ShmemAlloc(Size size)
267153
{
268154
Size newStart;
269155
Size newFree;
270156
void *newSpace;
271-
ContextNode *context;
272157

273158
/* use volatile pointer to prevent code rearrangement */
274159
volatile PGShmemHeader *shmemseghdr = ShmemSegHdr;
275160

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-
290161
/*
291162
* ensure all space is adequately aligned.
292163
*/
@@ -305,7 +176,7 @@ ShmemAllocFromContext(Size size, const char *context_name)
305176
newFree = newStart + size;
306177
if (newFree <= shmemseghdr->totalsize)
307178
{
308-
newSpace = (void *) MAKE_PTRFROM((SHMEM_OFFSET) shmemseghdr, newStart);
179+
newSpace = (void *) MAKE_PTR(newStart);
309180
shmemseghdr->freeoffset = newFree;
310181
}
311182
else
@@ -321,22 +192,6 @@ ShmemAllocFromContext(Size size, const char *context_name)
321192
return newSpace;
322193
}
323194

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-
340195
/*
341196
* ShmemIsValid -- test if an offset refers to valid shared memory
342197
*

0 commit comments

Comments
 (0)