1/*
2 * Copyright 2022-2023, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
4 */
5
6extern "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
15static_assert(sizeof(cv::condition) == sizeof(ConditionVariable));
16
17
18void
19cv_init(struct cv* variable, const char* description)
20{
21	__cv_ConditionVariable(variable)->Init(NULL, description);
22}
23
24
25void
26cv_destroy(struct cv* variable)
27{
28	__cv_ConditionVariable(variable)->NotifyAll();
29
30	// Nothing else to do.
31}
32
33
34void
35cv_signal(struct cv* variable)
36{
37	__cv_ConditionVariable(variable)->NotifyOne();
38}
39
40
41int
42cv_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
69void
70cv_wait(struct cv* variable, struct mtx* mutex)
71{
72	cv_timedwait(variable, mutex, 0);
73}
74