µ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 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#include <cmsis-plus/rtos/os.h>
29
30// ----------------------------------------------------------------------------
31
32#if defined(__clang__)
33#pragma clang diagnostic ignored "-Wc++98-compat"
34#endif
35
36// ----------------------------------------------------------------------------
37
38namespace os
39{
40 namespace rtos
41 {
42 // ------------------------------------------------------------------------
43
61 const condition_variable::attributes condition_variable::initializer;
62
63 // ------------------------------------------------------------------------
64
207 // ========================================================================
240 { nullptr, attr }
241 {
242 ;
243 }
244
276 const char* name, const attributes& attr __attribute__((unused))) :
277 object_named_system
278 { name }
279 {
280#if defined(OS_TRACE_RTOS_CONDVAR)
281 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
282#endif
283
284 // Don't call this from interrupt handlers.
286 }
287
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
352 {
353#if defined(OS_TRACE_RTOS_CONDVAR)
354 trace::printf ("%s() @%p %s\n", __func__, this, name ());
355#endif
356
357 // Don't call this from interrupt handlers.
359
360 list_.resume_one ();
361
362 return result::ok;
363 }
364
422 {
423#if defined(OS_TRACE_RTOS_CONDVAR)
424 trace::printf ("%s() @%p %s\n", __func__, this, name ());
425#endif
426
427 // Don't call this from interrupt handlers.
429
430 // Wake-up all threads, if any.
431 // Need not be inside the critical section,
432 // the list is protected by inner `resume_one()`.
433 list_.resume_all ();
434
435 return result::ok;
436 }
437
521 condition_variable::wait (mutex& mutex)
522 {
523#if defined(OS_TRACE_RTOS_CONDVAR)
524 trace::printf ("%s() @%p %s\n", __func__, this, name ());
525#endif
526
527 // Don't call this from interrupt handlers.
529 // Don't call this from critical regions.
531
532 thread& crt_thread = this_thread::thread ();
533
534 // Prepare a list node pointing to the current thread.
535 // Do not worry for being on stack, it is temporarily linked to the
536 // list and guaranteed to be removed before this function returns.
537 internal::waiting_thread_node node
538 { crt_thread };
539
540 // TODO: validate
541
542 result_t res;
543 res = mutex.unlock ();
544
545 if (res != result::ok)
546 {
547 return res;
548 }
549
550 {
551 // Add this thread to the condition variable waiting list.
552 list_.link (node);
553 node.thread_->waiting_node_ = &node;
554
555 res = mutex.lock ();
556
557 // Remove the thread from the node waiting list,
558 // if not already removed.
559 node.thread_->waiting_node_ = nullptr;
560 node.unlink ();
561 }
562
563 return res;
564 }
565
667 {
668#if defined(OS_TRACE_RTOS_CONDVAR)
669 trace::printf ("%s(%u) @%p %s\n", __func__,
670 static_cast<unsigned int> (timeout), this, name ());
671#endif
672
673 // Don't call this from interrupt handlers.
675 // Don't call this from critical regions.
677
678 thread& crt_thread = this_thread::thread ();
679
680 // Prepare a list node pointing to the current thread.
681 // Do not worry for being on stack, it is temporarily linked to the
682 // list and guaranteed to be removed before this function returns.
683 internal::waiting_thread_node node
684 { crt_thread };
685
686 // TODO: validate
687
688 result_t res;
689 res = mutex.unlock ();
690
691 if (res != result::ok)
692 {
693 return res;
694 }
695
696 {
697 // Add this thread to the condition variable waiting list.
698 list_.link (node);
699 node.thread_->waiting_node_ = &node;
700
701 res = mutex.timed_lock (timeout);
702
703 // Remove the thread from the node waiting list,
704 // if not already removed.
705 node.thread_->waiting_node_ = nullptr;
706 node.unlink ();
707 }
708
709 return res;
710 }
711
712 // --------------------------------------------------------------------------
713
714 } /* namespace rtos */
715} /* namespace os */
716
717// ----------------------------------------------------------------------------
Condition variable attributes.
Definition os-condvar.h:73
POSIX compliant condition variable.
Definition os-condvar.h:62
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:774
Standard thread.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:83
static const attributes initializer
Default condition variable initialiser.
Definition os-condvar.h:126
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1136
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:195
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:882
thread & thread(void)
Get the current running thread.
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:110
System namespace.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1141
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1126
Single file µOS++ RTOS definitions.