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 | |