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

Lines changed: 14 additions & 20 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy