diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-11 14:03:23 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-12 13:24:41 +0200 |
commit | ef6f8a8377964a2d94eb7215724d11b499ec078b (patch) | |
tree | aae76c846caa88944627c51b6589ab9caeb24ce0 /cpukit/rtems | |
parent | posix: Avoid Giant lock for some pthread functions (diff) | |
download | rtems-ef6f8a8377964a2d94eb7215724d11b499ec078b.tar.bz2 |
score: Avoid Giant lock for scheduler set/get
Update #2555.
Diffstat (limited to 'cpukit/rtems')
-rw-r--r-- | cpukit/rtems/src/taskgetscheduler.c | 52 | ||||
-rw-r--r-- | cpukit/rtems/src/tasksetscheduler.c | 50 |
2 files changed, 51 insertions, 51 deletions
diff --git a/cpukit/rtems/src/taskgetscheduler.c b/cpukit/rtems/src/taskgetscheduler.c index 47895a42e4..9d8bbb6c41 100644 --- a/cpukit/rtems/src/taskgetscheduler.c +++ b/cpukit/rtems/src/taskgetscheduler.c @@ -24,37 +24,31 @@ rtems_status_code rtems_task_get_scheduler( rtems_id *scheduler_id ) { - rtems_status_code sc; - - if ( scheduler_id != NULL ) { - Thread_Control *the_thread; - Objects_Locations location; - const Scheduler_Control *scheduler; - - the_thread = _Thread_Get( task_id, &location ); - - switch ( location ) { - case OBJECTS_LOCAL: - scheduler = _Scheduler_Get( the_thread ); - *scheduler_id = _Scheduler_Build_id( - _Scheduler_Get_index( scheduler ) - ); - _Objects_Put( &the_thread->Object ); - sc = RTEMS_SUCCESSFUL; - break; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + const Scheduler_Control *scheduler; + + if ( scheduler_id == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + the_thread = _Thread_Get_interrupt_disable( task_id, &lock_context ); + + if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: - _Thread_Dispatch(); - sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT; - break; -#endif - default: - sc = RTEMS_INVALID_ID; - break; + if ( _Thread_MP_Is_remote( task_id ) ) { + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } - } else { - sc = RTEMS_INVALID_ADDRESS; +#endif + + return RTEMS_INVALID_ID; } - return sc; + _Thread_State_acquire_critical( the_thread, &lock_context ); + + scheduler = _Scheduler_Get( the_thread ); + *scheduler_id = _Scheduler_Build_id( _Scheduler_Get_index( scheduler ) ); + + _Thread_State_release( the_thread, &lock_context ); + return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/tasksetscheduler.c b/cpukit/rtems/src/tasksetscheduler.c index e05553046d..428ef3dd9d 100644 --- a/cpukit/rtems/src/tasksetscheduler.c +++ b/cpukit/rtems/src/tasksetscheduler.c @@ -24,34 +24,40 @@ rtems_status_code rtems_task_set_scheduler( rtems_id scheduler_id ) { - rtems_status_code sc; const Scheduler_Control *scheduler; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + ISR_lock_Context state_lock_context; + Per_CPU_Control *cpu_self; + void *lock; + bool ok; - if ( _Scheduler_Get_by_id( scheduler_id, &scheduler ) ) { - Thread_Control *the_thread; - Objects_Locations location; + if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) { + return RTEMS_INVALID_ID; + } - the_thread = _Thread_Get( task_id, &location ); + the_thread = _Thread_Get_interrupt_disable( task_id, &lock_context ); - switch ( location ) { - case OBJECTS_LOCAL: - _Scheduler_Set( scheduler, the_thread ); - _Objects_Put( &the_thread->Object ); - sc = RTEMS_SUCCESSFUL; - break; + if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: - _Thread_Dispatch(); - sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT; - break; -#endif - default: - sc = RTEMS_INVALID_ID; - break; + if ( _Thread_MP_Is_remote( task_id ) ) { + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } - } else { - sc = RTEMS_INVALID_ID; +#endif + + return RTEMS_INVALID_ID; } - return sc; + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _ISR_lock_ISR_enable( &lock_context ); + + lock = _Thread_Lock_acquire( the_thread, &lock_context ); + _Thread_State_acquire_critical( the_thread, &state_lock_context ); + + ok = _Scheduler_Set( scheduler, the_thread ); + + _Thread_State_release_critical( the_thread, &state_lock_context ); + _Thread_Lock_release( lock, &lock_context ); + _Thread_Dispatch_enable( cpu_self ); + return ok ? RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE; } |