xref: /haiku/headers/private/kernel/condition_variable.h (revision f75a7bf508f3156d63a14f8fd77c5e0ca4d08c42)
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