summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-11 14:03:23 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-12 13:24:41 +0200
commitef6f8a8377964a2d94eb7215724d11b499ec078b (patch)
treeaae76c846caa88944627c51b6589ab9caeb24ce0 /cpukit/score
parentposix: Avoid Giant lock for some pthread functions (diff)
downloadrtems-ef6f8a8377964a2d94eb7215724d11b499ec078b.tar.bz2
score: Avoid Giant lock for scheduler set/get
Update #2555.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h42
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h8
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h26
3 files changed, 62 insertions, 14 deletions
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 640f871b05..bfc6df330a 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -599,25 +599,45 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Has_processor_ownership(
#endif
}
-RTEMS_INLINE_ROUTINE void _Scheduler_Set(
+RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
{
#if defined(RTEMS_SMP)
- const Scheduler_Control *current_scheduler = _Scheduler_Get( the_thread );
-
- if ( current_scheduler != scheduler ) {
- _Thread_Set_state( the_thread, STATES_MIGRATING );
- _Scheduler_Node_destroy( current_scheduler, the_thread );
- the_thread->Scheduler.own_control = scheduler;
- the_thread->Scheduler.control = scheduler;
- _Scheduler_Node_initialize( scheduler, the_thread );
- _Scheduler_Update_priority( the_thread, the_thread->current_priority );
- _Thread_Clear_state( the_thread, STATES_MIGRATING );
+ const Scheduler_Control *current_scheduler;
+ States_Control current_state;
+
+ current_scheduler = _Scheduler_Get( the_thread );
+
+ if ( current_scheduler == scheduler ) {
+ return true;
+ }
+
+ if ( _Thread_Owns_resources( the_thread ) ) {
+ return false;
+ }
+
+ current_state = the_thread->current_state;
+
+ if ( _States_Is_ready( current_state ) ) {
+ _Scheduler_Block( the_thread );
}
+
+ _Scheduler_Node_destroy( current_scheduler, the_thread );
+ the_thread->Scheduler.own_control = scheduler;
+ the_thread->Scheduler.control = scheduler;
+ _Scheduler_Node_initialize( scheduler, the_thread );
+ _Scheduler_Update_priority( the_thread, the_thread->current_priority );
+
+ if ( _States_Is_ready( current_state ) ) {
+ _Scheduler_Unblock( the_thread );
+ }
+
+ return true;
#else
(void) scheduler;
+ return true;
#endif
}
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 931eec0d1b..1ea49dd60e 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -359,6 +359,14 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_State_acquire_for_executing(
return executing;
}
+RTEMS_INLINE_ROUTINE void _Thread_State_release_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Release_critical( &the_thread->Join_queue, lock_context );
+}
+
RTEMS_INLINE_ROUTINE void _Thread_State_release(
Thread_Control *the_thread,
ISR_lock_Context *lock_context
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 898d61c552..b09cc97790 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -108,7 +108,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical(
_Thread_queue_Queue_do_acquire_critical( queue, lock_context )
#endif
-RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release_critical(
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
)
@@ -118,7 +118,18 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
&queue->Lock,
&lock_context->Lock_context.Stats_context
);
+#else
+ (void) queue;
+ (void) lock_context;
#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
+ Thread_queue_Queue *queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Queue_release_critical( queue, lock_context );
_ISR_lock_ISR_enable( lock_context );
}
@@ -159,7 +170,7 @@ RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_lock_owner(
}
#endif
-RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release_critical(
Thread_queue_Control *the_thread_queue,
ISR_lock_Context *lock_context
)
@@ -170,12 +181,21 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
the_thread_queue->owner = SMP_LOCK_NO_OWNER;
#endif
#endif
- _Thread_queue_Queue_release(
+ _Thread_queue_Queue_release_critical(
&the_thread_queue->Queue,
lock_context
);
}
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Release_critical( the_thread_queue, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
Thread_Control *_Thread_queue_Do_dequeue(
Thread_queue_Control *the_thread_queue,
const Thread_queue_Operations *operations