xref: /haiku/headers/private/kernel/condition_variable.h (revision 1757f197bd98997256fea2918bfa4603bf81b748)
1 /*
2  * Copyright 2007-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2019, Haiku, Inc. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 #ifndef _KERNEL_CONDITION_VARIABLE_H
7 #define _KERNEL_CONDITION_VARIABLE_H
8 
9 
10 #include <OS.h>
11 
12 #include <debug.h>
13 
14 #ifdef __cplusplus
15 
16 #include <util/DoublyLinkedList.h>
17 #include <util/OpenHashTable.h>
18 
19 
20 struct ConditionVariable;
21 
22 
23 struct ConditionVariableEntry
24 	: DoublyLinkedListLinkImpl<ConditionVariableEntry> {
25 public:
26 								ConditionVariableEntry();
27 								~ConditionVariableEntry();
28 
29 			bool				Add(const void* object);
30 			status_t			Wait(uint32 flags = 0, bigtime_t timeout = 0);
31 			status_t			Wait(const void* object, uint32 flags = 0,
32 									bigtime_t timeout = 0);
33 
34 	inline	status_t			WaitStatus() const { return fWaitStatus; }
35 
36 	inline	ConditionVariable*	Variable() const { return fVariable; }
37 
38 private:
39 	inline	void				_AddToLockedVariable(ConditionVariable* variable);
40 			void				_RemoveFromVariable();
41 
42 private:
43 			spinlock			fLock;
44 			ConditionVariable*	fVariable;
45 			Thread*				fThread;
46 			status_t			fWaitStatus;
47 
48 			friend struct ConditionVariable;
49 };
50 
51 
52 struct ConditionVariable {
53 public:
54 			void				Init(const void* object,
55 									const char* objectType);
56 									// for anonymous (unpublished) cvars
57 
58 			void				Publish(const void* object,
59 									const char* objectType);
60 			void				Unpublish();
61 
62 	inline	void				NotifyOne(status_t result = B_OK);
63 	inline	void				NotifyAll(status_t result = B_OK);
64 
65 	static	void				NotifyOne(const void* object, status_t result);
66 	static	void				NotifyAll(const void* object, status_t result);
67 									// (both methods) caller must ensure that
68 									// the variable is not unpublished
69 									// concurrently
70 
71 			void				Add(ConditionVariableEntry* entry);
72 
73 			status_t			Wait(uint32 flags = 0, bigtime_t timeout = 0);
74 									// all-in one, i.e. doesn't need a
75 									// ConditionVariableEntry
76 
77 			const void*			Object() const		{ return fObject; }
78 			const char*			ObjectType() const	{ return fObjectType; }
79 
80 	static	void				ListAll();
81 			void				Dump() const;
82 
83 private:
84 			void				_Notify(bool all, status_t result);
85 			void				_NotifyLocked(bool all, status_t result);
86 
87 protected:
88 			typedef DoublyLinkedList<ConditionVariableEntry> EntryList;
89 
90 			const void*			fObject;
91 			const char*			fObjectType;
92 
93 			spinlock			fLock;
94 			EntryList			fEntries;
95 			ConditionVariable*	fNext;
96 
97 			friend struct ConditionVariableEntry;
98 			friend struct ConditionVariableHashDefinition;
99 };
100 
101 
102 inline void
103 ConditionVariable::NotifyOne(status_t result)
104 {
105 	_Notify(false, result);
106 }
107 
108 
109 inline void
110 ConditionVariable::NotifyAll(status_t result)
111 {
112 	_Notify(true, result);
113 }
114 
115 
116 extern "C" {
117 #endif	// __cplusplus
118 
119 extern void condition_variable_init();
120 
121 #ifdef __cplusplus
122 }	// extern "C"
123 #endif
124 
125 #endif	/* _KERNEL_CONDITION_VARIABLE_H */
126