1 /*-------------------------------------------------------------------------
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).
15 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
16 * Portions Copyright (c) 1994, Regents of the University of California
18 * src/include/storage/condition_variable.h
20 *-------------------------------------------------------------------------
22 #ifndef CONDITION_VARIABLE_H
23 #define CONDITION_VARIABLE_H
25 #include "storage/proclist_types.h"
26 #include "storage/spin.h"
30 slock_t mutex
; /* spinlock protecting the wakeup list */
31 proclist_head wakeup
; /* list of wake-able processes */
35 * Pad a condition variable to a power-of-two size so that an array of
36 * condition variables does not cross a cache line boundary.
38 #define CV_MINIMAL_SIZE (sizeof(ConditionVariable) <= 16 ? 16 : 32)
39 typedef union ConditionVariableMinimallyPadded
42 char pad
[CV_MINIMAL_SIZE
];
43 } ConditionVariableMinimallyPadded
;
45 /* Initialize a condition variable. */
46 extern void ConditionVariableInit(ConditionVariable
*cv
);
49 * To sleep on a condition variable, a process should use a loop which first
50 * checks the condition, exiting the loop if it is met, and then calls
51 * ConditionVariableSleep. Spurious wakeups are possible, but should be
52 * infrequent. After exiting the loop, ConditionVariableCancelSleep must
53 * be called to ensure that the process is no longer in the wait list for
54 * the condition variable.
56 extern void ConditionVariableSleep(ConditionVariable
*cv
, uint32 wait_event_info
);
57 extern bool ConditionVariableTimedSleep(ConditionVariable
*cv
, long timeout
,
58 uint32 wait_event_info
);
59 extern void ConditionVariableCancelSleep(void);
62 * Optionally, ConditionVariablePrepareToSleep can be called before entering
63 * the test-and-sleep loop described above. Doing so is more efficient if
64 * at least one sleep is needed, whereas not doing so is more efficient when
65 * no sleep is needed because the test condition is true the first time.
67 extern void ConditionVariablePrepareToSleep(ConditionVariable
*cv
);
69 /* Wake up a single waiter (via signal) or all waiters (via broadcast). */
70 extern void ConditionVariableSignal(ConditionVariable
*cv
);
71 extern void ConditionVariableBroadcast(ConditionVariable
*cv
);
73 #endif /* CONDITION_VARIABLE_H */