|
|
@ -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); |
|
|
|