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); 31 status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); 32 status_t Wait(const void* object, uint32 flags = 0, 33 bigtime_t timeout = 0); 34 35 inline ConditionVariable* Variable() const { return fVariable; } 36 37 private: 38 inline void AddToVariable(ConditionVariable* variable); 39 40 private: 41 ConditionVariable* fVariable; 42 struct thread* fThread; 43 status_t fWaitStatus; 44 45 friend class ConditionVariable; 46 }; 47 48 49 class ConditionVariable : protected HashTableLink<ConditionVariable> { 50 public: 51 void Init(const void* object, 52 const char* objectType); 53 // for anonymous (unpublished) cvars 54 55 void Publish(const void* object, 56 const char* objectType); 57 void Unpublish(bool threadsLocked = false); 58 59 inline void NotifyOne(bool threadsLocked = false); 60 inline void NotifyAll(bool threadsLocked = false); 61 62 void Add(ConditionVariableEntry* entry); 63 64 status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); 65 // all-in one, i.e. doesn't need a 66 // ConditionVariableEntry 67 68 const void* Object() const { return fObject; } 69 const char* ObjectType() const { return fObjectType; } 70 71 static void ListAll(); 72 void Dump() const; 73 74 private: 75 void _Notify(bool all, bool threadsLocked); 76 void _NotifyChecked(bool all, status_t result); 77 78 protected: 79 typedef DoublyLinkedList<ConditionVariableEntry> EntryList; 80 81 const void* fObject; 82 const char* fObjectType; 83 EntryList fEntries; 84 85 friend class ConditionVariableEntry; 86 friend class ConditionVariableHashDefinition; 87 }; 88 89 90 #if KDEBUG 91 92 inline 93 ConditionVariableEntry::ConditionVariableEntry() 94 : fVariable(NULL) 95 { 96 } 97 98 inline 99 ConditionVariableEntry::~ConditionVariableEntry() 100 { 101 if (fVariable != NULL) { 102 panic("Destroying condition variable entry %p, but it's still " 103 "attached to variable %p\n", this, fVariable); 104 } 105 } 106 107 #endif 108 109 110 inline void 111 ConditionVariable::NotifyOne(bool threadsLocked) 112 { 113 _Notify(false, threadsLocked); 114 } 115 116 117 inline void 118 ConditionVariable::NotifyAll(bool threadsLocked) 119 { 120 _Notify(true, threadsLocked); 121 } 122 123 124 extern "C" { 125 #endif // __cplusplus 126 127 extern void condition_variable_init(); 128 129 #ifdef __cplusplus 130 } // extern "C" 131 #endif 132 133 #endif /* _KERNEL_CONDITION_VARIABLE_H */ 134