µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os-condvar.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#if defined(OS_USE_OS_APP_CONFIG_H)
13#include <cmsis-plus/os-app-config.h>
14#endif
15
16#include <cmsis-plus/rtos/os.h>
17
18// ----------------------------------------------------------------------------
19
20#if defined(__clang__)
21#pragma clang diagnostic ignored "-Wc++98-compat"
22#endif
23
24// ----------------------------------------------------------------------------
25
26namespace os
27{
28 namespace rtos
29 {
30 // ------------------------------------------------------------------------
31
51 const condition_variable::attributes condition_variable::initializer;
52
53 // ------------------------------------------------------------------------
54
200 // ========================================================================
235 : condition_variable{ nullptr, attr }
236 {
237 }
238
273 const attributes& attr
274 __attribute__ ((unused)))
275 : object_named_system{ name }
276 {
277#if defined(OS_TRACE_RTOS_CONDVAR)
278 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
279#endif
280
281 // Don't call this from interrupt handlers.
283 }
284
307 {
308#if defined(OS_TRACE_RTOS_CONDVAR)
309 trace::printf ("%s() @%p %s\n", __func__, this, name ());
310#endif
311
312 // There must be no threads waiting for this condition.
313 assert (list_.empty ());
314 }
315
355 {
356#if defined(OS_TRACE_RTOS_CONDVAR)
357 trace::printf ("%s() @%p %s\n", __func__, this, name ());
358#endif
359
360 // Don't call this from interrupt handlers.
362
363 list_.resume_one ();
364
365 return result::ok;
366 }
367
428 {
429#if defined(OS_TRACE_RTOS_CONDVAR)
430 trace::printf ("%s() @%p %s\n", __func__, this, name ());
431#endif
432
433 // Don't call this from interrupt handlers.
435
436 // Wake-up all threads, if any.
437 // Need not be inside the critical section,
438 // the list is protected by inner `resume_one()`.
439 list_.resume_all ();
440
441 return result::ok;
442 }
443
530 condition_variable::wait (mutex& mutex)
531 {
532#if defined(OS_TRACE_RTOS_CONDVAR)
533 trace::printf ("%s() @%p %s\n", __func__, this, name ());
534#endif
535
536 // Don't call this from interrupt handlers.
538 // Don't call this from critical regions.
539 os_assert_err (!scheduler::locked (), EPERM);
540
541 thread& crt_thread = this_thread::thread ();
542
543 // Prepare a list node pointing to the current thread.
544 // Do not worry for being on stack, it is temporarily linked to the
545 // list and guaranteed to be removed before this function returns.
546 internal::waiting_thread_node node{ crt_thread };
547
548 // TODO: validate
549
550 result_t res;
551 res = mutex.unlock ();
552
553 if (res != result::ok)
554 {
555 return res;
556 }
557
558 {
559 // Add this thread to the condition variable waiting list.
560 list_.link (node);
561 node.thread_->waiting_node_ = &node;
562
563 res = mutex.lock ();
564
565 // Remove the thread from the node waiting list,
566 // if not already removed.
567 node.thread_->waiting_node_ = nullptr;
568 node.unlink ();
569 }
570
571 return res;
572 }
573
678 {
679#if defined(OS_TRACE_RTOS_CONDVAR)
680
681#pragma GCC diagnostic push
682#if defined(__clang__)
683#elif defined(__GNUC__)
684#pragma GCC diagnostic ignored "-Wuseless-cast"
685#endif
686 trace::printf ("%s(%u) @%p %s\n", __func__,
687 static_cast<unsigned int> (timeout), this, name ());
688#pragma GCC diagnostic pop
689
690#endif // defined(OS_TRACE_RTOS_CONDVAR)
691
692 // Don't call this from interrupt handlers.
694 // Don't call this from critical regions.
695 os_assert_err (!scheduler::locked (), EPERM);
696
697 thread& crt_thread = this_thread::thread ();
698
699 // Prepare a list node pointing to the current thread.
700 // Do not worry for being on stack, it is temporarily linked to the
701 // list and guaranteed to be removed before this function returns.
702 internal::waiting_thread_node node{ crt_thread };
703
704 // TODO: validate
705
706 result_t res;
707 res = mutex.unlock ();
708
709 if (res != result::ok)
710 {
711 return res;
712 }
713
714 {
715 // Add this thread to the condition variable waiting list.
716 list_.link (node);
717 node.thread_->waiting_node_ = &node;
718
719 res = mutex.timed_lock (timeout);
720
721 // Remove the thread from the node waiting list,
722 // if not already removed.
723 node.thread_->waiting_node_ = nullptr;
724 node.unlink ();
725 }
726
727 return res;
728 }
729
730 // ------------------------------------------------------------------------
731
732 } /* namespace rtos */
733} /* namespace os */
734
735// ----------------------------------------------------------------------------
Condition variable attributes.
Definition os-condvar.h:55
POSIX compliant condition variable.
Definition os-condvar.h:45
result_t signal(void)
Notify one thread waiting for a condition variable.
result_t broadcast(void)
Notify all threads waiting for a condition variable.
result_t wait(mutex &mutex)
Wait for a condition variable to be notified.
condition_variable(const attributes &attr=initializer)
Construct a condition variable object instance.
~condition_variable()
Destruct the condition variable object instance.
result_t timed_wait(mutex &mutex, clock::duration_t timeout)
Timed wait for a condition variable to be notified.
const char * name(void) const
Get object name.
Definition os-decls.h:753
Standard thread.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:78
static const attributes initializer
Default condition variable initialiser.
Definition os-condvar.h:107
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:179
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:858
thread & thread(void)
Get the current running thread.
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:95
System namespace.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1122
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1101
Single file µOS++ RTOS definitions.