condition_variable.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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-2022, 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. #include "storage/proclist_types.h"
  25. #include "storage/spin.h"
  26. typedef struct
  27. {
  28. slock_t mutex; /* spinlock protecting the wakeup list */
  29. proclist_head wakeup; /* list of wake-able processes */
  30. } ConditionVariable;
  31. /*
  32. * Pad a condition variable to a power-of-two size so that an array of
  33. * condition variables does not cross a cache line boundary.
  34. */
  35. #define CV_MINIMAL_SIZE (sizeof(ConditionVariable) <= 16 ? 16 : 32)
  36. typedef union ConditionVariableMinimallyPadded
  37. {
  38. ConditionVariable cv;
  39. char pad[CV_MINIMAL_SIZE];
  40. } ConditionVariableMinimallyPadded;
  41. /* Initialize a condition variable. */
  42. extern void ConditionVariableInit(ConditionVariable *cv);
  43. /*
  44. * To sleep on a condition variable, a process should use a loop which first
  45. * checks the condition, exiting the loop if it is met, and then calls
  46. * ConditionVariableSleep. Spurious wakeups are possible, but should be
  47. * infrequent. After exiting the loop, ConditionVariableCancelSleep must
  48. * be called to ensure that the process is no longer in the wait list for
  49. * the condition variable.
  50. */
  51. extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info);
  52. extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
  53. uint32 wait_event_info);
  54. extern void ConditionVariableCancelSleep(void);
  55. /*
  56. * Optionally, ConditionVariablePrepareToSleep can be called before entering
  57. * the test-and-sleep loop described above. Doing so is more efficient if
  58. * at least one sleep is needed, whereas not doing so is more efficient when
  59. * no sleep is needed because the test condition is true the first time.
  60. */
  61. extern void ConditionVariablePrepareToSleep(ConditionVariable *cv);
  62. /* Wake up a single waiter (via signal) or all waiters (via broadcast). */
  63. extern void ConditionVariableSignal(ConditionVariable *cv);
  64. extern void ConditionVariableBroadcast(ConditionVariable *cv);
  65. #endif /* CONDITION_VARIABLE_H */