1 /* 2 * Copyright 2007-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2019, Haiku, Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 #ifndef _KERNEL_CONDITION_VARIABLE_H 7 #define _KERNEL_CONDITION_VARIABLE_H 8 9 10 #include <OS.h> 11 12 #include <debug.h> 13 14 #ifdef __cplusplus 15 16 #include <util/DoublyLinkedList.h> 17 #include <util/OpenHashTable.h> 18 19 20 struct ConditionVariable; 21 22 23 struct ConditionVariableEntry 24 : DoublyLinkedListLinkImpl<ConditionVariableEntry> { 25 public: 26 ConditionVariableEntry(); 27 ~ConditionVariableEntry(); 28 29 bool Add(const void* object); 30 status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); 31 status_t Wait(const void* object, uint32 flags = 0, 32 bigtime_t timeout = 0); 33 34 inline status_t WaitStatus() const { return fWaitStatus; } 35 36 inline ConditionVariable* Variable() const { return fVariable; } 37 38 private: 39 inline void _AddToLockedVariable(ConditionVariable* variable); 40 void _RemoveFromVariable(); 41 42 private: 43 spinlock fLock; 44 ConditionVariable* fVariable; 45 Thread* fThread; 46 status_t fWaitStatus; 47 48 friend struct ConditionVariable; 49 }; 50 51 52 struct ConditionVariable { 53 public: 54 void Init(const void* object, 55 const char* objectType); 56 // for anonymous (unpublished) cvars 57 58 void Publish(const void* object, 59 const char* objectType); 60 void Unpublish(); 61 62 inline void NotifyOne(status_t result = B_OK); 63 inline void NotifyAll(status_t result = B_OK); 64 65 static void NotifyOne(const void* object, status_t result); 66 static void NotifyAll(const void* object, status_t result); 67 // (both methods) caller must ensure that 68 // the variable is not unpublished 69 // concurrently 70 71 void Add(ConditionVariableEntry* entry); 72 73 status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); 74 // all-in one, i.e. doesn't need a 75 // ConditionVariableEntry 76 77 const void* Object() const { return fObject; } 78 const char* ObjectType() const { return fObjectType; } 79 80 static void ListAll(); 81 void Dump() const; 82 83 private: 84 void _Notify(bool all, status_t result); 85 void _NotifyLocked(bool all, status_t result); 86 87 protected: 88 typedef DoublyLinkedList<ConditionVariableEntry> EntryList; 89 90 const void* fObject; 91 const char* fObjectType; 92 93 spinlock fLock; 94 EntryList fEntries; 95 ConditionVariable* fNext; 96 97 friend struct ConditionVariableEntry; 98 friend struct ConditionVariableHashDefinition; 99 }; 100 101 102 inline void 103 ConditionVariable::NotifyOne(status_t result) 104 { 105 _Notify(false, result); 106 } 107 108 109 inline void 110 ConditionVariable::NotifyAll(status_t result) 111 { 112 _Notify(true, result); 113 } 114 115 116 extern "C" { 117 #endif // __cplusplus 118 119 extern void condition_variable_init(); 120 121 #ifdef __cplusplus 122 } // extern "C" 123 #endif 124 125 #endif /* _KERNEL_CONDITION_VARIABLE_H */ 126