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