Skip to content

Commit 814f1d8

Browse files
committed
Use condition variables for ProcSignalBarriers.
Instead of a poll/sleep loop, use a condition variable for precise wake-up whenever a backend's pss_barrierGeneration advances. Discussion: https://postgr.es/m/CA+hUKGLdemy2gBm80kz20GTe6hNVwoErE8KwcJk6-U56oStjtg@mail.gmail.com
1 parent 8bdb133 commit 814f1d8

File tree

1 file changed

+14
-20
lines changed

1 file changed

+14
-20
lines changed

src/backend/storage/ipc/procsignal.c

+14-20
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "miscadmin.h"
2424
#include "pgstat.h"
2525
#include "replication/walsender.h"
26+
#include "storage/condition_variable.h"
2627
#include "storage/ipc.h"
2728
#include "storage/latch.h"
2829
#include "storage/proc.h"
@@ -59,10 +60,11 @@
5960
*/
6061
typedef struct
6162
{
62-
pid_t pss_pid;
63-
sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS];
63+
volatile pid_t pss_pid;
64+
volatile sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS];
6465
pg_atomic_uint64 pss_barrierGeneration;
6566
pg_atomic_uint32 pss_barrierCheckMask;
67+
ConditionVariable pss_barrierCV;
6668
} ProcSignalSlot;
6769

6870
/*
@@ -93,7 +95,7 @@ typedef struct
9395
((flags) &= ~(((uint32) 1) << (uint32) (type)))
9496

9597
static ProcSignalHeader *ProcSignal = NULL;
96-
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
98+
static ProcSignalSlot *MyProcSignalSlot = NULL;
9799

98100
static bool CheckProcSignal(ProcSignalReason reason);
99101
static void CleanupProcSignalState(int status, Datum arg);
@@ -142,6 +144,7 @@ ProcSignalShmemInit(void)
142144
MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags));
143145
pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX);
144146
pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0);
147+
ConditionVariableInit(&slot->pss_barrierCV);
145148
}
146149
}
147150
}
@@ -156,7 +159,7 @@ ProcSignalShmemInit(void)
156159
void
157160
ProcSignalInit(int pss_idx)
158161
{
159-
volatile ProcSignalSlot *slot;
162+
ProcSignalSlot *slot;
160163
uint64 barrier_generation;
161164

162165
Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots);
@@ -208,7 +211,7 @@ static void
208211
CleanupProcSignalState(int status, Datum arg)
209212
{
210213
int pss_idx = DatumGetInt32(arg);
211-
volatile ProcSignalSlot *slot;
214+
ProcSignalSlot *slot;
212215

213216
slot = &ProcSignal->psh_slot[pss_idx - 1];
214217
Assert(slot == MyProcSignalSlot);
@@ -237,6 +240,7 @@ CleanupProcSignalState(int status, Datum arg)
237240
* no barrier waits block on it.
238241
*/
239242
pg_atomic_write_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX);
243+
ConditionVariableBroadcast(&slot->pss_barrierCV);
240244

241245
slot->pss_pid = 0;
242246
}
@@ -391,13 +395,11 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
391395
void
392396
WaitForProcSignalBarrier(uint64 generation)
393397
{
394-
long timeout = 125L;
395-
396398
Assert(generation <= pg_atomic_read_u64(&ProcSignal->psh_barrierGeneration));
397399

398400
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
399401
{
400-
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
402+
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
401403
uint64 oldval;
402404

403405
/*
@@ -409,20 +411,11 @@ WaitForProcSignalBarrier(uint64 generation)
409411
oldval = pg_atomic_read_u64(&slot->pss_barrierGeneration);
410412
while (oldval < generation)
411413
{
412-
int events;
413-
414-
CHECK_FOR_INTERRUPTS();
415-
416-
events =
417-
WaitLatch(MyLatch,
418-
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
419-
timeout, WAIT_EVENT_PROC_SIGNAL_BARRIER);
420-
ResetLatch(MyLatch);
421-
414+
ConditionVariableSleep(&slot->pss_barrierCV,
415+
WAIT_EVENT_PROC_SIGNAL_BARRIER);
422416
oldval = pg_atomic_read_u64(&slot->pss_barrierGeneration);
423-
if (events & WL_TIMEOUT)
424-
timeout = Min(timeout * 2, 1000L);
425417
}
418+
ConditionVariableCancelSleep();
426419
}
427420

428421
/*
@@ -589,6 +582,7 @@ ProcessProcSignalBarrier(void)
589582
* next called.
590583
*/
591584
pg_atomic_write_u64(&MyProcSignalSlot->pss_barrierGeneration, shared_gen);
585+
ConditionVariableBroadcast(&MyProcSignalSlot->pss_barrierCV);
592586
}
593587

594588
/*

0 commit comments

Comments
 (0)