Changeset 6c2b8a4b in rtems


Ignore:
Timestamp:
Nov 29, 2017, 5:23:27 AM (23 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
fd5471b
Parents:
3d7d2a37
git-author:
Sebastian Huber <sebastian.huber@…> (11/29/17 05:23:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/04/17 09:53:39)
Message:

score: Use self-contained API mutex

Use a self-contained recursive mutex for API_Mutex_Control. The API
mutexes are protected against asynchronous thread cancellation.

Add dedicated mutexes for libatomic and TOD.

Close #2629.
Close #2630.

Files:
1 added
2 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/include/rtems/posix/posixapi.h

    r3d7d2a37 r6c2b8a4b  
    2222#include <rtems/config.h>
    2323#include <rtems/score/assert.h>
    24 #include <rtems/score/apimutex.h>
    2524#include <rtems/score/objectimpl.h>
     25#include <rtems/score/onceimpl.h>
    2626#include <rtems/score/threadimpl.h>
    2727#include <rtems/seterr.h>
  • cpukit/rtems/src/rtemsobjectgetapiclassname.c

    r3d7d2a37 r6c2b8a4b  
    2626static const rtems_assoc_t rtems_object_api_internal_assoc[] = {
    2727  { "Thread",                  OBJECTS_INTERNAL_THREADS, 0},
    28   { "Mutex",                   OBJECTS_INTERNAL_MUTEXES, 0},
    2928  { NULL,                      0, 0}
    3029};
  • cpukit/rtems/src/timerserver.c

    r3d7d2a37 r6c2b8a4b  
    3030#include <rtems/rtems/timerimpl.h>
    3131#include <rtems/rtems/tasksimpl.h>
    32 #include <rtems/score/apimutex.h>
     32#include <rtems/score/onceimpl.h>
    3333#include <rtems/score/todimpl.h>
    3434
  • cpukit/sapi/include/confdefs.h

    r3d7d2a37 r6c2b8a4b  
    27952795
    27962796/**
    2797  * RTEMS uses two instance of an internal mutex class.  This accounts
    2798  * for these mutexes.
    2799  */
    2800 #define _CONFIGURE_API_MUTEX_MEMORY \
    2801   _Configure_Object_RAM(2, sizeof(API_Mutex_Control))
    2802 
    2803 /**
    28042797 * This calculates the amount of memory reserved for the IDLE tasks.
    28052798 * In an SMP system, each CPU core has its own idle task.
     
    28302823#define _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
    28312824  ( _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS + \
    2832     _CONFIGURE_INTERRUPT_STACK_MEMORY + \
    2833     _CONFIGURE_API_MUTEX_MEMORY \
     2825    _CONFIGURE_INTERRUPT_STACK_MEMORY \
    28342826  )
    28352827
  • cpukit/sapi/src/exinit.c

    r3d7d2a37 r6c2b8a4b  
    2828#include <rtems/score/sysstate.h>
    2929
    30 #include <rtems/score/apimutex.h>
    3130#include <rtems/score/copyrt.h>
    3231#include <rtems/score/heap.h>
     
    6059};
    6160
    62 API_Mutex_Control *_RTEMS_Allocator_Mutex;
    63 
    64 API_Mutex_Control *_Once_Mutex;
    65 
    6661static void rtems_initialize_data_structures(void)
    6762{
     
    8378
    8479  _ISR_Handler_initialization();
    85 
    86   _API_Mutex_Initialization( 2 );
    87   _API_Mutex_Allocate( &_RTEMS_Allocator_Mutex );
    88   _API_Mutex_Allocate( &_Once_Mutex );
    8980
    9081  _Thread_Handler_initialization();
  • cpukit/score/Makefile.am

    r3d7d2a37 r6c2b8a4b  
    163163
    164164## CORE_APIMUTEX_C_FILES
    165 libscore_a_SOURCES += src/apimutex.c \
    166     src/apimutexlock.c src/apimutexisowner.c src/apimutexunlock.c
     165libscore_a_SOURCES += src/allocatormutex.c
     166libscore_a_SOURCES += src/apimutexisowner.c
     167libscore_a_SOURCES += src/apimutexlock.c
     168libscore_a_SOURCES += src/apimutexunlock.c
    167169
    168170## CORE_BARRIER_C_FILES
     
    338340libscore_a_SOURCES += src/isrisinprogress.c
    339341libscore_a_SOURCES += src/condition.c
    340 libscore_a_SOURCES += src/debugisownerofallocator.c
    341342libscore_a_SOURCES += src/futex.c
    342343libscore_a_SOURCES += src/profilingisrentryexit.c
  • cpukit/score/include/rtems/score/apimutex.h

    r3d7d2a37 r6c2b8a4b  
    1919#define _RTEMS_SCORE_APIMUTEX_H
    2020
    21 #include <rtems/score/coremutex.h>
    22 #include <rtems/score/object.h>
     21#include <rtems/score/thread.h>
     22
     23#include <sys/lock.h>
    2324
    2425/**
     
    4041typedef struct {
    4142  /**
    42    * @brief Allows each API Mutex to be a full-fledged RTEMS object.
     43   * A recursive mutex.
    4344   */
    44   Objects_Control Object;
    45 
    46   /**
    47    * Contains the SuperCore mutex information.
    48    */
    49   CORE_recursive_mutex_Control Mutex;
     45  struct _Mutex_recursive_Control Mutex;
    5046
    5147  /**
     
    5753
    5854/**
    59  *  @brief Initialization for the API Mutexe Handler.
    60  *
    61  *  The value @a maximum_mutexes is the maximum number of API mutexes that may
    62  *  exist at any time.
    63  *
    64  *  @param[in] maximum_mutexes is the maximum number of API mutexes.
     55 * @brief Statically initialize an API mutex.
    6556 */
    66 void _API_Mutex_Initialization( uint32_t maximum_mutexes );
    67 
    68 /**
    69  * @brief Allocates an API mutex from the inactive set and returns it in
    70  * @a mutex.
    71  */
    72 void _API_Mutex_Allocate( API_Mutex_Control **mutex );
     57#define API_MUTEX_INITIALIZER( name ) \
     58  { _MUTEX_RECURSIVE_NAMED_INITIALIZER( name ), 0 }
    7359
    7460/**
     
    10894/**@{**/
    10995
    110 /**
    111  *  @brief Memory allocation mutex.
    112  *
    113  *  This points to the API Mutex instance used to ensure that only
    114  *  one thread at a time is allocating or freeing memory.
    115  */
    116 extern API_Mutex_Control *_RTEMS_Allocator_Mutex;
     96void _RTEMS_Lock_allocator( void );
    11797
    118 static inline void _RTEMS_Lock_allocator( void )
    119 {
    120   _API_Mutex_Lock( _RTEMS_Allocator_Mutex );
    121 }
     98void _RTEMS_Unlock_allocator( void );
    12299
    123 static inline void _RTEMS_Unlock_allocator( void )
    124 {
    125   _API_Mutex_Unlock( _RTEMS_Allocator_Mutex );
    126 }
    127 
    128 static inline bool _RTEMS_Allocator_is_owner( void )
    129 {
    130   return _API_Mutex_Is_owner( _RTEMS_Allocator_Mutex );
    131 }
    132 
    133 extern API_Mutex_Control *_Once_Mutex;
    134 
    135 static inline void _Once_Lock( void )
    136 {
    137   _API_Mutex_Lock( _Once_Mutex );
    138 }
    139 
    140 static inline void _Once_Unlock( void )
    141 {
    142   _API_Mutex_Unlock( _Once_Mutex );
    143 }
     100bool _RTEMS_Allocator_is_owner( void );
    144101
    145102/** @} */
  • cpukit/score/include/rtems/score/assert.h

    r3d7d2a37 r6c2b8a4b  
    102102#endif
    103103
    104 /**
    105  * @brief Returns true if the current thread of execution owns the allocator
    106  * mutex.
    107  */
    108 #if defined( RTEMS_DEBUG )
    109   bool _Debug_Is_owner_of_allocator( void );
    110 #endif
    111 
    112104#ifdef __cplusplus
    113105}
  • cpukit/score/include/rtems/score/objectimpl.h

    r3d7d2a37 r6c2b8a4b  
    5050typedef enum {
    5151  OBJECTS_INTERNAL_NO_CLASS =  0,
    52   OBJECTS_INTERNAL_THREADS  =  1,
    53   OBJECTS_INTERNAL_MUTEXES  =  2
     52  OBJECTS_INTERNAL_THREADS  =  1
    5453} Objects_Internal_API;
    5554
    5655/** This macro is used to generically specify the last API index. */
    57 #define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_MUTEXES
     56#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_THREADS
    5857
    5958/**
  • cpukit/score/include/rtems/score/onceimpl.h

    r3d7d2a37 r6c2b8a4b  
    4040int _Once( unsigned char *once_state, void (*init_routine)(void) );
    4141
     42void _Once_Lock( void );
     43
     44void _Once_Unlock( void );
     45
    4246/** @} */
    4347
  • cpukit/score/include/rtems/score/todimpl.h

    r3d7d2a37 r6c2b8a4b  
    2020
    2121#include <rtems/score/tod.h>
    22 #include <rtems/score/apimutex.h>
    2322#include <rtems/score/timestamp.h>
    2423#include <rtems/score/timecounterimpl.h>
     
    144143extern TOD_Control _TOD;
    145144
    146 static inline void _TOD_Lock( void )
    147 {
    148   /* FIXME: https://devel.rtems.org/ticket/2630 */
    149   _API_Mutex_Lock( _Once_Mutex );
    150 }
    151 
    152 static inline void _TOD_Unlock( void )
    153 {
    154   _API_Mutex_Unlock( _Once_Mutex );
    155 }
     145void _TOD_Lock( void );
     146
     147void _TOD_Unlock( void );
     148
     149#if defined(RTEMS_DEBUG)
     150bool _TOD_Is_owner( void );
     151#endif
    156152
    157153static inline void _TOD_Acquire( ISR_lock_Context *lock_context )
  • cpukit/score/src/apimutexisowner.c

    r3d7d2a37 r6c2b8a4b  
    1919
    2020#include <rtems/score/apimutex.h>
    21 #include <rtems/score/coremuteximpl.h>
    22 #include <rtems/score/threadimpl.h>
     21#include <rtems/score/percpu.h>
    2322
    2423bool _API_Mutex_Is_owner( const API_Mutex_Control *the_mutex )
    2524{
    26   return _CORE_mutex_Is_owner(
    27     &the_mutex->Mutex.Mutex,
    28     _Thread_Get_executing()
    29   );
     25  return the_mutex->Mutex._Mutex._Queue._owner == _Thread_Get_executing();
    3026}
  • cpukit/score/src/apimutexlock.c

    r3d7d2a37 r6c2b8a4b  
    2121
    2222#include <rtems/score/apimutex.h>
    23 #include <rtems/score/coremuteximpl.h>
    2423#include <rtems/score/threadimpl.h>
    2524
    2625void _API_Mutex_Lock( API_Mutex_Control *the_mutex )
    2726{
    28   Thread_Life_state    previous_thread_life_state;
    29   Thread_queue_Context queue_context;
     27  Thread_Life_state previous_thread_life_state;
    3028
    3129  previous_thread_life_state =
    3230    _Thread_Set_life_protection( THREAD_LIFE_PROTECTED );
    3331
    34   _Thread_queue_Context_initialize( &queue_context );
    35   _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
    36   _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    37   _CORE_recursive_mutex_Seize(
    38     &the_mutex->Mutex,
    39     CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
    40     _Thread_Executing,
    41     true,
    42     _CORE_recursive_mutex_Seize_nested,
    43     &queue_context
    44   );
     32  _Mutex_recursive_Acquire( &the_mutex->Mutex );
    4533
    46   if ( the_mutex->Mutex.nest_level == 0 ) {
     34  if ( the_mutex->Mutex._nest_level == 0 ) {
    4735    the_mutex->previous_thread_life_state = previous_thread_life_state;
    4836  }
  • cpukit/score/src/apimutexunlock.c

    r3d7d2a37 r6c2b8a4b  
    2121
    2222#include <rtems/score/apimutex.h>
    23 #include <rtems/score/coremuteximpl.h>
     23#include <rtems/score/threadimpl.h>
    2424
    2525void _API_Mutex_Unlock( API_Mutex_Control *the_mutex )
    2626{
    27   Thread_queue_Context queue_context;
    28   Thread_Life_state    previous_thread_life_state;
    29   bool                 restore_thread_life_protection;
     27  Thread_Life_state previous_thread_life_state;
     28  bool              restore_thread_life_protection;
    3029
    3130  previous_thread_life_state = the_mutex->previous_thread_life_state;
    32   restore_thread_life_protection = the_mutex->Mutex.nest_level == 0;
     31  restore_thread_life_protection = the_mutex->Mutex._nest_level == 0;
    3332
    34   _Thread_queue_Context_initialize( &queue_context );
    35   _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
    36   _CORE_recursive_mutex_Surrender(
    37     &the_mutex->Mutex,
    38     CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
    39     _Thread_Executing,
    40     &queue_context
    41   );
     33  _Mutex_recursive_Release( &the_mutex->Mutex );
    4234
    4335  if ( restore_thread_life_protection ) {
  • cpukit/score/src/coretod.c

    r3d7d2a37 r6c2b8a4b  
    2020
    2121#include <rtems/score/todimpl.h>
     22#include <rtems/score/apimutex.h>
    2223
    2324TOD_Control _TOD;
     25
     26static API_Mutex_Control _TOD_Mutex = API_MUTEX_INITIALIZER( "_TOD" );
     27
     28void _TOD_Lock( void )
     29{
     30  _API_Mutex_Lock( &_TOD_Mutex );
     31}
     32
     33void _TOD_Unlock( void )
     34{
     35  _API_Mutex_Unlock( &_TOD_Mutex );
     36}
     37
     38#if defined(RTEMS_DEBUG)
     39bool _TOD_Is_owner( void )
     40{
     41  return _API_Mutex_Is_owner( &_TOD_Mutex );
     42}
     43#endif
  • cpukit/score/src/coretodset.c

    r3d7d2a37 r6c2b8a4b  
    3333  uint32_t        cpu_index;
    3434
    35   _Assert( _API_Mutex_Is_owner( _Once_Mutex ) );
     35  _Assert( _TOD_Is_owner() );
    3636
    3737  timespec2bintime( tod, &tod_as_bintime );
  • cpukit/score/src/libatomic.c

    r3d7d2a37 r6c2b8a4b  
    6060}
    6161
    62 /*
    63  * FIXME: The once lock should be only a temporary solution. We need a
    64  * dedicated internal mutex for this.
    65  */
     62static API_Mutex_Control _Libatomic_Mutex =
     63  API_MUTEX_INITIALIZER( "_Libatomic" );
    6664
    6765void _Libatomic_Lock_n( void *ptr, __size_t n )
     
    6967  (void) ptr;
    7068  (void) n;
    71   _Once_Lock();
     69  _API_Mutex_Lock( &_Libatomic_Mutex );
    7270}
    7371
     
    7674  (void) ptr;
    7775  (void) n;
    78   _Once_Unlock();
     76  _API_Mutex_Unlock( &_Libatomic_Mutex );
    7977}
  • cpukit/score/src/objectactivecount.c

    r3d7d2a37 r6c2b8a4b  
    2828  size_t maximum;
    2929
    30   _Assert( _Debug_Is_owner_of_allocator() );
     30  _Assert( _Objects_Allocator_is_owner() );
    3131
    3232  inactive = _Chain_Node_count_unprotected( &information->Inactive );
  • cpukit/score/src/objectallocate.c

    r3d7d2a37 r6c2b8a4b  
    4444
    4545  _Assert(
    46     _Debug_Is_owner_of_allocator()
     46    _Objects_Allocator_is_owner()
    4747      || !_System_state_Is_up( _System_state_Get() )
    4848  );
  • cpukit/score/src/objectextendinformation.c

    r3d7d2a37 r6c2b8a4b  
    5757
    5858  _Assert(
    59     _Debug_Is_owner_of_allocator()
     59    _Objects_Allocator_is_owner()
    6060      || !_System_state_Is_up( _System_state_Get() )
    6161  );
  • cpukit/score/src/objectfree.c

    r3d7d2a37 r6c2b8a4b  
    3030  uint32_t    allocation_size = information->allocation_size;
    3131
    32   _Assert( _Debug_Is_owner_of_allocator() );
     32  _Assert( _Objects_Allocator_is_owner() );
    3333
    3434  _Chain_Append_unprotected( &information->Inactive, &the_object->Node );
  • cpukit/score/src/objectshrinkinformation.c

    r3d7d2a37 r6c2b8a4b  
    3232  uint32_t          index_base;
    3333
    34   _Assert( _Debug_Is_owner_of_allocator() );
     34  _Assert( _Objects_Allocator_is_owner() );
    3535
    3636  /*
  • cpukit/score/src/once.c

    r3d7d2a37 r6c2b8a4b  
    5555  return eno;
    5656}
     57
     58static API_Mutex_Control _Once_Mutex = API_MUTEX_INITIALIZER( "_Once" );
     59
     60void _Once_Lock( void )
     61{
     62  _API_Mutex_Lock( &_Once_Mutex );
     63}
     64
     65void _Once_Unlock( void )
     66{
     67  _API_Mutex_Unlock( &_Once_Mutex );
     68}
  • testsuites/sptests/sp43/init.c

    r3d7d2a37 r6c2b8a4b  
    348348  printf( "rtems_object_get_api_class_name(CLASSIC_API, 0) = %s\n",
    349349    rtems_object_get_api_class_name( OBJECTS_CLASSIC_API, 0 ) );
    350   printf("rtems_object_get_api_class_name(INTERNAL_API, MUTEXES) = %s\n",
     350  printf("rtems_object_get_api_class_name(INTERNAL_API, THREADS) = %s\n",
    351351    rtems_object_get_api_class_name(
    352        OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_MUTEXES));
     352       OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS));
    353353  printf("rtems_object_get_api_class_name(CLASSIC_API, RTEMS_BARRIERS) = %s\n",
    354354    rtems_object_get_api_class_name(
  • testsuites/sptests/sp43/sp43.scn

    r3d7d2a37 r6c2b8a4b  
    11*** BEGIN OF TEST SP 43 ***
    2 RTEMS Version: rtems-4.11.99.0(SPARC/w/FPU/sis)
     2RTEMS Version: rtems-5.0.0 (SPARC/w/FPU/erc32)
    33rtems_object_get_classic_name - INVALID_ADDRESS
    44rtems_object_get_classic_name - INVALID_ID (bad index)
     
    5454rtems_object_api_maximum_class(255) returned 0
    5555rtems_object_api_minimum_class(OBJECTS_INTERNAL_API) returned 1
    56 rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) returned 2
     56rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) returned 1
    5757rtems_object_api_minimum_class(OBJECTS_CLASSIC_API) returned 1
    5858rtems_object_api_maximum_class(OBJECTS_CLASSIC_API) returned 10
     
    6464rtems_object_get_api_class_name(0, RTEMS_TASKS) = BAD API
    6565rtems_object_get_api_class_name(CLASSIC_API, 0) = BAD CLASS
    66 rtems_object_get_api_class_name(INTERNAL_API, MUTEXES) = Mutex
     66rtems_object_get_api_class_name(INTERNAL_API, THREADS) = Thread
    6767rtems_object_get_api_class_name(CLASSIC_API, RTEMS_BARRIERS) = Barrier
    6868<pause>
     
    8383    auto_extend : no
    8484rtems_task_set_priority - use valid Idle thread id
    85 rtems_task_set_priority - clobber internal API info
    86 rtems_task_set_priority - use valid Idle thread id again
    87 rtems_task_set_priority - restore internal api info
    8885rtems_task_set_priority - clobber internal thread class info
    8986rtems_task_set_priority - use valid Idle thread id again
     
    9188rtems_task_set_priority - restore internal thread class info
    9289rtems_semaphore_obtain - good but uncreated ID - INVALID_ID - OK
    93 rtems_object_get_classic_name - bad API pointer - INVALID_ID
     90
    9491*** END OF TEST SP 43 ***
  • testsuites/sptests/spsysinit01/init.c

    r3d7d2a37 r6c2b8a4b  
    233233FIRST(RTEMS_SYSINIT_DATA_STRUCTURES)
    234234{
    235   assert(_RTEMS_Allocator_Mutex == NULL);
     235  assert(_Thread_Internal_information.Objects.maximum == 0);
    236236  next_step(DATA_STRUCTURES_PRE);
    237237}
     
    239239LAST(RTEMS_SYSINIT_DATA_STRUCTURES)
    240240{
    241   assert(_RTEMS_Allocator_Mutex != NULL);
     241  assert(_Thread_Internal_information.Objects.maximum != 0);
    242242  next_step(DATA_STRUCTURES_POST);
    243243}
Note: See TracChangeset for help on using the changeset viewer.