33#pragma clang diagnostic ignored "-Wc++98-compat"
481 type_ (attr.mx_type),
482 protocol_ (attr.mx_protocol),
483 robustness_ (attr.mx_robustness),
484 max_count_ ((attr.mx_type == type::recursive) ? attr.mx_max_count : 1)
486#if defined(OS_TRACE_RTOS_MUTEX)
487 trace::printf (
"%s() @%p %s\n", __func__,
this, this->name ());
497#if !defined(OS_USE_RTOS_PORT_MUTEX)
498 clock_ = attr.clock !=
nullptr ? attr.clock : &
sysclock;
506 initial_prio_ceiling_ = attr.mx_priority_ceiling;
507 prio_ceiling_ = attr.mx_priority_ceiling;
509#if defined(OS_USE_RTOS_PORT_MUTEX)
512 port::mutex::create (
this);
540#if defined(OS_TRACE_RTOS_MUTEX)
544#if defined(OS_USE_RTOS_PORT_MUTEX)
546 port::mutex::destroy (
this);
551 assert(owner_ ==
nullptr);
553 assert(list_.empty ());
563 mutex::internal_init_ (
void)
566 owner_links_.unlink ();
568 prio_ceiling_ = initial_prio_ceiling_;
574#if !defined(OS_USE_RTOS_PORT_MUTEX)
589 mutex::internal_try_lock_ (
class thread* th)
592 thread* saved_owner = owner_;
595 if (owner_ ==
nullptr)
606 th_list->link (*
this);
608#pragma GCC diagnostic push
609#if defined(__clang__)
610#pragma clang diagnostic ignored "-Wdeprecated-volatile"
613 ++(owner_->acquired_mutexes_);
614#pragma GCC diagnostic pop
618 if (th->priority () > prio_ceiling_)
637 boosted_prio_ = prio_ceiling_;
638 if (boosted_prio_ > owner_->priority_inherited ())
641 scheduler::uncritical_section sucs;
643 owner_->priority_inherited (boosted_prio_);
648#if defined(OS_TRACE_RTOS_MUTEX)
665 if (saved_owner == th)
670 if (count_ >= max_count_)
673#if defined(OS_TRACE_RTOS_MUTEX)
680#pragma GCC diagnostic push
681#if defined(__clang__)
682#pragma clang diagnostic ignored "-Wdeprecated-volatile"
686#pragma GCC diagnostic pop
688#if defined(OS_TRACE_RTOS_MUTEX)
690 name (), th, th->name (), count_);
697#if defined(OS_TRACE_RTOS_MUTEX)
704#if defined(OS_TRACE_RTOS_MUTEX)
732 boosted_prio_ = prio;
734 if (owner_links_.unlinked ())
738 th_list->link (*
this);
742 if ((boosted_prio_ > owner_->priority_inherited ()))
745 scheduler::uncritical_section sucs;
747 owner_->priority_inherited (boosted_prio_);
751#if defined(OS_TRACE_RTOS_MUTEX)
752 trace::printf (
"%s() @%p %s boost %u by %p %s \n", __func__,
this,
753 name (), boosted_prio_, th, th->name ());
765 mutex::internal_unlock_ (
thread* th)
769 return ENOTRECOVERABLE;
774 scheduler::critical_section scs;
781#pragma GCC diagnostic push
782#if defined(__clang__)
783#pragma clang diagnostic ignored "-Wdeprecated-volatile"
787#pragma GCC diagnostic pop
789#if defined(OS_TRACE_RTOS_MUTEX)
796#pragma GCC diagnostic push
797#if defined(__clang__)
798#pragma clang diagnostic ignored "-Wdeprecated-volatile"
800 --(owner_->acquired_mutexes_);
801#pragma GCC diagnostic pop
805 owner_links_.unlink ();
812 if (thread_mutexes->empty ())
824 for (
auto&& mx : *thread_mutexes)
826 if (mx.boosted_prio_ > max_prio)
828 max_prio = mx.boosted_prio_;
831 boosted_prio_ = max_prio;
834 owner_->priority_inherited (boosted_prio_);
844#if defined(OS_TRACE_RTOS_MUTEX)
859 recoverable_ =
false;
860 return ENOTRECOVERABLE;
871#if defined(OS_TRACE_RTOS_MUTEX)
880#if defined(OS_TRACE_RTOS_MUTEX)
881 trace::printf (
"%s() ENOTRECOVERABLE @%p %s \n", __func__,
this,
884 return ENOTRECOVERABLE;
891 mutex::internal_mark_owner_dead_ (
void)
955#if defined(OS_TRACE_RTOS_MUTEX)
967 return ENOTRECOVERABLE;
970#if defined(OS_USE_RTOS_PORT_MUTEX)
972 return port::mutex::lock (
this);
983 res = internal_try_lock_ (&crt_thread);
984 if (res != EWOULDBLOCK)
1003 res = internal_try_lock_ (&crt_thread);
1004 if (res != EWOULDBLOCK)
1014 scheduler::internal_link_node (list_, node);
1025 scheduler::internal_unlink_node (node);
1029#if defined(OS_TRACE_RTOS_MUTEX)
1037 return ENOTRECOVERABLE;
1076#if defined(OS_TRACE_RTOS_MUTEX)
1086 return ENOTRECOVERABLE;
1089#if defined(OS_USE_RTOS_PORT_MUTEX)
1091 return port::mutex::try_lock (
this);
1101 return internal_try_lock_ (&crt_thread);
1152#if defined(OS_TRACE_RTOS_MUTEX)
1154 static_cast<unsigned int> (timeout),
this,
name (),
1165 return ENOTRECOVERABLE;
1168#if defined(OS_USE_RTOS_PORT_MUTEX)
1170 return port::mutex::timed_lock (
this, timeout);
1184 res = internal_try_lock_ (&crt_thread);
1185 if (res != EWOULDBLOCK)
1203 { timeout_timestamp, crt_thread };
1211 res = internal_try_lock_ (&crt_thread);
1212 if (res != EWOULDBLOCK)
1223 scheduler::internal_link_node (list_, node, clock_list,
1236 scheduler::internal_unlink_node (node, timeout_node);
1242#if defined(OS_TRACE_RTOS_MUTEX)
1247 else if (clock_->steady_now () >= timeout_timestamp)
1249#if defined(OS_TRACE_RTOS_MUTEX)
1264 for (
auto&& th : list_)
1267 if (prio > max_prio)
1275 boosted_prio_ = max_prio;
1276 owner_->priority (boosted_prio_);
1284 return ENOTRECOVERABLE;
1312#if defined(OS_TRACE_RTOS_MUTEX)
1320#if defined(OS_USE_RTOS_PORT_MUTEX)
1322 return port::mutex::unlock (
this);
1328 return internal_unlock_ (crt_thread);
1347#if defined(OS_TRACE_RTOS_MUTEX)
1354#if defined(OS_USE_RTOS_PORT_MUTEX)
1356 return port::mutex::prio_ceiling (
this);
1360 return prio_ceiling_;
1389#if defined(OS_TRACE_RTOS_MUTEX)
1396#if defined(OS_USE_RTOS_PORT_MUTEX)
1398 return port::mutex::prio_ceiling (
this,
prio_ceiling, old_prio_ceiling);
1409 if (old_prio_ceiling !=
nullptr)
1411 *old_prio_ceiling = prio_ceiling_;
1454#if defined(OS_TRACE_RTOS_MUTEX)
1465#if defined(OS_USE_RTOS_PORT_MUTEX)
1467 return port::mutex::consistent (
this);
1491#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.