Skip to content

Commit 9adc46f

Browse files
ashutosh-bapatCommitfest Bot
authored andcommitted
Refactor shared memory allocation for semaphores
Before e256266 spinlocks were implemented using semaphores on some platforms. Hence PGReserveSemaphores() was required to be called before SpinlockSemaInit(). SpinlockSemaInit() was required to be called before InitShmemAllocation() since the latter initialized a spinlock to synchronize shared memory allocations. A cyclic dependency existed because PGReserveSemaphores() uses shared memory for semaphores on some platforms. It was broken by letting PGReserveSemaphores() allocate shared memory without a spinlock using ShmemAllocUnlocked(). After e256266, spinlocks are not implemented using semaphores at all. This allows us to eliminate the need to estimate and allocate shared memory required by semaphores specially and treat them similar to the other shared memory structures. Since the semaphores are used only in PGPROC array, it makes more sense to estimate size of memory required by semaphores to go along with the estimation of memory required for that array in ProcGlobalShmemSize(). Similarly, it makes sense to have the actual shared memory allocations for both to be collocated in InitProcGlobal(). With that change CalculateShmemSize() does not need to know about the number of semaphores to be allocated, eliminating other asymmetry. InitializeShmemGUCs() which used to get the number of semaphores through CalculateShmemSize() now fetches that value separately. Author: Ashutosh Bapat <[email protected]> Discussion: https://www.postgresql.org/message-id/CAExHW5seSZpPx-znjidVZNzdagGHOk06F+Ds88MpPUbxd1kTaA@mail.gmail.com
1 parent 43aa96c commit 9adc46f

File tree

5 files changed

+11
-36
lines changed

5 files changed

+11
-36
lines changed

src/backend/port/posix_sema.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,8 @@ PGReserveSemaphores(int maxSemas)
215215
elog(PANIC, "out of memory");
216216
#else
217217

218-
/*
219-
* We must use ShmemAllocUnlocked(), since the spinlock protecting
220-
* ShmemAlloc() won't be ready yet.
221-
*/
222218
sharedSemas = (PGSemaphore)
223-
ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
219+
ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
224220
#endif
225221

226222
numSems = 0;

src/backend/port/sysv_sema.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,8 @@ PGReserveSemaphores(int maxSemas)
343343
errmsg("could not stat data directory \"%s\": %m",
344344
DataDir)));
345345

346-
/*
347-
* We must use ShmemAllocUnlocked(), since the spinlock protecting
348-
* ShmemAlloc() won't be ready yet.
349-
*/
350346
sharedSemas = (PGSemaphore)
351-
ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
347+
ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
352348
numSharedSemas = 0;
353349
maxSharedSemas = maxSemas;
354350

src/backend/storage/ipc/ipci.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,9 @@ RequestAddinShmemSpace(Size size)
8686
* required.
8787
*/
8888
Size
89-
CalculateShmemSize(int *num_semaphores)
89+
CalculateShmemSize(void)
9090
{
9191
Size size;
92-
int numSemas;
93-
94-
/* Compute number of semaphores we'll need */
95-
numSemas = ProcGlobalSemas();
96-
97-
/* Return the number of semaphores if requested by the caller */
98-
if (num_semaphores)
99-
*num_semaphores = numSemas;
10092

10193
/*
10294
* Size of the Postgres shared-memory block is estimated via moderately-
@@ -108,7 +100,6 @@ CalculateShmemSize(int *num_semaphores)
108100
* during the actual allocation phase.
109101
*/
110102
size = 100000;
111-
size = add_size(size, PGSemaphoreShmemSize(numSemas));
112103
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
113104
sizeof(ShmemIndexEnt)));
114105
size = add_size(size, dsm_estimate_size());
@@ -202,12 +193,11 @@ CreateSharedMemoryAndSemaphores(void)
202193
PGShmemHeader *shim;
203194
PGShmemHeader *seghdr;
204195
Size size;
205-
int numSemas;
206196

207197
Assert(!IsUnderPostmaster);
208198

209199
/* Compute the size of the shared-memory block */
210-
size = CalculateShmemSize(&numSemas);
200+
size = CalculateShmemSize();
211201
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
212202

213203
/*
@@ -224,16 +214,6 @@ CreateSharedMemoryAndSemaphores(void)
224214

225215
InitShmemAccess(seghdr);
226216

227-
/*
228-
* Create semaphores. This is done here because of a now-non-existent
229-
* dependency between spinlocks, which were required for shared memory
230-
* allocation, and semaphores, which were allocated in the shared memory
231-
* on some platforms. Ideally it should be done in
232-
* CreateOrAttachShmemStructs() where we allocate other shared memory
233-
* structures.
234-
*/
235-
PGReserveSemaphores(numSemas);
236-
237217
/*
238218
* Set up shared memory allocation mechanism
239219
*/
@@ -363,12 +343,11 @@ InitializeShmemGUCs(void)
363343
Size size_b;
364344
Size size_mb;
365345
Size hp_size;
366-
int num_semas;
367346

368347
/*
369348
* Calculate the shared memory size and round up to the nearest megabyte.
370349
*/
371-
size_b = CalculateShmemSize(&num_semas);
350+
size_b = CalculateShmemSize();
372351
size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
373352
sprintf(buf, "%zu", size_mb);
374353
SetConfigOption("shared_memory_size", buf,
@@ -388,6 +367,6 @@ InitializeShmemGUCs(void)
388367
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
389368
}
390369

391-
sprintf(buf, "%d", num_semas);
370+
sprintf(buf, "%d", ProcGlobalSemas());
392371
SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
393372
}

src/backend/storage/lmgr/proc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ ProcGlobalShmemSize(void)
144144
size = add_size(size, sizeof(PROC_HDR));
145145
size = add_size(size, sizeof(slock_t));
146146

147+
size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas()));
147148
size = add_size(size, PGProcShmemSize());
148149
size = add_size(size, FastPathLockShmemSize());
149150

@@ -286,6 +287,9 @@ InitProcGlobal(void)
286287
/* For asserts checking we did not overflow. */
287288
fpEndPtr = fpPtr + requestSize;
288289

290+
/* Reserve space for semaphores. */
291+
PGReserveSemaphores(ProcGlobalSemas());
292+
289293
for (i = 0; i < TotalProcs; i++)
290294
{
291295
PGPROC *proc = &procs[i];

src/include/storage/ipc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ extern void check_on_shmem_exit_lists_are_empty(void);
7777
/* ipci.c */
7878
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
7979

80-
extern Size CalculateShmemSize(int *num_semaphores);
80+
extern Size CalculateShmemSize(void);
8181
extern void CreateSharedMemoryAndSemaphores(void);
8282
#ifdef EXEC_BACKEND
8383
extern void AttachSharedMemoryStructs(void);

0 commit comments

Comments
 (0)