From 6c2b8a4b35536a5f99ba1ef91139485b011dafc1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 29 Nov 2017 06:23:27 +0100 Subject: 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. --- cpukit/score/src/allocatormutex.c | 37 ++++++++++++++++++ cpukit/score/src/apimutex.c | 60 ------------------------------ cpukit/score/src/apimutexisowner.c | 8 +--- cpukit/score/src/apimutexlock.c | 18 ++------- cpukit/score/src/apimutexunlock.c | 18 +++------ cpukit/score/src/coretod.c | 20 ++++++++++ cpukit/score/src/coretodset.c | 2 +- cpukit/score/src/debugisownerofallocator.c | 37 ------------------ cpukit/score/src/libatomic.c | 10 ++--- cpukit/score/src/objectactivecount.c | 2 +- cpukit/score/src/objectallocate.c | 2 +- cpukit/score/src/objectextendinformation.c | 2 +- cpukit/score/src/objectfree.c | 2 +- cpukit/score/src/objectshrinkinformation.c | 2 +- cpukit/score/src/once.c | 12 ++++++ 15 files changed, 89 insertions(+), 143 deletions(-) create mode 100644 cpukit/score/src/allocatormutex.c delete mode 100644 cpukit/score/src/apimutex.c delete mode 100644 cpukit/score/src/debugisownerofallocator.c (limited to 'cpukit/score/src') diff --git a/cpukit/score/src/allocatormutex.c b/cpukit/score/src/allocatormutex.c new file mode 100644 index 0000000000..7f98a4008f --- /dev/null +++ b/cpukit/score/src/allocatormutex.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +static API_Mutex_Control _RTEMS_Allocator_Mutex = + API_MUTEX_INITIALIZER( "_Allocator" ); + +void _RTEMS_Lock_allocator( void ) +{ + _API_Mutex_Lock( &_RTEMS_Allocator_Mutex ); +} + +void _RTEMS_Unlock_allocator( void ) +{ + _API_Mutex_Unlock( &_RTEMS_Allocator_Mutex ); +} + +bool _RTEMS_Allocator_is_owner( void ) +{ + return _API_Mutex_Is_owner( &_RTEMS_Allocator_Mutex ); +} diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c deleted file mode 100644 index ed5cfd5831..0000000000 --- a/cpukit/score/src/apimutex.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file - * - * @brief Initialization and Allocation for API Mutex Handler - * - * @ingroup ScoreAPIMutex - */ - -/* - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -static Objects_Information _API_Mutex_Information; - -void _API_Mutex_Initialization( - uint32_t maximum_mutexes -) -{ - _Objects_Initialize_information( - &_API_Mutex_Information, /* object information table */ - OBJECTS_INTERNAL_API, /* object API */ - OBJECTS_INTERNAL_MUTEXES, /* object class */ - maximum_mutexes, /* maximum objects of this class */ - sizeof( API_Mutex_Control ), /* size of this object's control block */ - false, /* true if the name is a string */ - 0, /* maximum length of an object name */ - NULL /* Proxy extraction support callout */ - ); -} - -void _API_Mutex_Allocate( - API_Mutex_Control **the_mutex -) -{ - API_Mutex_Control *mutex; - - mutex = (API_Mutex_Control *) - _Objects_Allocate_unprotected( &_API_Mutex_Information ); - - _Assert( mutex != NULL ); - - _CORE_recursive_mutex_Initialize( &mutex->Mutex ); - - _Objects_Open_u32( &_API_Mutex_Information, &mutex->Object, 1 ); - - *the_mutex = mutex; -} diff --git a/cpukit/score/src/apimutexisowner.c b/cpukit/score/src/apimutexisowner.c index 65b80ed5b3..3c6f2a1b21 100644 --- a/cpukit/score/src/apimutexisowner.c +++ b/cpukit/score/src/apimutexisowner.c @@ -18,13 +18,9 @@ #endif #include -#include -#include +#include bool _API_Mutex_Is_owner( const API_Mutex_Control *the_mutex ) { - return _CORE_mutex_Is_owner( - &the_mutex->Mutex.Mutex, - _Thread_Get_executing() - ); + return the_mutex->Mutex._Mutex._Queue._owner == _Thread_Get_executing(); } diff --git a/cpukit/score/src/apimutexlock.c b/cpukit/score/src/apimutexlock.c index 312dcc2993..46a48a3e50 100644 --- a/cpukit/score/src/apimutexlock.c +++ b/cpukit/score/src/apimutexlock.c @@ -20,30 +20,18 @@ #endif #include -#include #include void _API_Mutex_Lock( API_Mutex_Control *the_mutex ) { - Thread_Life_state previous_thread_life_state; - Thread_queue_Context queue_context; + Thread_Life_state previous_thread_life_state; previous_thread_life_state = _Thread_Set_life_protection( THREAD_LIFE_PROTECTED ); - _Thread_queue_Context_initialize( &queue_context ); - _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); - _CORE_recursive_mutex_Seize( - &the_mutex->Mutex, - CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS, - _Thread_Executing, - true, - _CORE_recursive_mutex_Seize_nested, - &queue_context - ); + _Mutex_recursive_Acquire( &the_mutex->Mutex ); - if ( the_mutex->Mutex.nest_level == 0 ) { + if ( the_mutex->Mutex._nest_level == 0 ) { the_mutex->previous_thread_life_state = previous_thread_life_state; } } diff --git a/cpukit/score/src/apimutexunlock.c b/cpukit/score/src/apimutexunlock.c index e1fe6459d3..b4a5592059 100644 --- a/cpukit/score/src/apimutexunlock.c +++ b/cpukit/score/src/apimutexunlock.c @@ -20,25 +20,17 @@ #endif #include -#include +#include void _API_Mutex_Unlock( API_Mutex_Control *the_mutex ) { - Thread_queue_Context queue_context; - Thread_Life_state previous_thread_life_state; - bool restore_thread_life_protection; + Thread_Life_state previous_thread_life_state; + bool restore_thread_life_protection; previous_thread_life_state = the_mutex->previous_thread_life_state; - restore_thread_life_protection = the_mutex->Mutex.nest_level == 0; + restore_thread_life_protection = the_mutex->Mutex._nest_level == 0; - _Thread_queue_Context_initialize( &queue_context ); - _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context ); - _CORE_recursive_mutex_Surrender( - &the_mutex->Mutex, - CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS, - _Thread_Executing, - &queue_context - ); + _Mutex_recursive_Release( &the_mutex->Mutex ); if ( restore_thread_life_protection ) { _Thread_Set_life_protection( previous_thread_life_state ); diff --git a/cpukit/score/src/coretod.c b/cpukit/score/src/coretod.c index 1df1b4ed86..cd8428c15d 100644 --- a/cpukit/score/src/coretod.c +++ b/cpukit/score/src/coretod.c @@ -19,5 +19,25 @@ #endif #include +#include TOD_Control _TOD; + +static API_Mutex_Control _TOD_Mutex = API_MUTEX_INITIALIZER( "_TOD" ); + +void _TOD_Lock( void ) +{ + _API_Mutex_Lock( &_TOD_Mutex ); +} + +void _TOD_Unlock( void ) +{ + _API_Mutex_Unlock( &_TOD_Mutex ); +} + +#if defined(RTEMS_DEBUG) +bool _TOD_Is_owner( void ) +{ + return _API_Mutex_Is_owner( &_TOD_Mutex ); +} +#endif diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c index 1223f5c7aa..fa6407cfaf 100644 --- a/cpukit/score/src/coretodset.c +++ b/cpukit/score/src/coretodset.c @@ -32,7 +32,7 @@ void _TOD_Set( uint32_t cpu_count; uint32_t cpu_index; - _Assert( _API_Mutex_Is_owner( _Once_Mutex ) ); + _Assert( _TOD_Is_owner() ); timespec2bintime( tod, &tod_as_bintime ); _Timecounter_Set_clock( &tod_as_bintime, lock_context ); diff --git a/cpukit/score/src/debugisownerofallocator.c b/cpukit/score/src/debugisownerofallocator.c deleted file mode 100644 index 6b396df4fc..0000000000 --- a/cpukit/score/src/debugisownerofallocator.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2014-2015 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include -#include -#include - -#if defined( RTEMS_DEBUG ) - bool _Debug_Is_owner_of_allocator( void ) - { - API_Mutex_Control *mutex = _RTEMS_Allocator_Mutex; - bool owner; - - if ( mutex != NULL ) { - owner = _API_Mutex_Is_owner( mutex ); - } else { - owner = false; - } - - return owner; - } -#endif diff --git a/cpukit/score/src/libatomic.c b/cpukit/score/src/libatomic.c index bfa3e6fb25..364e38f1b3 100644 --- a/cpukit/score/src/libatomic.c +++ b/cpukit/score/src/libatomic.c @@ -59,21 +59,19 @@ void _Libatomic_Protect_end( void *ptr, __uint32_t isr_level ) _ISR_Local_enable( isr_level ); } -/* - * FIXME: The once lock should be only a temporary solution. We need a - * dedicated internal mutex for this. - */ +static API_Mutex_Control _Libatomic_Mutex = + API_MUTEX_INITIALIZER( "_Libatomic" ); void _Libatomic_Lock_n( void *ptr, __size_t n ) { (void) ptr; (void) n; - _Once_Lock(); + _API_Mutex_Lock( &_Libatomic_Mutex ); } void _Libatomic_Unlock_n( void *ptr, __size_t n ) { (void) ptr; (void) n; - _Once_Unlock(); + _API_Mutex_Unlock( &_Libatomic_Mutex ); } diff --git a/cpukit/score/src/objectactivecount.c b/cpukit/score/src/objectactivecount.c index de3243afcb..376820158a 100644 --- a/cpukit/score/src/objectactivecount.c +++ b/cpukit/score/src/objectactivecount.c @@ -27,7 +27,7 @@ Objects_Maximum _Objects_Active_count( size_t inactive; size_t maximum; - _Assert( _Debug_Is_owner_of_allocator() ); + _Assert( _Objects_Allocator_is_owner() ); inactive = _Chain_Node_count_unprotected( &information->Inactive ); maximum = information->maximum; diff --git a/cpukit/score/src/objectallocate.c b/cpukit/score/src/objectallocate.c index 40a7cae82c..146b5d5976 100644 --- a/cpukit/score/src/objectallocate.c +++ b/cpukit/score/src/objectallocate.c @@ -43,7 +43,7 @@ Objects_Control *_Objects_Allocate_unprotected( Objects_Control *the_object; _Assert( - _Debug_Is_owner_of_allocator() + _Objects_Allocator_is_owner() || !_System_state_Is_up( _System_state_Get() ) ); diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c index cd78a72af5..f4ac11be43 100644 --- a/cpukit/score/src/objectextendinformation.c +++ b/cpukit/score/src/objectextendinformation.c @@ -56,7 +56,7 @@ void _Objects_Extend_information( bool do_extend; _Assert( - _Debug_Is_owner_of_allocator() + _Objects_Allocator_is_owner() || !_System_state_Is_up( _System_state_Get() ) ); diff --git a/cpukit/score/src/objectfree.c b/cpukit/score/src/objectfree.c index f1c0ee49b2..30ea1e36e5 100644 --- a/cpukit/score/src/objectfree.c +++ b/cpukit/score/src/objectfree.c @@ -29,7 +29,7 @@ void _Objects_Free( { uint32_t allocation_size = information->allocation_size; - _Assert( _Debug_Is_owner_of_allocator() ); + _Assert( _Objects_Allocator_is_owner() ); _Chain_Append_unprotected( &information->Inactive, &the_object->Node ); diff --git a/cpukit/score/src/objectshrinkinformation.c b/cpukit/score/src/objectshrinkinformation.c index 2f64cd2502..db085e1042 100644 --- a/cpukit/score/src/objectshrinkinformation.c +++ b/cpukit/score/src/objectshrinkinformation.c @@ -31,7 +31,7 @@ void _Objects_Shrink_information( uint32_t block; uint32_t index_base; - _Assert( _Debug_Is_owner_of_allocator() ); + _Assert( _Objects_Allocator_is_owner() ); /* * Search the list to find block or chunk with all objects inactive. diff --git a/cpukit/score/src/once.c b/cpukit/score/src/once.c index 427659e173..5237c11878 100644 --- a/cpukit/score/src/once.c +++ b/cpukit/score/src/once.c @@ -54,3 +54,15 @@ int _Once( unsigned char *once_state, void ( *init_routine )( void ) ) return eno; } + +static API_Mutex_Control _Once_Mutex = API_MUTEX_INITIALIZER( "_Once" ); + +void _Once_Lock( void ) +{ + _API_Mutex_Lock( &_Once_Mutex ); +} + +void _Once_Unlock( void ) +{ + _API_Mutex_Unlock( &_Once_Mutex ); +} -- cgit v1.2.3