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 canceled 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-2020, 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/proclist_types.h" 26 #include "storage/s_lock.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 bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, 47 uint32 wait_event_info); 48 extern void ConditionVariableCancelSleep(void); 49 50 /* 51 * Optionally, ConditionVariablePrepareToSleep can be called before entering 52 * the test-and-sleep loop described above. Doing so is more efficient if 53 * at least one sleep is needed, whereas not doing so is more efficient when 54 * no sleep is needed because the test condition is true the first time. 55 */ 56 extern void ConditionVariablePrepareToSleep(ConditionVariable *cv); 57 58 /* Wake up a single waiter (via signal) or all waiters (via broadcast). */ 59 extern void ConditionVariableSignal(ConditionVariable *cv); 60 extern void ConditionVariableBroadcast(ConditionVariable *cv); 61 62 #endif /* CONDITION_VARIABLE_H */ 63