RTEMS
coremuteximpl.h
Go to the documentation of this file.
1 
9 /*
10  * COPYRIGHT (c) 1989-2009.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * The license and distribution terms for this file may be
14  * found in the file LICENSE in this distribution or at
15  * http://www.rtems.org/license/LICENSE.
16  */
17 
18 #ifndef _RTEMS_SCORE_COREMUTEXIMPL_H
19 #define _RTEMS_SCORE_COREMUTEXIMPL_H
20 
21 #include <rtems/score/coremutex.h>
22 #include <rtems/score/chainimpl.h>
24 #include <rtems/score/status.h>
25 #include <rtems/score/threadimpl.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
38 #define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
39 
40 #define CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS \
41  &_Thread_queue_Operations_priority_inherit
42 
49  CORE_mutex_Control *the_mutex
50 )
51 {
53 }
54 
61 {
62  _Thread_queue_Destroy( &the_mutex->Wait_queue );
63 }
64 
72  CORE_mutex_Control *the_mutex,
73  Thread_queue_Context *queue_context
74 )
75 {
76  _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, queue_context );
77 }
78 
86  CORE_mutex_Control *the_mutex,
87  Thread_queue_Context *queue_context
88 )
89 {
90  _Thread_queue_Release( &the_mutex->Wait_queue, queue_context );
91 }
92 
101  const CORE_mutex_Control *the_mutex
102 )
103 {
104  return the_mutex->Wait_queue.Queue.owner;
105 }
106 
119  const CORE_mutex_Control *the_mutex
120 )
121 {
122  return _CORE_mutex_Get_owner( the_mutex ) != NULL;
123 }
124 
137 Status_Control _CORE_mutex_Seize_slow(
138  CORE_mutex_Control *the_mutex,
139  const Thread_queue_Operations *operations,
140  Thread_Control *executing,
141  bool wait,
142  Thread_queue_Context *queue_context
143 );
144 
152  CORE_mutex_Control *the_mutex,
153  Thread_Control *owner
154 )
155 {
156  the_mutex->Wait_queue.Queue.owner = owner;
157 }
158 
169  const CORE_mutex_Control *the_mutex,
170  const Thread_Control *the_thread
171 )
172 {
173  return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
174 }
175 
183 )
184 {
185  _CORE_mutex_Initialize( &the_mutex->Mutex );
186  the_mutex->nest_level = 0;
187 }
188 
198 )
199 {
200  ++the_mutex->nest_level;
201  return STATUS_SUCCESSFUL;
202 }
203 
220  CORE_recursive_mutex_Control *the_mutex,
221  const Thread_queue_Operations *operations,
222  Thread_Control *executing,
223  bool wait,
224  Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
225  Thread_queue_Context *queue_context
226 )
227 {
228  Thread_Control *owner;
229 
230  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
231 
232  owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
233 
234  if ( owner == NULL ) {
235  _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
237  _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
238  return STATUS_SUCCESSFUL;
239  }
240 
241  if ( owner == executing ) {
242  Status_Control status;
243 
244  status = ( *nested )( the_mutex );
245  _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
246  return status;
247  }
248 
249  return _CORE_mutex_Seize_slow(
250  &the_mutex->Mutex,
251  operations,
252  executing,
253  wait,
254  queue_context
255  );
256 }
257 
270  CORE_recursive_mutex_Control *the_mutex,
271  const Thread_queue_Operations *operations,
272  Thread_Control *executing,
273  Thread_queue_Context *queue_context
274 )
275 {
276  unsigned int nest_level;
277  Thread_queue_Heads *heads;
278 
279  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
280 
281  if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
282  _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
283  return STATUS_NOT_OWNER;
284  }
285 
286  nest_level = the_mutex->nest_level;
287 
288  if ( nest_level > 0 ) {
289  the_mutex->nest_level = nest_level - 1;
290  _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
291  return STATUS_SUCCESSFUL;
292  }
293 
295  _CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
296 
297  heads = the_mutex->Mutex.Wait_queue.Queue.heads;
298 
299  if ( heads == NULL ) {
300  _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
301  return STATUS_SUCCESSFUL;
302  }
303 
305  &the_mutex->Mutex.Wait_queue.Queue,
306  heads,
307  executing,
308  queue_context,
309  operations
310  );
311  return STATUS_SUCCESSFUL;
312 }
313 
323  CORE_ceiling_mutex_Control *the_mutex,
324  const Scheduler_Control *scheduler,
325  Priority_Control priority_ceiling
326 )
327 {
329  _Priority_Node_initialize( &the_mutex->Priority_ceiling, priority_ceiling );
330 #if defined(RTEMS_SMP)
331  the_mutex->scheduler = scheduler;
332 #endif
333 }
334 
344  const CORE_ceiling_mutex_Control *the_mutex
345 )
346 {
347 #if defined(RTEMS_SMP)
348  return the_mutex->scheduler;
349 #else
350  return &_Scheduler_Table[ 0 ];
351 #endif
352 }
353 
362  CORE_ceiling_mutex_Control *the_mutex,
363  Priority_Control priority_ceiling,
364  Thread_queue_Context *queue_context
365 )
366 {
367  Thread_Control *owner;
368 
369  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
370 
371  if ( owner != NULL ) {
372  _Thread_Wait_acquire( owner, queue_context );
374  owner,
375  &the_mutex->Priority_ceiling,
376  priority_ceiling,
377  false,
378  queue_context
379  );
380  _Thread_Wait_release( owner, queue_context );
381  } else {
382  the_mutex->Priority_ceiling.priority = priority_ceiling;
383  }
384 }
385 
394  const CORE_ceiling_mutex_Control *the_mutex
395 )
396 {
397  return the_mutex->Priority_ceiling.priority;
398 }
399 
412  CORE_ceiling_mutex_Control *the_mutex,
413  Thread_Control *owner,
414  Thread_queue_Context *queue_context
415 )
416 {
417  ISR_lock_Context lock_context;
418  Scheduler_Node *scheduler_node;
419  Per_CPU_Control *cpu_self;
420 
421  _Thread_Wait_acquire_default_critical( owner, &lock_context );
422 
423  scheduler_node = _Thread_Scheduler_get_home_node( owner );
424 
425  if (
426  _Priority_Get_priority( &scheduler_node->Wait.Priority )
427  < the_mutex->Priority_ceiling.priority
428  ) {
429  _Thread_Wait_release_default_critical( owner, &lock_context );
430  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
431  return STATUS_MUTEX_CEILING_VIOLATED;
432  }
433 
434  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
437  owner,
438  &the_mutex->Priority_ceiling,
439  queue_context
440  );
441  _Thread_Wait_release_default_critical( owner, &lock_context );
442 
443  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
444  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
445  _Thread_Priority_update( queue_context );
446  _Thread_Dispatch_enable( cpu_self );
447  return STATUS_SUCCESSFUL;
448 }
449 
466  CORE_ceiling_mutex_Control *the_mutex,
467  Thread_Control *executing,
468  bool wait,
469  Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
470  Thread_queue_Context *queue_context
471 )
472 {
473  Thread_Control *owner;
474 
475  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
476 
477  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
478 
479  if ( owner == NULL ) {
480 #if defined(RTEMS_SMP)
481  if (
482  _Thread_Scheduler_get_home( executing )
483  != _CORE_ceiling_mutex_Get_scheduler( the_mutex )
484  ) {
485  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
486  return STATUS_NOT_DEFINED;
487  }
488 #endif
489 
492  the_mutex,
493  executing,
494  queue_context
495  );
496  }
497 
498  if ( owner == executing ) {
499  Status_Control status;
500 
501  status = ( *nested )( &the_mutex->Recursive );
502  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
503  return status;
504  }
505 
506  return _CORE_mutex_Seize_slow(
507  &the_mutex->Recursive.Mutex,
508  CORE_MUTEX_TQ_OPERATIONS,
509  executing,
510  wait,
511  queue_context
512  );
513 }
514 
526  CORE_ceiling_mutex_Control *the_mutex,
527  Thread_Control *executing,
528  Thread_queue_Context *queue_context
529 )
530 {
531  unsigned int nest_level;
532  ISR_lock_Context lock_context;
533  Per_CPU_Control *cpu_self;
534  Thread_Control *new_owner;
535 
536  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
537 
538  if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
539  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
540  return STATUS_NOT_OWNER;
541  }
542 
543  nest_level = the_mutex->Recursive.nest_level;
544 
545  if ( nest_level > 0 ) {
546  the_mutex->Recursive.nest_level = nest_level - 1;
547  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
548  return STATUS_SUCCESSFUL;
549  }
550 
552 
554  _Thread_Wait_acquire_default_critical( executing, &lock_context );
556  executing,
557  &the_mutex->Priority_ceiling,
558  queue_context
559  );
560  _Thread_Wait_release_default_critical( executing, &lock_context );
561 
562  new_owner = _Thread_queue_First_locked(
563  &the_mutex->Recursive.Mutex.Wait_queue,
564  CORE_MUTEX_TQ_OPERATIONS
565  );
566  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
567 
569  &queue_context->Lock_context.Lock_context
570  );
571 
572  if ( new_owner != NULL ) {
573 #if defined(RTEMS_MULTIPROCESSING)
574  if ( _Objects_Is_local_id( new_owner->Object.id ) )
575 #endif
576  {
579  new_owner,
580  &the_mutex->Priority_ceiling,
581  queue_context
582  );
583  }
584 
586  &the_mutex->Recursive.Mutex.Wait_queue.Queue,
587  CORE_MUTEX_TQ_OPERATIONS,
588  new_owner,
589  queue_context
590  );
591  } else {
592  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
593  }
594 
595  _Thread_Priority_update( queue_context );
596  _Thread_Dispatch_enable( cpu_self );
597  return STATUS_SUCCESSFUL;
598 }
599 
602 #ifdef __cplusplus
603 }
604 #endif
605 
606 #endif
607 /* end of include file */
static __inline__ void _Thread_queue_Acquire_critical(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Acquires the thread queue control in a critical section.
Definition: threadqimpl.h:681
Priority_Node Priority_ceiling
The priority ceiling node for the mutex owner.
Definition: coremutex.h:92
Thread_Control * owner
The thread queue owner.
Definition: threadq.h:431
static __inline__ Thread_Control * _Thread_queue_First_locked(Thread_queue_Control *the_thread_queue, const Thread_queue_Operations *operations)
Returns the first thread on the thread queue if it exists, otherwise NULL.
Definition: threadqimpl.h:1173
static __inline__ bool _Objects_Is_local_id(Objects_Id id RTEMS_UNUSED)
Checks if the id is of a local object.
Definition: objectimpl.h:587
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:70
Thread_queue_Control Wait_queue
The thread queue of this mutex.
Definition: coremutex.h:62
static __inline__ void _CORE_ceiling_mutex_Set_priority(CORE_ceiling_mutex_Control *the_mutex, Priority_Control priority_ceiling, Thread_queue_Context *queue_context)
Sets the priority of the ceiling mutex.
static __inline__ Per_CPU_Control * _Thread_queue_Dispatch_disable(Thread_queue_Context *queue_context)
Disables dispatching in a critical section.
Definition: threadqimpl.h:429
Thread queue context for the thread queue methods.
Definition: threadq.h:198
unsigned int nest_level
The nest level in case of a recursive seize.
Definition: coremutex.h:77
static __inline__ const Scheduler_Control * _Thread_Scheduler_get_home(const Thread_Control *the_thread)
Gets the home scheduler of the thread.
Definition: threadimpl.h:1419
static __inline__ bool _CORE_mutex_Is_locked(const CORE_mutex_Control *the_mutex)
Checks if the mutex is locked.
static __inline__ void _CORE_mutex_Set_owner(CORE_mutex_Control *the_mutex, Thread_Control *owner)
Sets the owner of the mutex.
static __inline__ void _Thread_Resource_count_increment(Thread_Control *the_thread)
Increments the thread&#39;s resource count.
Definition: threadimpl.h:1339
CORE_recursive_mutex_Control Recursive
The plain recursive mutex.
Definition: coremutex.h:87
Inlined Routines Associated with the Manipulation of the Scheduler.
static __inline__ Status_Control _CORE_recursive_mutex_Seize_nested(CORE_recursive_mutex_Control *the_mutex)
Seizes the recursive mutex nested.
Priority_Control priority
The priority value of this node.
Definition: priority.h:110
const struct _Scheduler_Control * scheduler
The scheduler instance for this priority ceiling mutex.
Definition: coremutex.h:98
static __inline__ const Scheduler_Control * _CORE_ceiling_mutex_Get_scheduler(const CORE_ceiling_mutex_Control *the_mutex)
Gets the scheduler of the ceiling mutex.
static __inline__ Status_Control _CORE_ceiling_mutex_Seize(CORE_ceiling_mutex_Control *the_mutex, Thread_Control *executing, bool wait, Status_Control(*nested)(CORE_recursive_mutex_Control *), Thread_queue_Context *queue_context)
Seizes the ceiling mutex.
static __inline__ Status_Control _CORE_ceiling_mutex_Set_owner(CORE_ceiling_mutex_Control *the_mutex, Thread_Control *owner, Thread_queue_Context *queue_context)
Sets the owner of the ceiling mutex.
static __inline__ void _Thread_Resource_count_decrement(Thread_Control *the_thread)
Decrements the thread&#39;s resource count.
Definition: threadimpl.h:1355
void _Thread_queue_Object_initialize(Thread_queue_Control *the_thread_queue)
Initializes a thread queue embedded in an object with identifier.
Definition: threadq.c:148
Thread queue operations.
Definition: threadq.h:517
Thread_queue_Queue Queue
The actual thread queue.
Definition: threadq.h:583
Thread_queue_Heads * heads
The thread queue heads.
Definition: threadq.h:426
Thread queue heads.
Definition: threadq.h:360
static __inline__ Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
static __inline__ Status_Control _CORE_ceiling_mutex_Surrender(CORE_ceiling_mutex_Control *the_mutex, Thread_Control *executing, Thread_queue_Context *queue_context)
Surrenders the ceiling mutex.
Per CPU Core Structure.
Definition: percpu.h:347
static __inline__ Scheduler_Node * _Thread_Scheduler_get_home_node(const Thread_Control *the_thread)
Gets the scheduler&#39;s home node.
Definition: threadimpl.h:1438
static __inline__ void _Thread_Wait_acquire(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Acquires the thread wait default lock and disables interrupts.
Definition: threadimpl.h:1868
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:203
Objects_Control Object
Definition: thread.h:727
CORE_mutex_Control Mutex
The plain non-recursive mutex.
Definition: coremutex.h:72
static __inline__ Thread_Control * _CORE_mutex_Get_owner(const CORE_mutex_Control *the_mutex)
Gets the owner of the mutex.
Constants and Structures Associated with the Manipulation of Objects.
static __inline__ Priority_Control _CORE_ceiling_mutex_Get_priority(const CORE_ceiling_mutex_Control *the_mutex)
Gets the priority of the ceiling mutex.
static __inline__ void _CORE_ceiling_mutex_Initialize(CORE_ceiling_mutex_Control *the_mutex, const Scheduler_Control *scheduler, Priority_Control priority_ceiling)
initializes a ceiling mutex.
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.
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Updates the priority of all threads in the set.
static __inline__ Status_Control _CORE_recursive_mutex_Seize(CORE_recursive_mutex_Control *the_mutex, const Thread_queue_Operations *operations, Thread_Control *executing, bool wait, Status_Control(*nested)(CORE_recursive_mutex_Control *), Thread_queue_Context *queue_context)
Seizes the recursive mutex.
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
static __inline__ void _Thread_queue_Context_clear_priority_updates(Thread_queue_Context *queue_context)
Clears the priority update count of the thread queue context.
Definition: threadqimpl.h:338
Chain Handler API.
The recursive mutex control.
Definition: coremutex.h:68
struct Scheduler_Node::@20 Wait
Thread wait support block.
static __inline__ void _CORE_mutex_Release(CORE_mutex_Control *the_mutex, Thread_queue_Context *queue_context)
Releases the mutex.
Definition: coremuteximpl.h:85
Control block used to manage each mutex.
Definition: coremutex.h:56
Scheduler control.
Definition: scheduler.h:264
Scheduler node for per-thread data.
Definition: schedulernode.h:79
Inlined Routines from the Thread Handler.
static __inline__ void _CORE_mutex_Acquire_critical(CORE_mutex_Control *the_mutex, Thread_queue_Context *queue_context)
Acquires the mutex critical.
Definition: coremuteximpl.h:71
static __inline__ Priority_Control _Priority_Get_priority(const Priority_Aggregation *aggregation)
Gets the priority aggregation&#39;s priority.
Definition: priorityimpl.h:270
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...
static __inline__ void _Thread_Wait_acquire_default_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the thread wait default lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1658
static __inline__ void _CORE_mutex_Initialize(CORE_mutex_Control *the_mutex)
Initializes the mutex.
Definition: coremuteximpl.h:48
The recursive mutex control with priority ceiling protocol support.
Definition: coremutex.h:83
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
static __inline__ void _Thread_Wait_release(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Releases the thread wait lock and restores the previous interrupt status.
Definition: threadimpl.h:1929
static __inline__ bool _CORE_mutex_Is_owner(const CORE_mutex_Control *the_mutex, const Thread_Control *the_thread)
Checks if the the thread is the owner of the mutex.
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:130
static __inline__ void _Thread_queue_Destroy(Thread_queue_Control *the_thread_queue)
Destroys the thread queue.
Definition: threadqimpl.h:1378
#define RTEMS_INLINE_ROUTINE
Gives a hint to the compiler in a function declaration to inline this function.
Definition: basedefs.h:683
static __inline__ void _Thread_Wait_release_default_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the thread wait default lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1718
void _Thread_queue_Release(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Releases the thread queue control and enables interrupts.
Definition: threadq.c:118
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.
static __inline__ void _CORE_mutex_Destroy(CORE_mutex_Control *the_mutex)
Destroys the mutex.
Definition: coremuteximpl.h:60
static __inline__ void _Thread_Priority_change(Thread_Control *the_thread, Priority_Node *priority_node, Priority_Control new_priority, bool prepend_it, Thread_queue_Context *queue_context)
Changes the thread priority value of the specified thread priority node in the corresponding thread p...
Definition: threadimpl.h:722
void _Thread_queue_Extract_critical(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Extracts the thread from the thread queue and unblocks it.
CORE Mutex API.
static __inline__ void _CORE_recursive_mutex_Initialize(CORE_recursive_mutex_Control *the_mutex)
Initializes a recursive mutex.
static __inline__ void _Priority_Node_initialize(Priority_Node *node, Priority_Control priority)
Initializes the priority node to the given priority.
Definition: priorityimpl.h:156
Status_Control _CORE_mutex_Seize_slow(CORE_mutex_Control *the_mutex, const Thread_queue_Operations *operations, Thread_Control *executing, bool wait, Thread_queue_Context *queue_context)
Seize the mutex slowly.
static __inline__ Status_Control _CORE_recursive_mutex_Surrender(CORE_recursive_mutex_Control *the_mutex, const Thread_queue_Operations *operations, Thread_Control *executing, Thread_queue_Context *queue_context)
Surrenders the recursive mutex.
Objects_Id id
Definition: objectdata.h:43