µ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++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#if defined(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
15#endif
16
17#include <cmsis-plus/rtos/os.h>
18
19// ----------------------------------------------------------------------------
20
21#if defined(__clang__)
22#pragma clang diagnostic ignored "-Wc++98-compat"
23#endif
24
25// ----------------------------------------------------------------------------
26
27namespace os
28{
29 namespace rtos
30 {
31 // ------------------------------------------------------------------------
32
50 const condition_variable::attributes condition_variable::initializer;
51
52 // ------------------------------------------------------------------------
53
196 // ========================================================================
229 { nullptr, attr }
230 {
231 }
232
264 const char* name, const attributes& attr __attribute__((unused))) :
265 object_named_system
266 { name }
267 {
268#if defined(OS_TRACE_RTOS_CONDVAR)
269 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
270#endif
271
272 // Don't call this from interrupt handlers.
274 }
275
295 {
296#if defined(OS_TRACE_RTOS_CONDVAR)
297 trace::printf ("%s() @%p %s\n", __func__, this, name ());
298#endif
299
300 // There must be no threads waiting for this condition.
301 assert(list_.empty ());
302 }
303
340 {
341#if defined(OS_TRACE_RTOS_CONDVAR)
342 trace::printf ("%s() @%p %s\n", __func__, this, name ());
343#endif
344
345 // Don't call this from interrupt handlers.
347
348 list_.resume_one ();
349
350 return result::ok;
351 }
352
410 {
411#if defined(OS_TRACE_RTOS_CONDVAR)
412 trace::printf ("%s() @%p %s\n", __func__, this, name ());
413#endif
414
415 // Don't call this from interrupt handlers.
417
418 // Wake-up all threads, if any.
419 // Need not be inside the critical section,
420 // the list is protected by inner `resume_one()`.
421 list_.resume_all ();
422
423 return result::ok;
424 }
425
509 condition_variable::wait (mutex& mutex)
510 {
511#if defined(OS_TRACE_RTOS_CONDVAR)
512 trace::printf ("%s() @%p %s\n", __func__, this, name ());
513#endif
514
515 // Don't call this from interrupt handlers.
517 // Don't call this from critical regions.
519
520 thread& crt_thread = this_thread::thread ();
521
522 // Prepare a list node pointing to the current thread.
523 // Do not worry for being on stack, it is temporarily linked to the
524 // list and guaranteed to be removed before this function returns.
525 internal::waiting_thread_node node
526 { crt_thread };
527
528 // TODO: validate
529
530 result_t res;
531 res = mutex.unlock ();
532
533 if (res != result::ok)
534 {
535 return res;
536 }
537
538 {
539 // Add this thread to the condition variable waiting list.
540 list_.link (node);
541 node.thread_->waiting_node_ = &node;
542
543 res = mutex.lock ();
544
545 // Remove the thread from the node waiting list,
546 // if not already removed.
547 node.thread_->waiting_node_ = nullptr;
548 node.unlink ();
549 }
550
551 return res;
552 }
553
655 {
656#if defined(OS_TRACE_RTOS_CONDVAR)
657
658#pragma GCC diagnostic push
659#if defined(__clang__)
660#elif defined(__GNUC__)
661#pragma GCC diagnostic ignored "-Wuseless-cast"
662#endif
663 trace::printf ("%s(%u) @%p %s\n", __func__,
664 static_cast<unsigned int> (timeout), this, name ());
665#pragma GCC diagnostic pop
666
667#endif // defined(OS_TRACE_RTOS_CONDVAR)
668
669 // Don't call this from interrupt handlers.
671 // Don't call this from critical regions.
673
674 thread& crt_thread = this_thread::thread ();
675
676 // Prepare a list node pointing to the current thread.
677 // Do not worry for being on stack, it is temporarily linked to the
678 // list and guaranteed to be removed before this function returns.
679 internal::waiting_thread_node node
680 { crt_thread };
681
682 // TODO: validate
683
684 result_t res;
685 res = mutex.unlock ();
686
687 if (res != result::ok)
688 {
689 return res;
690 }
691
692 {
693 // Add this thread to the condition variable waiting list.
694 list_.link (node);
695 node.thread_->waiting_node_ = &node;
696
697 res = mutex.timed_lock (timeout);
698
699 // Remove the thread from the node waiting list,
700 // if not already removed.
701 node.thread_->waiting_node_ = nullptr;
702 node.unlink ();
703 }
704
705 return res;
706 }
707
708 // --------------------------------------------------------------------------
709
710 } /* namespace rtos */
711} /* namespace os */
712
713// ----------------------------------------------------------------------------
Condition variable attributes.
Definition os-condvar.h:57
POSIX compliant condition variable.
Definition os-condvar.h:46
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:759
Standard thread.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:76
static const attributes initializer
Default condition variable initialiser.
Definition os-condvar.h:110
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1108
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:181
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:856
thread & thread(void)
Get the current running thread.
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:96
System namespace.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1130
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1115
Single file µOS++ RTOS definitions.