37#ifndef _RTEMS_SCORE_MRSPIMPL_H
38#define _RTEMS_SCORE_MRSPIMPL_H
59#define MRSP_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit
67static inline void _MRSP_Acquire_critical(
72 _Thread_queue_Acquire_critical( &mrsp->Wait_queue, queue_context );
81static inline void _MRSP_Release(
86 _Thread_queue_Release( &mrsp->Wait_queue, queue_context );
97 const MRSP_Control *mrsp
100 return mrsp->Wait_queue.Queue.owner;
109static inline void _MRSP_Set_owner(
114 mrsp->Wait_queue.Queue.owner = owner;
126 const MRSP_Control *mrsp,
130 uint32_t scheduler_index;
132 scheduler_index = _Scheduler_Get_index( scheduler );
134 return mrsp->ceiling_priorities[ scheduler_index ];
144static inline void _MRSP_Set_priority(
150 uint32_t scheduler_index;
152 scheduler_index = _Scheduler_Get_index( scheduler );
154 mrsp->ceiling_priorities[ scheduler_index ] = new_priority;
183 _Thread_queue_Context_clear_priority_updates( queue_context );
184 _Thread_Wait_acquire_default_critical( thread, &lock_context );
186 scheduler = _Thread_Scheduler_get_home( thread );
187 scheduler_node = _Thread_Scheduler_get_home_node( thread );
188 ceiling_priority = _MRSP_Get_priority( mrsp, scheduler );
192 <= _Priority_Get_priority( &scheduler_node->
Wait.Priority )
194 _Priority_Node_initialize( priority_node, ceiling_priority );
196 status = STATUS_SUCCESSFUL;
198 status = STATUS_MUTEX_CEILING_VIOLATED;
201 _Thread_Wait_release_default_critical( thread, &lock_context );
212static inline void _MRSP_Remove_priority(
220 _Thread_queue_Context_clear_priority_updates( queue_context );
221 _Thread_Wait_acquire_default_critical( thread, &lock_context );
223 _Thread_Wait_release_default_critical( thread, &lock_context );
234static inline void _MRSP_Replace_priority(
242 _Thread_Wait_acquire_default( thread, &lock_context );
243 _Thread_Priority_replace(
246 &mrsp->Ceiling_priority
248 _Thread_Wait_release_default( thread, &lock_context );
271 status = _MRSP_Raise_priority(
274 &mrsp->Ceiling_priority,
278 if ( status != STATUS_SUCCESSFUL ) {
279 _MRSP_Release( mrsp, queue_context );
283 _MRSP_Set_owner( mrsp, executing );
284 cpu_self = _Thread_queue_Dispatch_disable( queue_context );
285 _MRSP_Release( mrsp, queue_context );
286 _Thread_Priority_update_and_make_sticky( executing );
288 return STATUS_SUCCESSFUL;
310 bool initially_locked
315 size_t scheduler_count;
321 for ( i = 0 ; i < scheduler_count ; ++i ) {
326 if ( scheduler != scheduler_of_index ) {
327 mrsp->ceiling_priorities[ i ] =
328 _Scheduler_Map_priority( scheduler_of_index, 0 );
330 mrsp->ceiling_priorities[ i ] = ceiling_priority;
336 if ( !initially_locked ) {
337 return STATUS_SUCCESSFUL;
340 _Thread_queue_Context_initialize( &queue_context );
341 _Thread_queue_Context_ISR_disable( &queue_context, level );
342 _Thread_queue_Context_set_ISR_level( &queue_context, level );
343 _MRSP_Acquire_critical( mrsp, &queue_context );
344 status = _MRSP_Claim_ownership( mrsp, executing, &queue_context );
346 if ( status != STATUS_SUCCESSFUL ) {
347 _Thread_queue_Destroy( &mrsp->Wait_queue );
375 status = _MRSP_Raise_priority(
382 if ( status != STATUS_SUCCESSFUL ) {
383 _MRSP_Release( mrsp, queue_context );
387 _Thread_queue_Context_set_deadlock_callout(
391 status = _Thread_queue_Enqueue_sticky(
392 &mrsp->Wait_queue.Queue,
398 if ( status == STATUS_SUCCESSFUL ) {
399 _MRSP_Replace_priority( mrsp, executing, &ceiling_priority );
404 _MRSP_Remove_priority( executing, &ceiling_priority, queue_context );
405 cpu_self = _Thread_Dispatch_disable_critical(
410 if ( status != STATUS_DEADLOCK ) {
411 _Thread_Priority_update_and_clean_sticky( executing );
413 _Thread_Priority_update_ignore_sticky( executing );
454 _MRSP_Acquire_critical( mrsp, queue_context );
456 owner = _MRSP_Get_owner( mrsp );
458 if ( owner == NULL ) {
459 status = _MRSP_Claim_ownership( mrsp, executing, queue_context );
460 }
else if ( owner == executing ) {
461 _MRSP_Release( mrsp, queue_context );
462 status = STATUS_DEADLOCK;
464 status = _MRSP_Wait_for_ownership( mrsp, executing, queue_context );
466 _MRSP_Release( mrsp, queue_context );
467 status = STATUS_UNAVAILABLE;
491 if ( _MRSP_Get_owner( mrsp ) != executing ) {
493 return STATUS_NOT_OWNER;
496 _MRSP_Acquire_critical( mrsp, queue_context );
498 _MRSP_Set_owner( mrsp, NULL );
499 _MRSP_Remove_priority( executing, &mrsp->Ceiling_priority, queue_context );
501 heads = mrsp->Wait_queue.Queue.heads;
503 if ( heads == NULL ) {
506 cpu_self = _Thread_Dispatch_disable_critical(
509 _MRSP_Release( mrsp, queue_context );
510 _Thread_Priority_update_and_clean_sticky( executing );
512 return STATUS_SUCCESSFUL;
515 _Thread_queue_Surrender_sticky(
516 &mrsp->Wait_queue.Queue,
522 return STATUS_SUCCESSFUL;
535static inline Status_Control _MRSP_Can_destroy( MRSP_Control *mrsp )
537 if ( _MRSP_Get_owner( mrsp ) != NULL ) {
538 return STATUS_RESOURCE_IN_USE;
541 return STATUS_SUCCESSFUL;
550static inline void _MRSP_Destroy(
555 _MRSP_Release( mrsp, queue_context );
556 _Thread_queue_Destroy( &mrsp->Wait_queue );
This header file provides the interfaces of the Assert Handler.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Definition: isrlock.h:385
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Definition: isrlock.h:364
uint32_t ISR_Level
Definition: isrlevel.h:60
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
#define _Scheduler_Count
This constant contains the count of configured schedulers.
Definition: scheduler.h:395
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
Status_Control
Status codes.
Definition: status.h:111
void _Thread_queue_Deadlock_status(Thread_Control *the_thread)
Sets the thread wait return code to STATUS_DEADLOCK.
Definition: threadqenqueue.c:396
void _Thread_queue_Object_initialize(Thread_queue_Control *the_thread_queue)
Initializes a thread queue embedded in an object with identifier.
Definition: threadq.c:170
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_Priority_remove(Thread_Control *the_thread, Priority_Node *priority_node, Thread_queue_Context *queue_context)
Removes the specified thread priority node from the corresponding thread priority aggregation.
Definition: threadchangepriority.c:347
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
This header file provides interfaces of the Multiprocessor Resource Sharing Protocol (MrsP) which are...
This header file provides the interfaces of the Operation Status Support.
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:94
Per CPU Core Structure.
Definition: percpu.h:384
The priority node to build up a priority aggregation.
Definition: priority.h:112
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
Scheduler control.
Definition: scheduler.h:337
Thread queue heads.
Definition: threadq.h:385
This header file provides interfaces of the Thread Queue Handler which are only used by the implement...
This header file provides interfaces of the Watchdog Handler which are only used by the implementatio...