| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * condition_variable.h |
| 4 | * Condition variables |
| 5 | * |
| 6 | * A condition variable is a method of waiting until a certain condition |
| 7 | * becomes true. Conventionally, a condition variable supports three |
| 8 | * operations: (1) sleep; (2) signal, which wakes up one process sleeping |
| 9 | * on the condition variable; and (3) broadcast, which wakes up every |
| 10 | * process sleeping on the condition variable. In our implementation, |
| 11 | * condition variables put a process into an interruptible sleep (so it |
| 12 | * can be cancelled prior to the fulfillment of the condition) and do not |
| 13 | * use pointers internally (so that they are safe to use within DSMs). |
| 14 | * |
| 15 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 16 | * Portions Copyright (c) 1994, Regents of the University of California |
| 17 | * |
| 18 | * src/include/storage/condition_variable.h |
| 19 | * |
| 20 | *------------------------------------------------------------------------- |
| 21 | */ |
| 22 | #ifndef CONDITION_VARIABLE_H |
| 23 | #define CONDITION_VARIABLE_H |
| 24 | |
| 25 | #include "storage/s_lock.h" |
| 26 | #include "storage/proclist_types.h" |
| 27 | |
| 28 | typedef struct |
| 29 | { |
| 30 | slock_t mutex; /* spinlock protecting the wakeup list */ |
| 31 | proclist_head wakeup; /* list of wake-able processes */ |
| 32 | } ConditionVariable; |
| 33 | |
| 34 | /* Initialize a condition variable. */ |
| 35 | extern void ConditionVariableInit(ConditionVariable *cv); |
| 36 | |
| 37 | /* |
| 38 | * To sleep on a condition variable, a process should use a loop which first |
| 39 | * checks the condition, exiting the loop if it is met, and then calls |
| 40 | * ConditionVariableSleep. Spurious wakeups are possible, but should be |
| 41 | * infrequent. After exiting the loop, ConditionVariableCancelSleep must |
| 42 | * be called to ensure that the process is no longer in the wait list for |
| 43 | * the condition variable. |
| 44 | */ |
| 45 | extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info); |
| 46 | extern void ConditionVariableCancelSleep(void); |
| 47 | |
| 48 | /* |
| 49 | * Optionally, ConditionVariablePrepareToSleep can be called before entering |
| 50 | * the test-and-sleep loop described above. Doing so is more efficient if |
| 51 | * at least one sleep is needed, whereas not doing so is more efficient when |
| 52 | * no sleep is needed because the test condition is true the first time. |
| 53 | */ |
| 54 | extern void ConditionVariablePrepareToSleep(ConditionVariable *cv); |
| 55 | |
| 56 | /* Wake up a single waiter (via signal) or all waiters (via broadcast). */ |
| 57 | extern void ConditionVariableSignal(ConditionVariable *cv); |
| 58 | extern void ConditionVariableBroadcast(ConditionVariable *cv); |
| 59 | |
| 60 | #endif /* CONDITION_VARIABLE_H */ |
| 61 | |