Changeset 0b713f89 in rtems


Ignore:
Timestamp:
May 30, 2016, 4:59:55 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
3692095
Parents:
33e250c9
git-author:
Sebastian Huber <sebastian.huber@…> (05/30/16 04:59:55)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/30/16 14:16:23)
Message:

score: Rework CORE inherit priority mutex

Provide dedicated seize and surrender methods for inherit priority
mutexes. This eliminates CORE_mutex_Attributes.

Location:
cpukit
Files:
1 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/monitor/mon-sema.c

    r33e250c9 r0b713f89  
    99#include <rtems.h>
    1010#include "monitor.h"
    11 #include <rtems/rtems/attrimpl.h>
     11#include <rtems/rtems/semimpl.h>
    1212#include <stdio.h>
    1313#include <string.h>    /* memcpy() */
     
    2020{
    2121    const Semaphore_Control *rtems_sema = (const Semaphore_Control *) sema_void;
     22    Thread_Control *owner;
    2223
    23     canonical_sema->attribute = rtems_sema->attribute_set;
    24     canonical_sema->priority_ceiling =
    25       rtems_sema->Core_control.Mutex.priority_ceiling;
     24    memset(canonical_sema, 0, sizeof(*canonical_sema));
    2625
    27     canonical_sema->holder_id = 0;
     26#if defined(RTEMS_MULTIPROCESSING)
     27    if (rtems_sema->is_global) {
     28      canonical_sema->attribute |= RTEMS_GLOBAL;
     29    }
     30#endif
    2831
    29     if (_Attributes_Is_counting_semaphore(canonical_sema->attribute)) {
    30       /* we have a counting semaphore */
    31       canonical_sema->cur_count  = rtems_sema->Core_control.semaphore.count;
    32       canonical_sema->max_count  = UINT32_MAX;
     32    if (rtems_sema->discipline == SEMAPHORE_DISCIPLINE_PRIORITY) {
     33      canonical_sema->attribute |= RTEMS_PRIORITY;
    3334    }
    34     else {
    35       /* we have a binary semaphore (mutex) */
    36       Thread_Control *holder;
    3735
    38       holder = rtems_sema->Core_control.Mutex.Recursive.Mutex.holder;
    39       if (holder != NULL) {
    40         canonical_sema->holder_id = holder->Object.id;
    41         canonical_sema->cur_count = 0;
    42       } else {
    43         canonical_sema->cur_count = 1;
    44       }
     36    switch ( rtems_sema->variant ) {
     37      case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
     38        canonical_sema->attribute |= RTEMS_BINARY_SEMAPHORE
     39          | RTEMS_INHERIT_PRIORITY;
     40        break;
     41      case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     42        canonical_sema->attribute |= RTEMS_BINARY_SEMAPHORE
     43          | RTEMS_PRIORITY_CEILING;
     44        break;
     45      case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     46        canonical_sema->attribute |= RTEMS_BINARY_SEMAPHORE;
     47        break;
     48#if defined(RTEMS_SMP)
     49      case SEMAPHORE_VARIANT_MRSP:
     50        canonical_sema->attribute |= RTEMS_BINARY_SEMAPHORE
     51          | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
     52        break;
     53#endif
     54      case SEMAPHORE_VARIANT_SIMPLE_BINARY:
     55        canonical_sema->attribute |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
     56        break;
     57      case SEMAPHORE_VARIANT_COUNTING:
     58        canonical_sema->attribute |= RTEMS_COUNTING_SEMAPHORE;
     59        break;
     60    }
    4561
    46       canonical_sema->max_count = 1; /* mutex is either 0 or 1 */
     62    switch ( rtems_sema->variant ) {
     63      case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     64        canonical_sema->priority_ceiling =
     65          rtems_sema->Core_control.Mutex.priority_ceiling;
     66        /* Fall through */
     67      case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
     68      case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     69        owner = _CORE_mutex_Get_owner(
     70          &rtems_sema->Core_control.Mutex.Recursive.Mutex
     71        );
     72
     73        if (owner != NULL) {
     74          canonical_sema->holder_id = owner->Object.id;
     75          canonical_sema->cur_count = 0;
     76        } else {
     77          canonical_sema->cur_count = 1;
     78        }
     79
     80        canonical_sema->max_count = 1;
     81        break;
     82#if defined(RTEMS_SMP)
     83      case SEMAPHORE_VARIANT_MRSP:
     84        canonical_sema->cur_count =
     85          rtems_sema->Core_control.mrsp.Resource.owner == NULL;
     86        canonical_sema->max_count = 1;
     87        break;
     88#endif
     89      case SEMAPHORE_VARIANT_SIMPLE_BINARY:
     90        canonical_sema->cur_count = rtems_sema->Core_control.semaphore.count;
     91        canonical_sema->max_count = 1;
     92        break;
     93      case SEMAPHORE_VARIANT_COUNTING:
     94        canonical_sema->cur_count = rtems_sema->Core_control.semaphore.count;
     95        canonical_sema->max_count = UINT32_MAX;
     96        break;
    4797    }
    4898}
  • cpukit/libnetworking/rtems/rtems_glue.c

    r33e250c9 r0b713f89  
    119119        nest_count =
    120120                the_networkSemaphore ?
    121                 the_networkSemaphore->Core_control.Mutex.Recursive.Mutex.nest_count : 0;
     121                the_networkSemaphore->Core_control.Mutex.Recursive.nest_level + 1 : 0;
    122122        for (i = 0; i < nest_count; ++i) {
    123123                rtems_bsdnet_semaphore_release();
     
    378378        _Thread_queue_Context_initialize(&queue_context);
    379379        _ISR_lock_ISR_disable(&queue_context.Lock_context);
    380         status = _CORE_mutex_Seize (
    381                 &the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
     380        status = _CORE_recursive_mutex_Seize (
     381                &the_networkSemaphore->Core_control.Mutex.Recursive,
    382382                _Thread_Executing,
    383                 1,              /* wait */
    384                 0,              /* forever */
     383                true,                   /* wait */
     384                WATCHDOG_NO_TIMEOUT,    /* forever */
     385                _CORE_recursive_mutex_Seize_nested,
    385386                &queue_context
    386                 );
     387        );
    387388        if (status != STATUS_SUCCESSFUL)
    388389                rtems_panic ("rtems-net: can't obtain network sema: %d\n", status);
     
    411412        _Thread_queue_Context_initialize(&queue_context);
    412413        _ISR_lock_ISR_disable(&queue_context.Lock_context);
    413         status = _CORE_mutex_Surrender (
    414                 &the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
     414        status = _CORE_recursive_mutex_Surrender(
     415                &the_networkSemaphore->Core_control.Mutex.Recursive,
     416                _Thread_Executing,
    415417                &queue_context
    416                 );
     418        );
    417419        if (status != STATUS_SUCCESSFUL)
    418420                rtems_panic ("rtems-net: can't release network sema: %i\n");
  • cpukit/posix/src/mutexinit.c

    r33e250c9 r0b713f89  
    120120  the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
    121121
    122   if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
    123     _CORE_ceiling_mutex_Initialize(
    124       &the_mutex->Mutex,
    125       _POSIX_Priority_To_core( the_attr->prio_ceiling )
    126     );
    127   } else if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
    128     _CORE_recursive_mutex_Initialize(
    129       &the_mutex->Mutex.Recursive
    130     );
    131   } else {
    132     CORE_mutex_Attributes the_mutex_attr;
    133 
    134     if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE ) {
    135       the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    136     } else {
    137       the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
    138     }
    139 
    140     /*
    141      *  Must be initialized to unlocked.
    142      */
    143     _CORE_mutex_Initialize(
    144       &the_mutex->Mutex.Recursive.Mutex,
    145       NULL,
    146       &the_mutex_attr,
    147       false
    148     );
     122  switch ( the_mutex->protocol ) {
     123    case POSIX_MUTEX_PRIORITY_CEILING:
     124      _CORE_ceiling_mutex_Initialize(
     125        &the_mutex->Mutex,
     126        _POSIX_Priority_To_core( the_attr->prio_ceiling )
     127      );
     128      break;
     129    default:
     130      _Assert(
     131        the_mutex->protocol == POSIX_MUTEX_NO_PROTOCOL
     132          || the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT
     133      );
     134      _CORE_recursive_mutex_Initialize(
     135        &the_mutex->Mutex.Recursive
     136      );
     137      break;
    149138  }
    150139
  • cpukit/posix/src/mutexlocksupp.c

    r33e250c9 r0b713f89  
    8989    default:
    9090      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
    91       status = _CORE_mutex_Seize(
    92         &the_mutex->Mutex.Recursive.Mutex,
     91      status = _CORE_recursive_mutex_Seize(
     92        &the_mutex->Mutex.Recursive,
    9393        executing,
    9494        wait,
    9595        timeout,
     96        _POSIX_Mutex_Lock_nested,
    9697        &queue_context
    9798      );
  • cpukit/posix/src/mutexunlock.c

    r33e250c9 r0b713f89  
    6363    default:
    6464      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
    65       status = _CORE_mutex_Surrender(
    66         &the_mutex->Mutex.Recursive.Mutex,
     65      status = _CORE_recursive_mutex_Surrender(
     66        &the_mutex->Mutex.Recursive,
     67        executing,
    6768        &queue_context
    6869      );
  • cpukit/rtems/include/rtems/rtems/sem.h

    r33e250c9 r0b713f89  
    114114  unsigned int is_global : 1;
    115115#endif
    116 
    117   /**
    118    *  This is the Classic API attribute provided to the create directive.
    119    *  It is translated into behavioral attributes on the SuperCore Semaphore
    120    *  or Mutex instance.
    121    */
    122   rtems_attribute          attribute_set;
    123116}   Semaphore_Control;
    124117
  • cpukit/rtems/include/rtems/rtems/semimpl.h

    r33e250c9 r0b713f89  
    3333 */
    3434typedef enum {
    35   SEMAPHORE_VARIANT_MUTEX,
     35  SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY,
    3636  SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING,
    3737  SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
  • cpukit/rtems/src/semcreate.c

    r33e250c9 r0b713f89  
    6262)
    6363{
    64   Semaphore_Control     *the_semaphore;
    65   CORE_mutex_Attributes  the_mutex_attr;
    66   Thread_Control        *executing;
    67   Status_Control         status;
     64  Semaphore_Control *the_semaphore;
     65  Thread_Control    *executing;
     66  Status_Control     status;
    6867
    6968  if ( !rtems_is_name_valid( name ) )
     
    138137
    139138  priority_ceiling = _RTEMS_tasks_Priority_to_Core( priority_ceiling );
    140   the_semaphore->attribute_set = attribute_set;
    141139  executing = _Thread_Get_executing();
    142140
     
    196194      status = STATUS_SUCCESSFUL;
    197195    }
    198   } else if ( !_Attributes_Is_inherit_priority( attribute_set ) ) {
     196  } else {
    199197    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
    200     the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
     198
     199    if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
     200      the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY;
     201    } else {
     202      the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
     203    }
     204
    201205    _CORE_recursive_mutex_Initialize(
    202206      &the_semaphore->Core_control.Mutex.Recursive
     
    208212        executing
    209213      );
     214
     215      if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
     216        ++executing->resource_count;
     217      }
    210218    }
    211219
    212220    status = STATUS_SUCCESSFUL;
    213   } else {
    214     _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
    215     _Assert( _Attributes_Is_inherit_priority( attribute_set ) );
    216     the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
    217 
    218     the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
    219 
    220     status = _CORE_mutex_Initialize(
    221       &the_semaphore->Core_control.Mutex.Recursive.Mutex,
    222       executing,
    223       &the_mutex_attr,
    224       count != 1
    225     );
    226221  }
    227222
  • cpukit/rtems/src/semdelete.c

    r33e250c9 r0b713f89  
    5151
    5252  switch ( the_semaphore->variant ) {
    53     case SEMAPHORE_VARIANT_MUTEX:
     53    case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
    5454    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
    5555    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
     
    9898    default:
    9999      _Assert(
    100         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     100        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
    101101          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
    102102          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
  • cpukit/rtems/src/semflush.c

    r33e250c9 r0b713f89  
    5858    default:
    5959      _Assert(
    60         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     60        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
    6161          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
    6262          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
  • cpukit/rtems/src/semobtain.c

    r33e250c9 r0b713f89  
    8282      break;
    8383#endif
    84     case SEMAPHORE_VARIANT_MUTEX:
    85       status = _CORE_mutex_Seize(
    86         &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     84    case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
     85      status = _CORE_recursive_mutex_Seize(
     86        &the_semaphore->Core_control.Mutex.Recursive,
    8787        executing,
    8888        wait,
    8989        timeout,
     90        _CORE_recursive_mutex_Seize_nested,
    9091        &queue_context
    9192      );
  • cpukit/rtems/src/semrelease.c

    r33e250c9 r0b713f89  
    5959      break;
    6060#endif
    61     case SEMAPHORE_VARIANT_MUTEX:
    62       status = _CORE_mutex_Surrender(
    63         &the_semaphore->Core_control.Mutex.Recursive.Mutex,
     61    case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
     62      status = _CORE_recursive_mutex_Surrender(
     63        &the_semaphore->Core_control.Mutex.Recursive,
     64        executing,
    6465        &queue_context
    6566      );
  • cpukit/rtems/src/semsetpriority.c

    r33e250c9 r0b713f89  
    7676    default:
    7777      _Assert(
    78         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
     78        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
    7979          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
    8080          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
  • cpukit/score/Makefile.am

    r33e250c9 r0b713f89  
    182182
    183183## CORE_MUTEX_C_FILES
    184 libscore_a_SOURCES += src/coremutex.c \
    185     src/coremutexseize.c src/coremutexsurrender.c
     184libscore_a_SOURCES += src/coremutexseize.c
     185libscore_a_SOURCES += src/coremutexsurrender.c
    186186
    187187## CORE_PERCPU_C_FILES
  • cpukit/score/include/rtems/score/apimutex.h

    r33e250c9 r0b713f89  
    4747   * Contains the SuperCore mutex information.
    4848   */
    49   CORE_mutex_Control Mutex;
     49  CORE_recursive_mutex_Control Mutex;
    5050
    5151  /**
  • cpukit/score/include/rtems/score/coremutex.h

    r33e250c9 r0b713f89  
    4343
    4444/**
    45  *  @brief The possible behaviors for lock nesting.
    46  *
    47  *  This enumerated type defines the possible behaviors for
    48  *  lock nesting.
    49  */
    50 typedef enum {
    51   /**
    52    *    This sequence has no blocking or errors:
    53    *
    54    *         + lock(m)
    55    *         + lock(m)
    56    *         + unlock(m)
    57    *         + unlock(m)
    58    */
    59   CORE_MUTEX_NESTING_ACQUIRES,
    60 #if defined(RTEMS_POSIX_API)
    61   /**
    62    *    This sequence returns an error at the indicated point:
    63    *
    64    *        + lock(m)
    65    *        + lock(m)   - already locked error
    66    *        + unlock(m)
    67    */
    68   CORE_MUTEX_NESTING_IS_ERROR,
    69 #endif
    70 }  CORE_mutex_Nesting_behaviors;
    71 
    72 /**
    73  *  @brief The control block used to manage attributes of each mutex.
    74  *
    75  *  The following defines the control block used to manage the
    76  *  attributes of each mutex.
    77  */
    78 typedef struct {
    79   /** This field determines what the behavior of this mutex instance will
    80    *  be when attempting to acquire the mutex when it is already locked.
    81    */
    82   CORE_mutex_Nesting_behaviors lock_nesting_behavior;
    83 }   CORE_mutex_Attributes;
    84 
    85 /**
    8645 *  @brief Control block used to manage each mutex.
    8746 *
     
    9453  Thread_queue_Control    Wait_queue;
    9554
    96   /** This element is the set of attributes which define this instance's
    97    *  behavior.
    98    */
    99   CORE_mutex_Attributes   Attributes;
    100   /** This element contains the number of times the mutex has been acquired
    101    *  nested.  This must be zero (0) before the mutex is actually unlocked.
    102    */
    103   uint32_t                nest_count;
    10455  /** This element points to the thread which is currently holding this mutex.
    10556   *  The holder is the last thread to successfully lock the mutex and which
  • cpukit/score/include/rtems/score/coremuteximpl.h

    r33e250c9 r0b713f89  
    3636#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
    3737
    38 /**
    39  *  @brief Initializes the mutex based on the parameters passed.
    40  *
    41  *  This routine initializes the mutex based on the parameters passed.
    42  *
    43  *  @param[in,out] the_mutex is the mutex to initalize
    44  *  @param[in,out] executing The currently executing thread.
    45  *  @param[in] the_mutex_attributes is the attributes associated with this
    46  *         mutex instance
    47  *  @param[in] initially_locked If true, then the mutex is initially locked by
    48  *  the executing thread.
    49  *
    50  *  @retval This method returns STATUS_SUCCESSFUL if successful.
    51  */
    52 Status_Control _CORE_mutex_Initialize(
    53   CORE_mutex_Control           *the_mutex,
    54   Thread_Control               *executing,
    55   const CORE_mutex_Attributes  *the_mutex_attributes,
    56   bool                          initially_locked
    57 );
     38RTEMS_INLINE_ROUTINE void _CORE_mutex_Initialize(
     39  CORE_mutex_Control *the_mutex
     40)
     41{
     42  _Thread_queue_Initialize( &the_mutex->Wait_queue );
     43  the_mutex->holder = NULL;
     44}
    5845
    5946RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
     
    8370  );
    8471}
    85 
    86 /**
    87  *  @brief Performs the blocking portion of a mutex obtain.
    88  *
    89  *  This routine performs the blocking portion of a mutex obtain.
    90  *  It is an actual subroutine and is not implemented as something
    91  *  that may be inlined.
    92  *
    93  *  @param[in,out] the_mutex is the mutex to attempt to lock
    94  *  @param[in,out] executing The currently executing thread.
    95  *  @param[in] timeout is the maximum number of ticks to block
    96  *  @param[in] lock_context is the interrupt level
    97  */
    98 Status_Control _CORE_mutex_Seize_interrupt_blocking(
    99   CORE_mutex_Control   *the_mutex,
    100   Thread_Control       *executing,
    101   Watchdog_Interval     timeout,
    102   Thread_queue_Context *queue_context
    103 );
    10472
    10573RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
     
    12896}
    12997
    130 /**
    131  *  @brief Attempt to receive a unit from the_mutex.
    132  *
    133  *  This routine attempts to receive a unit from the_mutex.
    134  *  If a unit is available or if the wait flag is false, then the routine
    135  *  returns.  Otherwise, the calling task is blocked until a unit becomes
    136  *  available.
    137  *
    138  *  @param[in,out] executing The currently executing thread.
    139  *  @param[in,out] the_mutex is the mutex to attempt to lock
    140  *  @param[in] queue_context is the interrupt level
    141  *
    142  *  @retval STATUS_UNAVAILABLE The mutex is already locked.
    143  *  @retval other Otherwise.
    144  */
    145 RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize_interrupt_trylock(
     98Status_Control _CORE_mutex_Seize_slow(
    14699  CORE_mutex_Control   *the_mutex,
    147100  Thread_Control       *executing,
    148   Thread_queue_Context *queue_context
    149 )
    150 {
    151   /* disabled when you get here */
    152 
    153   if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
    154     the_mutex->holder     = executing;
    155     the_mutex->nest_count = 1;
    156     ++executing->resource_count;
    157 
    158     _CORE_mutex_Release( the_mutex, queue_context );
    159     return STATUS_SUCCESSFUL;
    160   }
    161 
    162   /*
    163    *  At this point, we know the mutex was not available.  If this thread
    164    *  is the thread that has locked the mutex, let's see if we are allowed
    165    *  to nest access.
    166    */
    167   if ( _Thread_Is_executing( the_mutex->holder ) ) {
    168     switch ( the_mutex->Attributes.lock_nesting_behavior ) {
    169       case CORE_MUTEX_NESTING_ACQUIRES:
    170         the_mutex->nest_count++;
    171         _CORE_mutex_Release( the_mutex, queue_context );
    172         return STATUS_SUCCESSFUL;
    173       #if defined(RTEMS_POSIX_API)
    174         case CORE_MUTEX_NESTING_IS_ERROR:
    175           _CORE_mutex_Release( the_mutex, queue_context );
    176           return STATUS_NESTING_NOT_ALLOWED;
    177       #endif
    178     }
    179   }
    180 
    181   /*
    182    *  The mutex is not available and the caller must deal with the possibility
    183    *  of blocking.
    184    */
    185   return STATUS_UNAVAILABLE;
    186 }
    187 
    188 /**
    189  *  @brief Attempt to obtain the mutex.
    190  *
    191  *  This routine attempts to obtain the mutex.  If the mutex is available,
    192  *  then it will return immediately.  Otherwise, it will invoke the
    193  *  support routine @a _Core_mutex_Seize_interrupt_blocking.
    194  *
    195  *  @param[in] the_mutex is the mutex to attempt to lock
    196  *  @param[in] wait is true if the thread is willing to wait
    197  *  @param[in] timeout is the maximum number of ticks to block
    198  *  @param[in] queue_context is a temporary variable used to contain the ISR
    199  *         disable level cookie
    200  *
    201  *  @note If the mutex is called from an interrupt service routine,
    202  *        with context switching disabled, or before multitasking,
    203  *        then a fatal error is generated.
    204  *
    205  *  The logic on this routine is as follows:
    206  *
    207  *  * If incorrect system state
    208  *      return an error
    209  *  * If mutex is available without any contention or blocking
    210  *      obtain it with interrupts disabled and returned
    211  *  * If the caller is willing to wait
    212  *      then they are blocked.
    213  */
    214 RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize(
    215   CORE_mutex_Control   *the_mutex,
    216   Thread_Control       *executing,
     101  Thread_Control       *owner,
    217102  bool                  wait,
    218103  Watchdog_Interval     timeout,
    219104  Thread_queue_Context *queue_context
    220 )
    221 {
    222   Status_Control status;
    223 
    224   _CORE_mutex_Acquire_critical( the_mutex, queue_context );
    225 
    226   status = _CORE_mutex_Seize_interrupt_trylock(
    227     the_mutex,
    228     executing,
    229     queue_context
    230   );
    231 
    232   if ( status != STATUS_UNAVAILABLE ) {
    233     return status;
    234   }
    235 
    236   if ( !wait ) {
    237     _CORE_mutex_Release( the_mutex, queue_context );
    238     return status;
    239   }
    240 
    241   return _CORE_mutex_Seize_interrupt_blocking(
    242     the_mutex,
    243     executing,
    244     timeout,
    245     queue_context
    246   );
    247 }
     105);
    248106
    249107Status_Control _CORE_mutex_Seize_no_protocol_slow(
     
    256114);
    257115
    258 Status_Control _CORE_mutex_Surrender(
     116Status_Control _CORE_mutex_Surrender_slow(
    259117  CORE_mutex_Control   *the_mutex,
     118  Thread_Control       *executing,
     119  Thread_queue_Heads   *heads,
     120  bool                  keep_priority,
    260121  Thread_queue_Context *queue_context
    261122);
     
    307168)
    308169{
    309   _Thread_queue_Initialize( &the_mutex->Mutex.Wait_queue );
    310   the_mutex->Mutex.holder = NULL;
     170  _CORE_mutex_Initialize( &the_mutex->Mutex );
    311171  the_mutex->nest_level = 0;
    312172}
     
    318178  ++the_mutex->nest_level;
    319179  return STATUS_SUCCESSFUL;
     180}
     181
     182RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize(
     183  CORE_recursive_mutex_Control  *the_mutex,
     184  Thread_Control                *executing,
     185  bool                           wait,
     186  Watchdog_Interval              timeout,
     187  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
     188  Thread_queue_Context          *queue_context
     189)
     190{
     191  Thread_Control *owner;
     192
     193  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
     194
     195  owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
     196
     197  if ( owner == NULL ) {
     198    _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
     199    ++executing->resource_count;
     200    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     201    return STATUS_SUCCESSFUL;
     202  }
     203
     204  if ( owner == executing ) {
     205    Status_Control status;
     206
     207    status = ( *nested )( the_mutex );
     208    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     209    return status;
     210  }
     211
     212  return _CORE_mutex_Seize_slow(
     213    &the_mutex->Mutex,
     214    executing,
     215    owner,
     216    wait,
     217    timeout,
     218    queue_context
     219  );
     220}
     221
     222RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
     223  CORE_recursive_mutex_Control *the_mutex,
     224  Thread_Control               *executing,
     225  Thread_queue_Context         *queue_context
     226)
     227{
     228  unsigned int        nest_level;
     229  Thread_queue_Heads *heads;
     230  bool                keep_priority;
     231
     232  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
     233
     234  if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
     235    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     236    return STATUS_NOT_OWNER;
     237  }
     238
     239  nest_level = the_mutex->nest_level;
     240
     241  if ( nest_level > 0 ) {
     242    the_mutex->nest_level = nest_level - 1;
     243    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     244    return STATUS_SUCCESSFUL;
     245  }
     246
     247  --executing->resource_count;
     248  _CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
     249
     250  /*
     251   * Ensure that the owner resource count is visible to all other
     252   * processors and that we read the latest priority restore
     253   * hint.
     254   */
     255  _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
     256
     257  heads = the_mutex->Mutex.Wait_queue.Queue.heads;
     258  keep_priority = _Thread_Owns_resources( executing )
     259    || !executing->priority_restore_hint;
     260
     261  if ( heads == NULL && keep_priority ) {
     262    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
     263    return STATUS_SUCCESSFUL;
     264  }
     265
     266  return _CORE_mutex_Surrender_slow(
     267    &the_mutex->Mutex,
     268    executing,
     269    heads,
     270    keep_priority,
     271    queue_context
     272  );
    320273}
    321274
  • cpukit/score/src/apimutex.c

    r33e250c9 r0b713f89  
    4848  API_Mutex_Control *mutex;
    4949
    50   CORE_mutex_Attributes attr =  {
    51     CORE_MUTEX_NESTING_ACQUIRES
    52   };
    53 
    5450  mutex = (API_Mutex_Control *)
    5551    _Objects_Allocate_unprotected( &_API_Mutex_Information );
     
    5753  _Assert( mutex != NULL );
    5854
    59   _CORE_mutex_Initialize( &mutex->Mutex, NULL, &attr, false );
     55  _CORE_recursive_mutex_Initialize( &mutex->Mutex );
    6056
    6157  _Objects_Open_u32( &_API_Mutex_Information, &mutex->Object, 1 );
  • cpukit/score/src/apimutexisowner.c

    r33e250c9 r0b713f89  
    1919
    2020#include <rtems/score/apimutex.h>
     21#include <rtems/score/coremuteximpl.h>
    2122#include <rtems/score/threadimpl.h>
    2223
    2324bool _API_Mutex_Is_owner( const API_Mutex_Control *the_mutex )
    2425{
    25   return the_mutex->Mutex.holder == _Thread_Get_executing();
     26  return _CORE_mutex_Is_owner(
     27    &the_mutex->Mutex.Mutex,
     28    _Thread_Get_executing()
     29  );
    2630}
  • cpukit/score/src/apimutexlock.c

    r33e250c9 r0b713f89  
    3535  _ISR_lock_ISR_disable( &queue_context.Lock_context );
    3636
    37   _CORE_mutex_Seize(
     37  _CORE_recursive_mutex_Seize(
    3838    &the_mutex->Mutex,
    3939    _Thread_Executing,
    4040    true,
    41     0,
     41    WATCHDOG_NO_TIMEOUT,
     42    _CORE_recursive_mutex_Seize_nested,
    4243    &queue_context
    4344  );
    4445
    45   if ( the_mutex->Mutex.nest_count == 1 ) {
     46  if ( the_mutex->Mutex.nest_level == 0 ) {
    4647    the_mutex->previous_thread_life_state = previous_thread_life_state;
    4748  }
  • cpukit/score/src/apimutexunlock.c

    r33e250c9 r0b713f89  
    3030
    3131  previous_thread_life_state = the_mutex->previous_thread_life_state;
    32   restore_thread_life_protection = the_mutex->Mutex.nest_count == 1;
     32  restore_thread_life_protection = the_mutex->Mutex.nest_level == 0;
    3333
    3434  _Thread_queue_Context_initialize( &queue_context );
    3535  _ISR_lock_ISR_disable( &queue_context.Lock_context );
    36   _CORE_mutex_Surrender( &the_mutex->Mutex, &queue_context );
     36  _CORE_recursive_mutex_Surrender(
     37    &the_mutex->Mutex,
     38    _Thread_Executing,
     39    &queue_context
     40  );
    3741
    3842  if ( restore_thread_life_protection ) {
  • cpukit/score/src/coremutexseize.c

    r33e250c9 r0b713f89  
    2323#include <rtems/score/thread.h>
    2424
    25 Status_Control _CORE_mutex_Seize_interrupt_blocking(
     25Status_Control _CORE_mutex_Seize_slow(
    2626  CORE_mutex_Control   *the_mutex,
    2727  Thread_Control       *executing,
     28  Thread_Control       *owner,
     29  bool                  wait,
    2830  Watchdog_Interval     timeout,
    2931  Thread_queue_Context *queue_context
    3032)
    3133{
    32   Thread_Control *holder;
     34  if ( !wait ) {
     35    _CORE_mutex_Release( the_mutex, queue_context );
     36    return STATUS_UNAVAILABLE;
     37  }
    3338
    3439#if !defined(RTEMS_SMP)
     
    3843   */
    3944  _Thread_Dispatch_disable();
    40 #endif
    4145
    42   holder = the_mutex->holder;
    43 
    44 #if !defined(RTEMS_SMP)
    4546  /*
    4647   * To enable interrupts here works only since exactly one executing thread
     
    4849   * the priority inheritance protocol.  On SMP configurations more than one
    4950   * executing thread may exist, so here we must not release the lock, since
    50    * otherwise the current holder may be no longer the holder of the mutex
     51   * otherwise the current owner may be no longer the owner of the mutex
    5152   * once we released the lock.
    5253   */
     
    5455#endif
    5556
    56   _Thread_Inherit_priority( holder, executing );
     57  _Thread_Inherit_priority( owner, executing );
    5758
    5859#if defined(RTEMS_SMP)
  • cpukit/score/src/coremutexsurrender.c

    r33e250c9 r0b713f89  
    1919#endif
    2020
    21 #include <rtems/system.h>
    22 #include <rtems/score/isr.h>
    2321#include <rtems/score/coremuteximpl.h>
    24 #include <rtems/score/thread.h>
    2522
    26 Status_Control _CORE_mutex_Surrender(
     23Status_Control _CORE_mutex_Surrender_slow(
    2724  CORE_mutex_Control   *the_mutex,
     25  Thread_Control       *executing,
     26  Thread_queue_Heads   *heads,
     27  bool                  keep_priority,
    2828  Thread_queue_Context *queue_context
    2929)
    3030{
    31   Thread_Control *the_thread;
    32   Thread_Control *holder;
     31  if ( heads != NULL ) {
     32    const Thread_queue_Operations *operations;
     33    Thread_Control                *new_owner;
     34    bool                           unblock;
    3335
    34   holder = the_mutex->holder;
     36    operations = CORE_MUTEX_TQ_OPERATIONS;
     37    new_owner = ( *operations->first )( heads );
    3538
    36   /*
    37    *  Priority Ceiling or Priority Inheritance mutexes must be released by the
    38    *  thread which acquired them.
    39    */
    40   if ( !_Thread_Is_executing( holder ) ) {
    41     _ISR_lock_ISR_enable( &queue_context->Lock_context );
    42     return STATUS_NOT_OWNER;
    43   }
     39    _CORE_mutex_Set_owner( the_mutex, new_owner );
    4440
    45   _CORE_mutex_Acquire_critical( the_mutex, queue_context );
    46 
    47   /* XXX already unlocked -- not right status */
    48 
    49   if ( !the_mutex->nest_count ) {
    50     _CORE_mutex_Release( the_mutex, queue_context );
    51     return STATUS_SUCCESSFUL;
    52   }
    53 
    54   the_mutex->nest_count--;
    55 
    56   if ( the_mutex->nest_count != 0 ) {
    57     /*
    58      *  All error checking is on the locking side, so if the lock was
    59      *  allowed to acquired multiple times, then we should just deal with
    60      *  that.  The RTEMS_DEBUG is just a validation.
    61      */
    62     #if defined(RTEMS_DEBUG)
    63       switch ( the_mutex->Attributes.lock_nesting_behavior ) {
    64         case CORE_MUTEX_NESTING_ACQUIRES:
    65           _CORE_mutex_Release( the_mutex, queue_context );
    66           return STATUS_SUCCESSFUL;
    67         #if defined(RTEMS_POSIX_API)
    68           case CORE_MUTEX_NESTING_IS_ERROR:
    69             /* should never occur */
    70             _CORE_mutex_Release( the_mutex, queue_context );
    71             return STATUS_NESTING_NOT_ALLOWED;
    72         #endif
    73       }
    74     #else
    75       _CORE_mutex_Release( the_mutex, queue_context );
    76       /* must be CORE_MUTEX_NESTING_ACQUIRES or we wouldn't be here */
    77       return STATUS_SUCCESSFUL;
    78     #endif
    79   }
    80 
    81   /*
    82    *  Formally release the mutex before possibly transferring it to a
    83    *  blocked thread.
    84    */
    85    holder->resource_count--;
    86   the_mutex->holder = NULL;
    87 
    88   /*
    89    *  Now we check if another thread was waiting for this mutex.  If so,
    90    *  transfer the mutex to that thread.
    91    */
    92   if (
    93     ( the_thread = _Thread_queue_First_locked(
    94         &the_mutex->Wait_queue,
    95         CORE_MUTEX_TQ_OPERATIONS
    96       )
    97     )
    98   ) {
    99     bool unblock;
    100 
    101     the_mutex->holder     = the_thread;
    102     the_mutex->nest_count = 1;
    103 
    104     /*
    105      * We must extract the thread now since this will restore its default
    106      * thread lock.  This is necessary to avoid a deadlock in the
    107      * _Thread_Change_priority() below due to a recursive thread queue lock
    108      * acquire.
    109      */
    11041    unblock = _Thread_queue_Extract_locked(
    11142      &the_mutex->Wait_queue.Queue,
    112       CORE_MUTEX_TQ_OPERATIONS,
    113       the_thread,
     43      operations,
     44      new_owner,
    11445      queue_context
    11546    );
    11647
    11748#if defined(RTEMS_MULTIPROCESSING)
    118     if ( _Objects_Is_local_id( the_thread->Object.id ) )
     49    if ( _Objects_Is_local_id( new_owner->Object.id ) )
    11950#endif
    12051    {
    121       the_thread->resource_count++;
    122       _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
     52      ++new_owner->resource_count;
     53      _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, new_owner );
    12354    }
    12455
     
    12657      unblock,
    12758      &the_mutex->Wait_queue.Queue,
    128       the_thread,
     59      new_owner,
    12960      &queue_context->Lock_context
    13061    );
     
    13364  }
    13465
    135   /*
    136    *  Whether or not someone is waiting for the mutex, an
    137    *  inherited priority must be lowered if this is the last
    138    *  mutex (i.e. resource) this task has.
    139    */
    140   if ( !_Thread_Owns_resources( holder ) ) {
    141     /*
    142      * Ensure that the holder resource count is visible to all other processors
    143      * and that we read the latest priority restore hint.
    144      */
    145     _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
     66  if ( !keep_priority ) {
     67    Per_CPU_Control *cpu_self;
    14668
    147     if ( holder->priority_restore_hint ) {
    148       Per_CPU_Control *cpu_self;
    149 
    150       cpu_self = _Thread_Dispatch_disable();
    151       _Thread_Restore_priority( holder );
    152       _Thread_Dispatch_enable( cpu_self );
    153     }
     69    cpu_self = _Thread_Dispatch_disable();
     70    _Thread_Restore_priority( executing );
     71    _Thread_Dispatch_enable( cpu_self );
    15472  }
    15573
    156   _CORE_mutex_Restore_priority( holder );
    15774  return STATUS_SUCCESSFUL;
    15875}
  • cpukit/score/src/debugisownerofallocator.c

    r33e250c9 r0b713f89  
    2828
    2929    if ( mutex != NULL ) {
    30       owner = mutex->Mutex.holder == _Thread_Get_executing();
     30      owner = _API_Mutex_Is_owner( mutex );
    3131    } else {
    3232      owner = false;
Note: See TracChangeset for help on using the changeset viewer.