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