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
28typedef 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. */
35extern 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 */
45extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info);
46extern 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 */
54extern void ConditionVariablePrepareToSleep(ConditionVariable *cv);
55
56/* Wake up a single waiter (via signal) or all waiters (via broadcast). */
57extern void ConditionVariableSignal(ConditionVariable *cv);
58extern void ConditionVariableBroadcast(ConditionVariable *cv);
59
60#endif /* CONDITION_VARIABLE_H */
61