37#ifndef _RTEMS_POSIX_MUTEXIMPL_H
38#define _RTEMS_POSIX_MUTEXIMPL_H
58#define POSIX_MUTEX_PROTOCOL_MASK 0x3UL
60#define POSIX_MUTEX_RECURSIVE 0x4UL
62#define POSIX_MUTEX_FLAGS_MASK 0x7UL
64#define POSIX_MUTEX_MAGIC 0x961c13b8UL
66#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
68#define POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS \
69 &_Thread_queue_Operations_priority_inherit
71#define POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS \
72 &_Thread_queue_Operations_priority
80 POSIX_MUTEX_NO_PROTOCOL,
81 POSIX_MUTEX_PRIORITY_INHERIT,
82 POSIX_MUTEX_PRIORITY_CEILING
98 _Thread_queue_Context_initialize( queue_context );
99 _Thread_queue_Context_ISR_disable( queue_context, level );
100 _Thread_queue_Context_set_ISR_level( queue_context, level );
101 executing = _Thread_Executing;
102 _Thread_queue_Queue_acquire_critical(
103 &the_mutex->Recursive.Mutex.Queue.Queue,
104 &executing->Potpourri_stats,
111static inline void _POSIX_Mutex_Release(
116 _Thread_queue_Queue_release(
117 &the_mutex->Recursive.Mutex.Queue.Queue,
129static inline bool _POSIX_Mutex_Is_recursive(
133 return ( flags & POSIX_MUTEX_RECURSIVE ) != 0;
140 return the_mutex->Recursive.Mutex.Queue.Queue.
owner;
143static inline bool _POSIX_Mutex_Is_locked(
147 return _POSIX_Mutex_Get_owner( the_mutex ) != NULL;
154 const struct timespec *abstime,
158static inline void _POSIX_Mutex_Set_owner(
163 the_mutex->Recursive.Mutex.Queue.Queue.
owner = owner;
166static inline bool _POSIX_Mutex_Is_owner(
171 return _POSIX_Mutex_Get_owner( the_mutex ) == the_thread;
180 if ( _POSIX_Mutex_Is_recursive( flags ) ) {
181 ++the_mutex->Recursive.nest_level;
182 return STATUS_SUCCESSFUL;
184 return STATUS_NESTING_NOT_ALLOWED;
193 const struct timespec *abstime,
199 owner = _POSIX_Mutex_Get_owner( the_mutex );
201 if ( owner == NULL ) {
202 _POSIX_Mutex_Set_owner( the_mutex, executing );
203 _Thread_Resource_count_increment( executing );
204 _POSIX_Mutex_Release( the_mutex, queue_context );
205 return STATUS_SUCCESSFUL;
208 if ( owner == executing ) {
211 status = _POSIX_Mutex_Lock_nested( the_mutex, flags );
212 _POSIX_Mutex_Release( the_mutex, queue_context );
216 return _POSIX_Mutex_Seize_slow(
232 unsigned int nest_level;
235 if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) {
236 _POSIX_Mutex_Release( the_mutex, queue_context );
237 return STATUS_NOT_OWNER;
240 nest_level = the_mutex->Recursive.nest_level;
242 if ( nest_level > 0 ) {
243 the_mutex->Recursive.nest_level = nest_level - 1;
244 _POSIX_Mutex_Release( the_mutex, queue_context );
245 return STATUS_SUCCESSFUL;
248 _Thread_Resource_count_decrement( executing );
249 _POSIX_Mutex_Set_owner( the_mutex, NULL );
251 heads = the_mutex->Recursive.Mutex.Queue.Queue.
heads;
253 if ( heads == NULL ) {
254 _POSIX_Mutex_Release( the_mutex, queue_context );
255 return STATUS_SUCCESSFUL;
259 &the_mutex->Recursive.Mutex.Queue.Queue,
265 return STATUS_SUCCESSFUL;
272#if defined(RTEMS_SMP)
273 return the_mutex->scheduler;
279static inline void _POSIX_Mutex_Set_priority(
287 owner = _POSIX_Mutex_Get_owner( the_mutex );
289 if ( owner != NULL ) {
290 _Thread_Wait_acquire( owner, queue_context );
291 _Thread_Priority_change(
293 &the_mutex->Priority_ceiling,
298 _Thread_Wait_release( owner, queue_context );
300 the_mutex->Priority_ceiling.
priority = priority_ceiling;
308 return the_mutex->Priority_ceiling.
priority;
321 _Thread_Wait_acquire_default_critical( owner, &lock_context );
323 scheduler_node = _Thread_Scheduler_get_home_node( owner );
326 _Priority_Get_priority( &scheduler_node->
Wait.Priority )
327 < the_mutex->Priority_ceiling.
priority
329 _Thread_Wait_release_default_critical( owner, &lock_context );
330 _POSIX_Mutex_Release( the_mutex, queue_context );
331 return STATUS_MUTEX_CEILING_VIOLATED;
334 _POSIX_Mutex_Set_owner( the_mutex, owner );
335 _Thread_Resource_count_increment( owner );
338 &the_mutex->Priority_ceiling,
341 _Thread_Wait_release_default_critical( owner, &lock_context );
343 cpu_self = _Thread_queue_Dispatch_disable( queue_context );
344 _POSIX_Mutex_Release( the_mutex, queue_context );
347 return STATUS_SUCCESSFUL;
354 const struct timespec *abstime,
360 owner = _POSIX_Mutex_Get_owner( the_mutex );
362 if ( owner == NULL ) {
363#if defined(RTEMS_SMP)
365 _Thread_Scheduler_get_home( executing )
366 != _POSIX_Mutex_Get_scheduler( the_mutex )
368 _POSIX_Mutex_Release( the_mutex, queue_context );
369 return STATUS_NOT_DEFINED;
373 _Thread_queue_Context_clear_priority_updates( queue_context );
374 return _POSIX_Mutex_Ceiling_set_owner(
381 if ( owner == executing ) {
384 status = _POSIX_Mutex_Lock_nested( the_mutex, flags );
385 _POSIX_Mutex_Release( the_mutex, queue_context );
389 return _POSIX_Mutex_Seize_slow(
391 POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS,
404 unsigned int nest_level;
406 if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) {
407 _POSIX_Mutex_Release( the_mutex, queue_context );
408 return STATUS_NOT_OWNER;
411 nest_level = the_mutex->Recursive.nest_level;
413 if ( nest_level > 0 ) {
414 the_mutex->Recursive.nest_level = nest_level - 1;
415 _POSIX_Mutex_Release( the_mutex, queue_context );
416 return STATUS_SUCCESSFUL;
420 &the_mutex->Recursive.Mutex.Queue.Queue,
422 &the_mutex->Priority_ceiling,
424 POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS
428#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1)
430int _POSIX_Mutex_Lock_support(
431 pthread_mutex_t *
mutex,
432 const struct timespec *abstime,
437 pthread_mutex_t *
mutex
445#define POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags ) \
447 if ( ( the_mutex ) == NULL ) { \
450 flags = ( the_mutex )->flags; \
452 ( ( (uintptr_t) ( the_mutex ) ^ POSIX_MUTEX_MAGIC ) \
453 & ~POSIX_MUTEX_FLAGS_MASK ) \
454 != ( flags & ~POSIX_MUTEX_FLAGS_MASK ) \
456 if ( !_POSIX_Mutex_Auto_initialization( the_mutex ) ) { \
uint32_t ISR_Level
Definition: isrlevel.h:60
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
@ PRIORITY_GROUP_LAST
Priority group last option requests that the priority node is inserted as the last node into its prio...
Definition: priorityimpl.h:73
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
Status_Control
Status codes.
Definition: status.h:111
void _Thread_queue_Surrender(Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations)
Surrenders the thread queue previously owned by the thread to the first enqueued thread.
Definition: threadqenqueue.c:691
void(* Thread_queue_Enqueue_callout)(Thread_queue_Queue *queue, Thread_Control *the_thread, struct Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context)
Thread queue enqueue callout.
Definition: threadq.h:90
Status_Control _Thread_queue_Surrender_priority_ceiling(Thread_queue_Queue *queue, Thread_Control *executing, Priority_Node *ceiling_priority, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations)
Surrenders the thread queue previously owned by the thread to the first enqueued thread.
Definition: threadqenqueue.c:760
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Updates the priority of all threads in the set.
Definition: threadchangepriority.c:396
void _Thread_Priority_add(Thread_Control *the_thread, Priority_Node *priority_node, Thread_queue_Context *queue_context)
Adds the specified thread priority node to the corresponding thread priority aggregation.
Definition: threadchangepriority.c:332
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
POSIX_Mutex_Protocol
Supported POSIX mutex protocols.
Definition: muteximpl.h:79
const pthread_mutexattr_t _POSIX_Mutex_Default_attributes
Definition: mutexinit.c:77
POSIX Threads Private Support.
This header file provides the interfaces of the System Lock Mutex Support.
This header file provides the interfaces of the Per-CPU Information.
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:94
Definition: muteximpl.h:62
Definition: muteximpl.h:51
Per CPU Core Structure.
Definition: percpu.h:384
The priority node to build up a priority aggregation.
Definition: priority.h:112
Priority_Control priority
The priority value of this node.
Definition: priority.h:124
Scheduler node for per-thread data.
Definition: schedulernode.h:94
struct Scheduler_Node::@4406 Wait
Thread wait support block.
Thread queue context for the thread queue methods.
Definition: threadq.h:216
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:221
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:148
The thread queue operations are used to manage the threads of a thread queue.
Definition: threadq.h:554
Thread_queue_Heads * heads
The thread queue heads.
Definition: threadq.h:451
Thread_Control * owner
The thread queue owner.
Definition: threadq.h:456
Scheduler control.
Definition: scheduler.h:337
Thread queue heads.
Definition: threadq.h:385
This header file provides interfaces of the Thread Handler which are only used by the implementation.