From f009ed086d3da813a2c92b9834c3b2d618894883 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 27 Apr 2016 16:36:04 +0200 Subject: rtems: Avoid Giant lock for semaphores Update #2555. --- cpukit/libnetworking/rtems/rtems_glue.c | 7 ++----- cpukit/rtems/include/rtems/rtems/semimpl.h | 20 -------------------- cpukit/rtems/src/semsetpriority.c | 26 ++++++++++++++++++++------ testsuites/tmtests/tm26/task1.c | 14 +++++++++++--- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c index f079a67a3a..b360b079ba 100644 --- a/cpukit/libnetworking/rtems/rtems_glue.c +++ b/cpukit/libnetworking/rtems/rtems_glue.c @@ -330,11 +330,8 @@ rtems_bsdnet_initialize (void) return -1; } #ifdef RTEMS_FAST_MUTEX - { - Objects_Locations location; - the_networkSemaphore = _Semaphore_Get( networkSemaphore, &location ); - _Thread_Enable_dispatch(); - } + the_networkSemaphore = (Semaphore_Control *) + _Objects_Get_no_protection(networkSemaphore, &_Semaphore_Information); #endif /* diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h index 68eac6f2e7..b67b415750 100644 --- a/cpukit/rtems/include/rtems/rtems/semimpl.h +++ b/cpukit/rtems/include/rtems/rtems/semimpl.h @@ -134,26 +134,6 @@ RTEMS_INLINE_ROUTINE void _Semaphore_Free ( _Objects_Free( &_Semaphore_Information, &the_semaphore->Object ); } -/** - * @brief Maps semaphore IDs to semaphore control blocks. - * - * This function maps semaphore IDs to semaphore control blocks. - * If ID corresponds to a local semaphore, then it returns - * the_semaphore control pointer which maps to ID and location - * is set to OBJECTS_LOCAL. if the semaphore ID is global and - * resides on a remote node, then location is set to OBJECTS_REMOTE, - * and the_semaphore is undefined. Otherwise, location is set - * to OBJECTS_ERROR and the_semaphore is undefined. - */ -RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get ( - Objects_Id id, - Objects_Locations *location -) -{ - return (Semaphore_Control *) - _Objects_Get( &_Semaphore_Information, id, location ); -} - /** * @brief Maps semaphore IDs to semaphore control blocks. * diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c index b5dd1db101..1073a561a8 100644 --- a/cpukit/rtems/src/semsetpriority.c +++ b/cpukit/rtems/src/semsetpriority.c @@ -25,7 +25,8 @@ static rtems_status_code _Semaphore_Set_priority( Semaphore_Control *the_semaphore, rtems_id scheduler_id, rtems_task_priority new_priority, - rtems_task_priority *old_priority_p + rtems_task_priority *old_priority_p, + ISR_lock_Context *lock_context ) { rtems_status_code sc; @@ -39,26 +40,36 @@ static rtems_status_code _Semaphore_Set_priority( MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp; uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id ); + _MRSP_Acquire_critical( mrsp, lock_context ); + old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); if ( new_priority != RTEMS_CURRENT_PRIORITY ) { _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority ); } + _MRSP_Release( mrsp, lock_context ); + sc = RTEMS_SUCCESSFUL; } else #endif if ( _Attributes_Is_priority_ceiling( attribute_set ) ) { CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex; + _CORE_mutex_Acquire_critical( mutex, lock_context ); + old_priority = mutex->Attributes.priority_ceiling; if ( new_priority != RTEMS_CURRENT_PRIORITY ) { mutex->Attributes.priority_ceiling = new_priority; } + _CORE_mutex_Release( mutex, lock_context ); + sc = RTEMS_SUCCESSFUL; } else { + _ISR_lock_ISR_enable( lock_context ); + old_priority = 0; sc = RTEMS_NOT_DEFINED; @@ -66,8 +77,6 @@ static rtems_status_code _Semaphore_Set_priority( *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority ); - _Objects_Put( &the_semaphore->Object ); - return sc; } @@ -80,6 +89,7 @@ rtems_status_code rtems_semaphore_set_priority( { Semaphore_Control *the_semaphore; Objects_Locations location; + ISR_lock_Context lock_context; if ( new_priority != RTEMS_CURRENT_PRIORITY && !_RTEMS_tasks_Priority_is_valid( new_priority ) ) { @@ -94,18 +104,22 @@ rtems_status_code rtems_semaphore_set_priority( return RTEMS_INVALID_ID; } - the_semaphore = _Semaphore_Get( semaphore_id, &location ); + the_semaphore = _Semaphore_Get_interrupt_disable( + semaphore_id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: return _Semaphore_Set_priority( the_semaphore, scheduler_id, new_priority, - old_priority + old_priority, + &lock_context ); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: - _Thread_Dispatch(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif case OBJECTS_ERROR: diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c index 5b19c3d3b6..a46f042ac6 100644 --- a/testsuites/tmtests/tm26/task1.c +++ b/testsuites/tmtests/tm26/task1.c @@ -575,8 +575,16 @@ void complete_test( void ) thread_get_time = benchmark_timer_read(); benchmark_timer_initialize(); - for ( index=1 ; index <= OPERATION_COUNT ; index++ ) - (void) _Semaphore_Get( Semaphore_id, &location ); + for ( index=1 ; index <= OPERATION_COUNT ; index++ ) { + ISR_lock_Context lock_context; + + (void) _Semaphore_Get_interrupt_disable( + Semaphore_id, + &location, + &lock_context + ); + _ISR_lock_ISR_enable( &lock_context ); + } semaphore_get_time = benchmark_timer_read(); benchmark_timer_initialize(); @@ -592,7 +600,7 @@ void complete_test( void ) set_thread_heir( _Thread_Get_executing() ); set_thread_dispatch_necessary( false ); - for (index = 0; index < 2 * OPERATION_COUNT; ++index) { + for (index = 0; index < OPERATION_COUNT; ++index) { _Thread_Unnest_dispatch(); } -- cgit v1.2.3