1/* 2 * Copyright 2007-2011, Ingo Weinhold, ingo_weinhold@gmx.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 19struct ConditionVariable; 20 21 22struct ConditionVariableEntry 23 : DoublyLinkedListLinkImpl<ConditionVariableEntry> { 24public: 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 status_t WaitStatus() const { return fWaitStatus; } 36 37 inline ConditionVariable* Variable() const { return fVariable; } 38 39private: 40 inline void AddToVariable(ConditionVariable* variable); 41 42private: 43 ConditionVariable* fVariable; 44 Thread* fThread; 45 status_t fWaitStatus; 46 47 friend struct ConditionVariable; 48}; 49 50 51struct ConditionVariable { 52public: 53 void Init(const void* object, 54 const char* objectType); 55 // for anonymous (unpublished) cvars 56 57 void Publish(const void* object, 58 const char* objectType); 59 void Unpublish(bool schedulerLocked = false); 60 61 inline void NotifyOne(bool schedulerLocked = false, 62 status_t result = B_OK); 63 inline void NotifyAll(bool schedulerLocked = false, 64 status_t result = B_OK); 65 66 static void NotifyOne(const void* object, 67 bool schedulerLocked = false, 68 status_t result = B_OK); 69 static void NotifyAll(const void* object, 70 bool schedulerLocked = false, 71 status_t result = B_OK); 72 // (both methods) caller must ensure that 73 // the variable is not unpublished 74 // concurrently 75 76 void Add(ConditionVariableEntry* entry); 77 78 status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); 79 // all-in one, i.e. doesn't need a 80 // ConditionVariableEntry 81 82 const void* Object() const { return fObject; } 83 const char* ObjectType() const { return fObjectType; } 84 85 static void ListAll(); 86 void Dump() const; 87 88private: 89 void _Notify(bool all, bool schedulerLocked, 90 status_t result); 91 void _NotifyLocked(bool all, status_t result); 92 93protected: 94 typedef DoublyLinkedList<ConditionVariableEntry> EntryList; 95 96 const void* fObject; 97 const char* fObjectType; 98 EntryList fEntries; 99 ConditionVariable* fNext; 100 101 friend struct ConditionVariableEntry; 102 friend struct ConditionVariableHashDefinition; 103}; 104 105 106#if KDEBUG 107 108inline 109ConditionVariableEntry::ConditionVariableEntry() 110 : fVariable(NULL) 111{ 112} 113 114inline 115ConditionVariableEntry::~ConditionVariableEntry() 116{ 117 if (fVariable != NULL) { 118 panic("Destroying condition variable entry %p, but it's still " 119 "attached to variable %p\n", this, fVariable); 120 } 121} 122 123#endif 124 125 126inline void 127ConditionVariable::NotifyOne(bool schedulerLocked, status_t result) 128{ 129 _Notify(false, schedulerLocked, result); 130} 131 132 133inline void 134ConditionVariable::NotifyAll(bool schedulerLocked, status_t result) 135{ 136 _Notify(true, schedulerLocked, result); 137} 138 139 140extern "C" { 141#endif // __cplusplus 142 143extern void condition_variable_init(); 144 145#ifdef __cplusplus 146} // extern "C" 147#endif 148 149#endif /* _KERNEL_CONDITION_VARIABLE_H */ 150