RTEMS CPU Kit with SuperCore  4.11.2
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>
23 #include <rtems/score/sysstate.h>
24 #include <rtems/score/threadimpl.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
45  );
46 
52 typedef enum {
60 #if defined(RTEMS_POSIX_API)
61 
64  CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED,
65 #endif
66 
79 
80 #if defined(__RTEMS_STRICT_ORDER_MUTEX__)
81 
84  CORE_MUTEX_RELEASE_NOT_ORDER,
85 #endif
86 
91 
93 
99 #define CORE_MUTEX_STATUS_LAST CORE_MUTEX_STATUS_CEILING_VIOLATED
100 
115 CORE_mutex_Status _CORE_mutex_Initialize(
116  CORE_mutex_Control *the_mutex,
117  Thread_Control *executing,
118  const CORE_mutex_Attributes *the_mutex_attributes,
119  bool initially_locked
120 );
121 
122 RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
123 {
124  _Thread_queue_Destroy( &the_mutex->Wait_queue );
125 }
126 
149  CORE_mutex_Control *the_mutex,
150  Thread_Control *executing,
151  ISR_lock_Context *lock_context
152 );
153 
154 #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
155 
168  CORE_mutex_Control *the_mutex,
169  Thread_Control *executing,
170  ISR_lock_Context *lock_context
171  );
172 #else
173 
181  #define _CORE_mutex_Seize_interrupt_trylock( _mutex, _executing, _lock_context ) \
182  _CORE_mutex_Seize_interrupt_trylock_body( _mutex, _executing, _lock_context )
183 #endif
184 
198  CORE_mutex_Control *the_mutex,
199  Thread_Control *executing,
200  Watchdog_Interval timeout,
201  ISR_lock_Context *lock_context
202 );
203 
213 #define _CORE_mutex_Check_dispatch_for_seize(_wait) \
214  (!_Thread_Dispatch_is_enabled() \
215  && (_wait) \
216  && (_System_state_Get() >= SYSTEM_STATE_UP))
217 
246  CORE_mutex_Control *the_mutex,
247  Thread_Control *executing,
248  Objects_Id id,
249  bool wait,
250  Watchdog_Interval timeout,
251  ISR_lock_Context *lock_context
252 )
253 {
254  if ( _CORE_mutex_Check_dispatch_for_seize( wait ) ) {
255  _Terminate(
257  false,
258  INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE
259  );
260  }
261  _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, lock_context );
262  if ( _CORE_mutex_Seize_interrupt_trylock( the_mutex, executing, lock_context ) ) {
263  if ( !wait ) {
264  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
265  executing->Wait.return_code =
267  } else {
268  executing->Wait.id = id;
270  the_mutex,
271  executing,
272  timeout,
273  lock_context
274  );
275  }
276  }
277 }
278 
290 #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__)
291  void _CORE_mutex_Seize(
292  CORE_mutex_Control *_the_mutex,
293  Thread_Control *_executing,
294  Objects_Id _id,
295  bool _wait,
296  Watchdog_Interval _timeout,
297  ISR_lock_Context *_lock_context
298  );
299 #else
300  #define _CORE_mutex_Seize( \
301  _the_mutex, _executing, _id, _wait, _timeout, _lock_context ) \
302  _CORE_mutex_Seize_body( \
303  _the_mutex, _executing, _id, _wait, _timeout, _lock_context )
304 #endif
305 
321 CORE_mutex_Status _CORE_mutex_Surrender(
322  CORE_mutex_Control *the_mutex,
323  Objects_Id id,
324  CORE_mutex_API_mp_support_callout api_mutex_mp_support,
325  ISR_lock_Context *lock_context
326 );
327 
340 void _CORE_mutex_Flush(
341  CORE_mutex_Control *the_mutex,
342  Thread_queue_Flush_callout remote_extract_callout,
343  uint32_t status
344 );
345 
358  const CORE_mutex_Control *the_mutex
359 )
360 {
361  return the_mutex->holder != NULL;
362 }
363 
376  const CORE_mutex_Attributes *the_attribute
377 )
378 {
379  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
380 }
381 
395  CORE_mutex_Attributes *the_attribute
396 )
397 {
398  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
399 }
400 
413  CORE_mutex_Attributes *the_attribute
414 )
415 {
416  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
417 }
418 
431  CORE_mutex_Attributes *the_attribute
432 )
433 {
434  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
435 }
436 
437 /*
438  * Seize Mutex with Quick Success Path
439  *
440  * NOTE: There is no MACRO version of this routine. A body is in
441  * coremutexseize.c that is duplicated from the .inl by hand.
442  *
443  * NOTE: The Doxygen for this routine is in the .h file.
444  */
445 
447  CORE_mutex_Control *the_mutex,
448  Thread_Control *executing,
449  ISR_lock_Context *lock_context
450 )
451 {
452  /* disabled when you get here */
453 
455  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
456  the_mutex->holder = executing;
457  the_mutex->nest_count = 1;
458  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
460 
461 #ifdef __RTEMS_STRICT_ORDER_MUTEX__
462  _Chain_Prepend_unprotected( &executing->lock_mutex,
463  &the_mutex->queue.lock_queue );
464  the_mutex->queue.priority_before = executing->current_priority;
465 #endif
466 
467  executing->resource_count++;
468  }
469 
470  if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
471  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
472  return 0;
473  } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
474  *
475  * we possibly bump the priority of the current holder -- which
476  * happens to be _Thread_Executing.
477  */
478  {
479  Priority_Control ceiling;
480  Priority_Control current;
481 
482  ceiling = the_mutex->Attributes.priority_ceiling;
483  current = executing->current_priority;
484  if ( current == ceiling ) {
485  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
486  return 0;
487  }
488 
489  if ( current > ceiling ) {
490  Per_CPU_Control *cpu_self;
491 
492  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
493  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
494  _Thread_Raise_priority( executing, ceiling );
495  _Thread_Dispatch_enable( cpu_self );
496  return 0;
497  }
498  /* if ( current < ceiling ) */ {
500  the_mutex->holder = NULL;
501  the_mutex->nest_count = 0; /* undo locking above */
502  executing->resource_count--; /* undo locking above */
503  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
504  return 0;
505  }
506  }
507  return 0;
508  }
509 
510  /*
511  * At this point, we know the mutex was not available. If this thread
512  * is the thread that has locked the mutex, let's see if we are allowed
513  * to nest access.
514  */
515  if ( _Thread_Is_executing( the_mutex->holder ) ) {
516  switch ( the_mutex->Attributes.lock_nesting_behavior ) {
518  the_mutex->nest_count++;
519  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
520  return 0;
521  #if defined(RTEMS_POSIX_API)
522  case CORE_MUTEX_NESTING_IS_ERROR:
523  executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
524  _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
525  return 0;
526  #endif
528  break;
529  }
530  }
531 
532  /*
533  * The mutex is not available and the caller must deal with the possibility
534  * of blocking.
535  */
536  return 1;
537 }
538 
541 #ifdef __cplusplus
542 }
543 #endif
544 
545 #endif
546 /* end of include file */
CORE_mutex_Nesting_behaviors lock_nesting_behavior
This field determines what the behavior of this mutex instance will be when attempting to acquire the...
Definition: coremutex.h:109
RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(CORE_mutex_Control *the_mutex, Thread_Control *executing, Objects_Id id, bool wait, Watchdog_Interval timeout, ISR_lock_Context *lock_context)
Attempt to obtain the mutex.
Definition: coremuteximpl.h:245
This status indicates that the operation completed successfully.
Definition: coremuteximpl.h:54
Priority_Control current_priority
This field is the current priority state of this thread.
Definition: thread.h:683
Thread_queue_Control Wait_queue
This field is the Waiting Queue used to manage the set of tasks which are blocked waiting to lock the...
Definition: coremutex.h:153
void(* CORE_mutex_API_mp_support_callout)(Thread_Control *, Objects_Id)
Callout which provides to support global/multiprocessor operations.
Definition: coremuteximpl.h:42
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(CORE_mutex_Attributes *the_attribute)
Doex core mutex use priority blocking.
Definition: coremuteximpl.h:394
Errors of the core system.
Definition: interr.h:51
#define RTEMS_INLINE_ROUTINE
The following (in conjunction with compiler arguments) are used to choose between the use of static i...
Definition: basedefs.h:135
This specifies that threads will wait for the mutex in priority order.
Definition: coremutex.h:53
RTEMS_INLINE_ROUTINE void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
Definition: threaddispatch.h:304
RTEMS_INLINE_ROUTINE bool _Thread_Is_executing(const Thread_Control *the_thread)
This function returns true if the_thread is the currently executing thread, and false otherwise...
Definition: threadimpl.h:517
void _Terminate(Internal_errors_Source the_source, bool is_internal, Internal_errors_t the_error)
Initiates system termination.
Definition: interr.c:31
Priority_Control priority_ceiling
This field contains the ceiling priority to be used if that protocol is selected. ...
Definition: coremutex.h:121
This specifies that threads will wait for the mutex in FIFO order.
Definition: coremutex.h:51
uint32_t return_code
This field will contain the return status from a blocking operation.
Definition: thread.h:317
#define _CORE_mutex_Seize_interrupt_trylock(_mutex, _executing, _lock_context)
The default is to favor speed and inlining this definitely saves a few instructions.
Definition: coremuteximpl.h:181
uint32_t nest_count
This element contains the number of times the mutex has been acquired nested.
Definition: coremutex.h:161
RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(CORE_mutex_Control *the_mutex, Thread_Control *executing, ISR_lock_Context *lock_context)
Attempt to receive a unit from the_mutex.
Definition: coremuteximpl.h:446
void _Thread_Raise_priority(Thread_Control *the_thread, Priority_Control new_priority)
Raises the priority of a thread.
Definition: threadchangepriority.c:99
CORE_mutex_Status _CORE_mutex_Surrender(CORE_mutex_Control *the_mutex, Objects_Id id, CORE_mutex_API_mp_support_callout api_mutex_mp_support, ISR_lock_Context *lock_context)
Frees a unit to the mutex.
Definition: coremutexsurrender.c:88
This specifies that threads will wait for the mutex in priority order.
Definition: coremutex.h:61
uint32_t Priority_Control
The following type defines the control block used to manage thread priorities.
Definition: priority.h:56
CORE_mutex_Status
The possible Mutex handler return statuses.
Definition: coremuteximpl.h:52
This structure defines the Thread Control Block (TCB).
Definition: thread.h:671
Per CPU Core Structure.
Definition: percpu.h:233
This status indicates that a thread of logically greater importance than the ceiling priority attempt...
Definition: coremuteximpl.h:90
This status indicates that the thread was blocked waiting for an operation to complete and the mutex ...
Definition: coremuteximpl.h:73
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(CORE_mutex_Attributes *the_attribute)
Does mutex use priority ceiling.
Definition: coremuteximpl.h:430
uint32_t resource_count
This field is the number of mutexes currently held by this thread.
Definition: thread.h:713
Objects_Id id
This field is the Id of the object this thread is waiting upon.
Definition: thread.h:302
Constants and Structures Associated with the Manipulation of Objects.
#define _CORE_mutex_Check_dispatch_for_seize(_wait)
Verifies that a mutex blocking seize is performed safely.
Definition: coremuteximpl.h:213
CORE_mutex_Status _CORE_mutex_Initialize(CORE_mutex_Control *the_mutex, Thread_Control *executing, const CORE_mutex_Attributes *the_mutex_attributes, bool initially_locked)
Initializes the mutex based on the parameters passed.
Definition: coremutex.c:26
Chain Handler API.
void _CORE_mutex_Seize_interrupt_blocking(CORE_mutex_Control *the_mutex, Thread_Control *executing, Watchdog_Interval timeout, ISR_lock_Context *lock_context)
Performs the blocking portion of a mutex obtain.
Definition: coremutexseize.c:48
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(CORE_mutex_Attributes *the_attribute)
Does mutex use priority inheritance.
Definition: coremuteximpl.h:412
This status indicates that the calling task did not want to block and the operation was unable to com...
Definition: coremuteximpl.h:59
This status indicates that the calling task was willing to block but the operation was unable to comp...
Definition: coremuteximpl.h:78
This specifies that threads will wait for the mutex in priority order.
Definition: coremutex.h:57
uint32_t Watchdog_Interval
Type is used to specify the length of intervals.
Definition: watchdog.h:47
Control block used to manage each mutex.
Definition: coremutex.h:149
System State Handler API.
This sequence performs as indicated:
Definition: coremutex.h:96
This sequence has no blocking or errors:
Definition: coremutex.h:79
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(const CORE_mutex_Attributes *the_attribute)
Does core mutex use FIFO blocking.
Definition: coremuteximpl.h:375
This status indicates that an attempt was made to release a mutex by a thread other than the thread w...
Definition: coremuteximpl.h:69
Inlined Routines from the Thread Handler.
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(const CORE_mutex_Control *the_mutex)
Is mutex locked.
Definition: coremuteximpl.h:357
RTEMS_INLINE_ROUTINE Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
Definition: threaddispatch.h:251
Thread_Control * holder
This element points to the thread which is currently holding this mutex.
Definition: coremutex.h:166
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
The control block used to manage attributes of each mutex.
Definition: coremutex.h:105
CORE_mutex_Attributes Attributes
This element is the set of attributes which define this instance&#39;s behavior.
Definition: coremutex.h:157
#define _CORE_mutex_Seize(_the_mutex, _executing, _id, _wait, _timeout, _lock_context)
This method is used to obtain a core mutex.
Definition: coremuteximpl.h:300
uint32_t Objects_Id
The following type defines the control block used to manage object IDs.
Definition: object.h:122
CORE Mutex API.
CORE_mutex_Disciplines discipline
This field indicates whether threads waiting on the mutex block in FIFO or priority order...
Definition: coremutex.h:117
Thread_Wait_information Wait
This field is the blocking information for this thread.
Definition: thread.h:715
RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Prepend a node (unprotected).
Definition: chainimpl.h:787
void(* Thread_queue_Flush_callout)(Thread_Control *)
The following type defines the callout used when a remote task is extracted from a local thread queue...
Definition: threadqimpl.h:65
void _CORE_mutex_Flush(CORE_mutex_Control *the_mutex, Thread_queue_Flush_callout remote_extract_callout, uint32_t status)
Flush all waiting threads.
Definition: coremutexflush.c:26