13#if defined(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
22#pragma clang diagnostic ignored "-Wc++98-compat"
469 type_ (attr.mx_type),
470 protocol_ (attr.mx_protocol),
471 robustness_ (attr.mx_robustness),
472 max_count_ ((attr.mx_type == type::recursive) ? attr.mx_max_count : 1)
474#if defined(OS_TRACE_RTOS_MUTEX)
475 trace::printf (
"%s() @%p %s\n", __func__,
this, this->name ());
485#if !defined(OS_USE_RTOS_PORT_MUTEX)
486 clock_ = attr.clock !=
nullptr ? attr.clock : &
sysclock;
494 initial_prio_ceiling_ = attr.mx_priority_ceiling;
495 prio_ceiling_ = attr.mx_priority_ceiling;
497#if defined(OS_USE_RTOS_PORT_MUTEX)
500 port::mutex::create (
this);
528#if defined(OS_TRACE_RTOS_MUTEX)
532#if defined(OS_USE_RTOS_PORT_MUTEX)
534 port::mutex::destroy (
this);
539 assert(owner_ ==
nullptr);
541 assert(list_.empty ());
551 mutex::internal_init_ (
void)
554 owner_links_.unlink ();
556 prio_ceiling_ = initial_prio_ceiling_;
562#if !defined(OS_USE_RTOS_PORT_MUTEX)
577 mutex::internal_try_lock_ (
thread* th)
580 thread* saved_owner = owner_;
583 if (owner_ ==
nullptr)
594 th_list->link (*
this);
596#pragma GCC diagnostic push
597#if defined(__clang__)
598#pragma clang diagnostic ignored "-Wdeprecated-volatile"
599#elif defined(__GNUC__)
600#pragma GCC diagnostic ignored "-Wvolatile"
603 ++(owner_->acquired_mutexes_);
604#pragma GCC diagnostic pop
608 if (th->priority () > prio_ceiling_)
627 boosted_prio_ = prio_ceiling_;
628 if (boosted_prio_ > owner_->priority_inherited ())
631 scheduler::uncritical_section sucs;
633 owner_->priority_inherited (boosted_prio_);
638#if defined(OS_TRACE_RTOS_MUTEX)
655 if (saved_owner == th)
660 if (count_ >= max_count_)
663#if defined(OS_TRACE_RTOS_MUTEX)
670#pragma GCC diagnostic push
671#if defined(__clang__)
672#pragma clang diagnostic ignored "-Wdeprecated-volatile"
673#elif defined(__GNUC__)
674#pragma GCC diagnostic ignored "-Wvolatile"
678#pragma GCC diagnostic pop
680#if defined(OS_TRACE_RTOS_MUTEX)
682 name (), th, th->name (), count_);
689#if defined(OS_TRACE_RTOS_MUTEX)
696#if defined(OS_TRACE_RTOS_MUTEX)
724 boosted_prio_ = prio;
726 if (owner_links_.unlinked ())
730 th_list->link (*
this);
734 if ((boosted_prio_ > owner_->priority_inherited ()))
737 scheduler::uncritical_section sucs;
739 owner_->priority_inherited (boosted_prio_);
743#if defined(OS_TRACE_RTOS_MUTEX)
744 trace::printf (
"%s() @%p %s boost %u by %p %s \n", __func__,
this,
745 name (), boosted_prio_, th, th->name ());
757 mutex::internal_unlock_ (
thread* th)
761 return ENOTRECOVERABLE;
766 scheduler::critical_section scs;
773#pragma GCC diagnostic push
774#if defined(__clang__)
775#pragma clang diagnostic ignored "-Wdeprecated-volatile"
776#elif defined(__GNUC__)
777#pragma GCC diagnostic ignored "-Wvolatile"
781#pragma GCC diagnostic pop
783#if defined(OS_TRACE_RTOS_MUTEX)
790#pragma GCC diagnostic push
791#if defined(__clang__)
792#pragma clang diagnostic ignored "-Wdeprecated-volatile"
793#elif defined(__GNUC__)
794#pragma GCC diagnostic ignored "-Wvolatile"
796 --(owner_->acquired_mutexes_);
797#pragma GCC diagnostic pop
801 owner_links_.unlink ();
808 if (thread_mutexes->empty ())
820#pragma GCC diagnostic push
821#if defined(__clang__)
822#elif defined(__GNUC__)
823#pragma GCC diagnostic ignored "-Waggregate-return"
825 for (
auto&& mx : *thread_mutexes)
827 if (mx.boosted_prio_ > max_prio)
829 max_prio = mx.boosted_prio_;
832#pragma GCC diagnostic pop
833 boosted_prio_ = max_prio;
836 owner_->priority_inherited (boosted_prio_);
846#if defined(OS_TRACE_RTOS_MUTEX)
861 recoverable_ =
false;
862 return ENOTRECOVERABLE;
873#if defined(OS_TRACE_RTOS_MUTEX)
882#if defined(OS_TRACE_RTOS_MUTEX)
883 trace::printf (
"%s() ENOTRECOVERABLE @%p %s \n", __func__,
this,
886 return ENOTRECOVERABLE;
893 mutex::internal_mark_owner_dead_ (
void)
957#if defined(OS_TRACE_RTOS_MUTEX)
969 return ENOTRECOVERABLE;
972#if defined(OS_USE_RTOS_PORT_MUTEX)
974 return port::mutex::lock (
this);
985 res = internal_try_lock_ (&crt_thread);
986 if (res != EWOULDBLOCK)
1005 res = internal_try_lock_ (&crt_thread);
1006 if (res != EWOULDBLOCK)
1016 scheduler::internal_link_node (list_, node);
1027 scheduler::internal_unlink_node (node);
1031#if defined(OS_TRACE_RTOS_MUTEX)
1039 return ENOTRECOVERABLE;
1078#if defined(OS_TRACE_RTOS_MUTEX)
1088 return ENOTRECOVERABLE;
1091#if defined(OS_USE_RTOS_PORT_MUTEX)
1093 return port::mutex::try_lock (
this);
1103 return internal_try_lock_ (&crt_thread);
1154#if defined(OS_TRACE_RTOS_MUTEX)
1155#pragma GCC diagnostic push
1156#if defined(__clang__)
1157#elif defined(__GNUC__)
1158#pragma GCC diagnostic ignored "-Wuseless-cast"
1161 static_cast<unsigned int> (timeout),
this,
name (),
1163#pragma GCC diagnostic pop
1173 return ENOTRECOVERABLE;
1176#if defined(OS_USE_RTOS_PORT_MUTEX)
1178 return port::mutex::timed_lock (
this, timeout);
1192 res = internal_try_lock_ (&crt_thread);
1193 if (res != EWOULDBLOCK)
1211 { timeout_timestamp, crt_thread };
1219 res = internal_try_lock_ (&crt_thread);
1220 if (res != EWOULDBLOCK)
1231 scheduler::internal_link_node (list_, node, clock_list,
1244 scheduler::internal_unlink_node (node, timeout_node);
1250#if defined(OS_TRACE_RTOS_MUTEX)
1255 else if (clock_->steady_now () >= timeout_timestamp)
1257#if defined(OS_TRACE_RTOS_MUTEX)
1272#pragma GCC diagnostic push
1273#if defined(__clang__)
1274#elif defined(__GNUC__)
1275#pragma GCC diagnostic ignored "-Waggregate-return"
1277 for (
auto&& th : list_)
1280 if (prio > max_prio)
1285#pragma GCC diagnostic pop
1289 boosted_prio_ = max_prio;
1290 owner_->priority (boosted_prio_);
1298 return ENOTRECOVERABLE;
1326#if defined(OS_TRACE_RTOS_MUTEX)
1334#if defined(OS_USE_RTOS_PORT_MUTEX)
1336 return port::mutex::unlock (
this);
1342 return internal_unlock_ (crt_thread);
1361#if defined(OS_TRACE_RTOS_MUTEX)
1368#if defined(OS_USE_RTOS_PORT_MUTEX)
1370 return port::mutex::prio_ceiling (
this);
1374 return prio_ceiling_;
1403#if defined(OS_TRACE_RTOS_MUTEX)
1410#if defined(OS_USE_RTOS_PORT_MUTEX)
1412 return port::mutex::prio_ceiling (
this,
prio_ceiling, old_prio_ceiling);
1423 if (old_prio_ceiling !=
nullptr)
1425 *old_prio_ceiling = prio_ceiling_;
1468#if defined(OS_TRACE_RTOS_MUTEX)
1479#if defined(OS_USE_RTOS_PORT_MUTEX)
1481 return port::mutex::consistent (
this);
1505#if defined(OS_TRACE_RTOS_MUTEX)
Ordered list of time stamp nodes.
const char * name(void) const
Get object name.
Double linked list node, with time stamp and thread.
Double linked list node, with thread reference.
Interrupts critical section RAII helper.
result_t reset(void)
Reset the mutex.
result_t lock(void)
Lock/acquire the mutex.
thread::priority_t prio_ceiling(void) const
Get the priority ceiling of a mutex.
mutex(const attributes &attr=initializer_normal)
Construct a mutex object instance.
result_t timed_lock(clock::duration_t timeout)
Timed attempt to lock/acquire the mutex.
result_t try_lock(void)
Try to lock/acquire the mutex.
~mutex()
Destruct the mutex object instance.
result_t consistent(void)
Mark mutex as consistent.
result_t unlock(void)
Unlock/release the mutex.
Scheduler critical section RAII helper.
POSIX compliant thread, using the default RTOS allocator.
bool interrupted(void)
Check if interrupted.
The core of a double linked list, pointers to next, previous.
int printf(const char *format,...)
Write a formatted string to the trace device.
port::clock::duration_t duration_t
Type of variables holding clock durations.
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
clock_systick sysclock
The system clock object instance.
static const attributes_recursive initializer_recursive
Default recursive mutex initialiser.
static const attributes initializer_normal
Default normal mutex initialiser.
uint8_t priority_t
Type of variables holding thread priorities.
bool in_handler_mode(void)
Check if the CPU is in handler mode.
@ ok
Function completed; no errors or events occurred.
bool locked(void)
Check if the scheduler is locked.
thread & thread(void)
Get the current running thread.
utils::intrusive_list< mutex, utils::double_list_links, &mutex::owner_links_ > mutexes_list
uint32_t result_t
Type of values returned by RTOS functions.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
#define os_assert_err(__e, __er)
Assert or return an error.
Single file µOS++ RTOS definitions.
@ inherit
Inherit priority from highest priority thread.
@ protect
Execute at the highest priority.
@ robust
Enhanced robustness at thread termination.
@ normal
Normal mutex behaviour.
@ errorcheck
Check mutex behaviour.
@ recursive
Recursive mutex behaviour.