1 /* 2 * Copyright 2007-2008, Ingo Weinhold, bonefish@cs.tu-berlin.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_CONDITION_VARIABLE_H 6 #define _KERNEL_CONDITION_VARIABLE_H 7 8 9 #include <OS.h> 10 11 #include <debug.h> 12 13 #ifdef __cplusplus 14 15 #include <util/DoublyLinkedList.h> 16 #include <util/OpenHashTable.h> 17 18 19 class ConditionVariable; 20 21 22 struct ConditionVariableEntry 23 : DoublyLinkedListLinkImpl<ConditionVariableEntry> { 24 public: 25 #if KDEBUG 26 inline ConditionVariableEntry(); 27 inline ~ConditionVariableEntry(); 28 #endif 29 30 bool Add(const void* object, uint32 flags = 0); 31 status_t Wait(uint32 timeoutFlags = 0, 32 bigtime_t timeout = 0); 33 status_t Wait(const void* object, uint32 flags = 0, 34 bigtime_t timeout = 0); 35 36 inline ConditionVariable* Variable() const { return fVariable; } 37 38 private: 39 inline void AddToVariable(ConditionVariable* variable, 40 uint32 flags); 41 42 private: 43 ConditionVariable* fVariable; 44 struct thread* fThread; 45 46 friend class ConditionVariable; 47 }; 48 49 50 class ConditionVariable : protected HashTableLink<ConditionVariable> { 51 public: 52 void Init(const void* object, 53 const char* objectType); 54 // for anonymous (unpublished) cvars 55 56 void Publish(const void* object, 57 const char* objectType); 58 void Unpublish(bool threadsLocked = false); 59 60 inline void NotifyOne(bool threadsLocked = false); 61 inline void NotifyAll(bool threadsLocked = false); 62 63 void Add(ConditionVariableEntry* entry, 64 uint32 flags = 0); 65 66 const void* Object() const { return fObject; } 67 68 static void ListAll(); 69 void Dump() const; 70 71 private: 72 void _Notify(bool all, bool threadsLocked); 73 void _NotifyChecked(bool all, status_t result); 74 75 protected: 76 typedef DoublyLinkedList<ConditionVariableEntry> EntryList; 77 78 const void* fObject; 79 const char* fObjectType; 80 EntryList fEntries; 81 82 friend class ConditionVariableEntry; 83 friend class ConditionVariableHashDefinition; 84 }; 85 86 87 #if KDEBUG 88 89 inline 90 ConditionVariableEntry::ConditionVariableEntry() 91 : fVariable(NULL) 92 { 93 } 94 95 inline 96 ConditionVariableEntry::~ConditionVariableEntry() 97 { 98 if (fVariable != NULL) { 99 panic("Destroying condition variable entry %p, but it's still " 100 "attached to variable %p\n", this, fVariable); 101 } 102 } 103 104 #endif 105 106 107 inline void 108 ConditionVariable::NotifyOne(bool threadsLocked) 109 { 110 _Notify(false, threadsLocked); 111 } 112 113 114 inline void 115 ConditionVariable::NotifyAll(bool threadsLocked) 116 { 117 _Notify(true, threadsLocked); 118 } 119 120 121 extern "C" { 122 #endif // __cplusplus 123 124 extern void condition_variable_init(); 125 126 #ifdef __cplusplus 127 } // extern "C" 128 #endif 129 130 #endif /* _KERNEL_CONDITION_VARIABLE_H */ 131