xref: /haiku/src/libs/compat/freebsd_network/condvar.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2022-2023, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT license.
4  */
5 
6 extern "C" {
7 #include <compat/sys/mutex.h>
8 #include <compat/sys/kernel.h>
9 #include <compat/sys/condvar.h>
10 }
11 
12 #include <condition_variable.h>
13 
14 
15 static_assert(sizeof(cv::condition) == sizeof(ConditionVariable));
16 
17 
18 void
19 cv_init(struct cv* variable, const char* description)
20 {
21 	__cv_ConditionVariable(variable)->Init(NULL, description);
22 }
23 
24 
25 void
26 cv_destroy(struct cv* variable)
27 {
28 	__cv_ConditionVariable(variable)->NotifyAll();
29 
30 	// Nothing else to do.
31 }
32 
33 
34 void
35 cv_signal(struct cv* variable)
36 {
37 	__cv_ConditionVariable(variable)->NotifyOne();
38 }
39 
40 
41 int
42 cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout)
43 {
44 	ConditionVariable* condition = __cv_ConditionVariable(variable);
45 
46 	const uint32 flags = timeout ? B_RELATIVE_TIMEOUT : 0;
47 	const bigtime_t bigtimeout = TICKS_2_USEC(timeout);
48 	int status;
49 
50 	if (mutex->type == MTX_RECURSE) {
51 		// Special case: let the ConditionVariable handle switching recursive locks.
52 		status = condition->Wait(&mutex->u.recursive,
53 			flags, bigtimeout);
54 		return status;
55 	}
56 
57 	ConditionVariableEntry entry;
58 	condition->Add(&entry);
59 
60 	mtx_unlock(mutex);
61 
62 	status = entry.Wait(flags, bigtimeout);
63 
64 	mtx_lock(mutex);
65 	return status;
66 }
67 
68 
69 void
70 cv_wait(struct cv* variable, struct mtx* mutex)
71 {
72 	cv_timedwait(variable, mutex, 0);
73 }
74