Use WaitLatch() for condition variables.
Previously, condition_variable.c created a long lived WaitEventSet to avoid extra system calls. WaitLatch() now uses something similar internally, so there is no point in wasting an extra kernel descriptor. Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGJAC4Oqao%3DqforhNey20J8CiG2R%3DoBPqvfR0vOJrFysGw%40mail.gmail.com
This commit is contained in:
parent
3347c982ba
commit
e2d394df5d
@ -30,9 +30,6 @@
|
|||||||
/* Initially, we are not prepared to sleep on any condition variable. */
|
/* Initially, we are not prepared to sleep on any condition variable. */
|
||||||
static ConditionVariable *cv_sleep_target = NULL;
|
static ConditionVariable *cv_sleep_target = NULL;
|
||||||
|
|
||||||
/* Reusable WaitEventSet. */
|
|
||||||
static WaitEventSet *cv_wait_event_set = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a condition variable.
|
* Initialize a condition variable.
|
||||||
*/
|
*/
|
||||||
@ -62,23 +59,6 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
|
|||||||
{
|
{
|
||||||
int pgprocno = MyProc->pgprocno;
|
int pgprocno = MyProc->pgprocno;
|
||||||
|
|
||||||
/*
|
|
||||||
* If first time through in this process, create a WaitEventSet, which
|
|
||||||
* we'll reuse for all condition variable sleeps.
|
|
||||||
*/
|
|
||||||
if (cv_wait_event_set == NULL)
|
|
||||||
{
|
|
||||||
WaitEventSet *new_event_set;
|
|
||||||
|
|
||||||
new_event_set = CreateWaitEventSet(TopMemoryContext, 2);
|
|
||||||
AddWaitEventToSet(new_event_set, WL_LATCH_SET, PGINVALID_SOCKET,
|
|
||||||
MyLatch, NULL);
|
|
||||||
AddWaitEventToSet(new_event_set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
|
|
||||||
NULL, NULL);
|
|
||||||
/* Don't set cv_wait_event_set until we have a correct WES. */
|
|
||||||
cv_wait_event_set = new_event_set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If some other sleep is already prepared, cancel it; this is necessary
|
* If some other sleep is already prepared, cancel it; this is necessary
|
||||||
* because we have just one static variable tracking the prepared sleep,
|
* because we have just one static variable tracking the prepared sleep,
|
||||||
@ -135,6 +115,7 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
|
|||||||
long cur_timeout = -1;
|
long cur_timeout = -1;
|
||||||
instr_time start_time;
|
instr_time start_time;
|
||||||
instr_time cur_time;
|
instr_time cur_time;
|
||||||
|
int wait_events;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the caller didn't prepare to sleep explicitly, then do so now and
|
* If the caller didn't prepare to sleep explicitly, then do so now and
|
||||||
@ -166,19 +147,20 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
|
|||||||
INSTR_TIME_SET_CURRENT(start_time);
|
INSTR_TIME_SET_CURRENT(start_time);
|
||||||
Assert(timeout >= 0 && timeout <= INT_MAX);
|
Assert(timeout >= 0 && timeout <= INT_MAX);
|
||||||
cur_timeout = timeout;
|
cur_timeout = timeout;
|
||||||
|
wait_events = WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
wait_events = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
WaitEvent event;
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for latch to be set. (If we're awakened for some other
|
* Wait for latch to be set. (If we're awakened for some other
|
||||||
* reason, the code below will cope anyway.)
|
* reason, the code below will cope anyway.)
|
||||||
*/
|
*/
|
||||||
(void) WaitEventSetWait(cv_wait_event_set, cur_timeout, &event, 1,
|
(void) WaitLatch(MyLatch, wait_events, cur_timeout, wait_event_info);
|
||||||
wait_event_info);
|
|
||||||
|
|
||||||
/* Reset latch before examining the state of the wait list. */
|
/* Reset latch before examining the state of the wait list. */
|
||||||
ResetLatch(MyLatch);
|
ResetLatch(MyLatch);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user