[PATCH 11/19] rtems: Avoid Giant lock for semaphores
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Apr 29 09:13:11 UTC 2016
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 f079a67..b360b07 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 68eac6f..b67b415 100644
--- a/cpukit/rtems/include/rtems/rtems/semimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/semimpl.h
@@ -145,26 +145,6 @@ RTEMS_INLINE_ROUTINE void _Semaphore_Free (
* 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.
- *
- * 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_interrupt_disable (
Objects_Id id,
Objects_Locations *location,
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index b5dd1db..1073a56 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 5b19c3d..a46f042 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();
}
--
1.8.4.5
More information about the devel
mailing list