0001-Introduce-timed-waits-for-condition-variables-v6.patch
application/octet-stream
Filename: 0001-Introduce-timed-waits-for-condition-variables-v6.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v6-0001
Subject: Introduce timed waits for condition variables.
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/condition_variable.c | 56 | 8 |
| src/include/storage/condition_variable.h | 2 | 0 |
From a3f819ade8dd99ec43b1709fbf291b303daa085d Mon Sep 17 00:00:00 2001
From: Shawn Debnath <sdn@amazon.com>
Date: Tue, 12 Mar 2019 23:21:41 +0000
Subject: [PATCH 1/3] Introduce timed waits for condition variables.
Provide ConditionVariableTimedSleep(), like ConditionVariableSleep()
but with a timeout argument.
Author: Shawn Debnath
Reviewed-by: Kyotaro Horiguchi, Thomas Munro
Discussion: https://postgr.es/m/eeb06007ccfe46e399df6af18bfcd15a@EX13D05UWC002.ant.amazon.com
---
src/backend/storage/lmgr/condition_variable.c | 64 ++++++++++++++++---
src/include/storage/condition_variable.h | 2 +
2 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index 58b7b514720..951039da551 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -19,6 +19,7 @@
#include "postgres.h"
#include "miscadmin.h"
+#include "portability/instr_time.h"
#include "storage/condition_variable.h"
#include "storage/ipc.h"
#include "storage/proc.h"
@@ -122,8 +123,24 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
void
ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
{
- WaitEvent event;
- bool done = false;
+ (void) ConditionVariableTimedSleep(cv, -1 /* no timeout */ ,
+ wait_event_info);
+}
+
+/*
+ * Wait for a condition variable to be signaled or a timeout to be reached.
+ *
+ * Returns true when timeout expires, otherwise returns false.
+ *
+ * See ConditionVariableSleep() for general usage.
+ */
+bool
+ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
+ uint32 wait_event_info)
+{
+ long cur_timeout = -1;
+ instr_time start_time;
+ instr_time cur_time;
/*
* If the caller didn't prepare to sleep explicitly, then do so now and
@@ -143,23 +160,38 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
if (cv_sleep_target != cv)
{
ConditionVariablePrepareToSleep(cv);
- return;
+ return false;
}
- do
+ /*
+ * Record the current time so that we can calculate the remaining timeout
+ * if we are woken up spuriously.
+ */
+ if (timeout >= 0)
{
- CHECK_FOR_INTERRUPTS();
+ INSTR_TIME_SET_CURRENT(start_time);
+ Assert(timeout >= 0 && timeout <= INT_MAX);
+ cur_timeout = timeout;
+ }
+
+ while (true)
+ {
+ WaitEvent event;
+ bool done = false;
+ int rc;
/*
* Wait for latch to be set. (If we're awakened for some other
* reason, the code below will cope anyway.)
*/
- (void) WaitEventSetWait(cv_wait_event_set, -1, &event, 1,
- wait_event_info);
+ rc = WaitEventSetWait(cv_wait_event_set, cur_timeout, &event, 1,
+ wait_event_info);
/* Reset latch before examining the state of the wait list. */
ResetLatch(MyLatch);
+ CHECK_FOR_INTERRUPTS();
+
/*
* If this process has been taken out of the wait list, then we know
* that it has been signaled by ConditionVariableSignal (or
@@ -182,7 +214,23 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
proclist_push_tail(&cv->wakeup, MyProc->pgprocno, cvWaitLink);
}
SpinLockRelease(&cv->mutex);
- } while (!done);
+
+ /* We were signaled, so return */
+ if (done)
+ return false;
+
+ /* If we're not done, update cur_timeout for next iteration */
+ if (timeout >= 0)
+ {
+ INSTR_TIME_SET_CURRENT(cur_time);
+ INSTR_TIME_SUBTRACT(cur_time, start_time);
+ cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time);
+
+ /* Have we crossed the timeout threshold? */
+ if (cur_timeout <= 0)
+ return true;
+ }
+ }
}
/*
diff --git a/src/include/storage/condition_variable.h b/src/include/storage/condition_variable.h
index 2a0249392cc..ee06e051ce1 100644
--- a/src/include/storage/condition_variable.h
+++ b/src/include/storage/condition_variable.h
@@ -43,6 +43,8 @@ extern void ConditionVariableInit(ConditionVariable *cv);
* the condition variable.
*/
extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info);
+extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
+ uint32 wait_event_info);
extern void ConditionVariableCancelSleep(void);
/*
--
2.21.0