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