[PATCH 13/14] posix: Avoid Giant lock for some pthread functions
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed May 11 13:23:40 UTC 2016
Avoid Giant lock for pthread_getattr_np(), pthread_setschedparam() and
pthread_getschedparam(). Replace POSIX threads scheduler lock with
thread state lock.
Update #2555.
---
cpukit/posix/include/rtems/posix/pthreadimpl.h | 17 ----
cpukit/posix/include/rtems/posix/threadsup.h | 2 -
cpukit/posix/src/pthread.c | 11 +--
cpukit/posix/src/pthreadgetattrnp.c | 35 ++++---
cpukit/posix/src/pthreadgetschedparam.c | 42 ++++-----
cpukit/posix/src/pthreadsetschedparam.c | 123 ++++++++++++-------------
cpukit/score/include/rtems/score/thread.h | 5 +
7 files changed, 103 insertions(+), 132 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index ef5821e..42f10b0 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -223,23 +223,6 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Join_dequeue(
);
}
-RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_acquire(
- POSIX_API_Control *api,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_ISR_disable_and_acquire( &api->Scheduler_lock, lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_release(
- POSIX_API_Control *api,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_Release_and_ISR_enable( &api->Scheduler_lock, lock_context );
-}
-
-
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index 93ba2c1..8109921 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -52,8 +52,6 @@ typedef struct {
/** This is the set of threads waiting for the thread to exit. */
Thread_queue_Control Join_List;
/** This is the thread's current scheduling policy. */
- ISR_LOCK_MEMBER( Scheduler_lock )
- /** This is the thread's current scheduling policy. */
int schedpolicy;
/** This is the thread's current set of scheduling parameters. */
struct sched_param schedparam;
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 61e498b..5c5cff7 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -114,7 +114,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
the_thread = api->thread;
- _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+ _Thread_State_acquire( the_thread, &lock_context );
the_thread->cpu_time_budget =
_Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
@@ -128,7 +128,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
- _POSIX_Threads_Scheduler_release( api, &lock_context );
+ _Thread_State_release( the_thread, &lock_context );
_Thread_Change_priority(
the_thread,
@@ -200,8 +200,6 @@ static bool _POSIX_Threads_Create_extension(
api = created->API_Extensions[ THREAD_API_POSIX ];
- _ISR_lock_Initialize( &api->Scheduler_lock, "POSIX Threads Scheduler" );
-
/* XXX check all fields are touched */
api->thread = created;
_POSIX_Threads_Initialize_attributes( &api->Attributes );
@@ -253,7 +251,6 @@ static void _POSIX_Threads_Delete_extension(
api = deleted->API_Extensions[ THREAD_API_POSIX ];
- _ISR_lock_Destroy( &api->Scheduler_lock );
_Thread_queue_Destroy( &api->Join_List );
}
@@ -281,13 +278,13 @@ static void _POSIX_Threads_Terminate_extension(
_Thread_Enable_dispatch();
- _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+ _Thread_State_acquire( executing, &lock_context );
if ( api->schedpolicy == SCHED_SPORADIC ) {
_Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
}
- _POSIX_Threads_Scheduler_release( api, &lock_context );
+ _Thread_State_release( executing, &lock_context );
}
/*
diff --git a/cpukit/posix/src/pthreadgetattrnp.c b/cpukit/posix/src/pthreadgetattrnp.c
index f71819f..57c5318 100644
--- a/cpukit/posix/src/pthreadgetattrnp.c
+++ b/cpukit/posix/src/pthreadgetattrnp.c
@@ -26,32 +26,29 @@
#include <rtems/score/threadimpl.h>
int pthread_getattr_np(
- pthread_t id,
+ pthread_t thread,
pthread_attr_t *attr
)
{
- Objects_Locations location;
- POSIX_API_Control *api;
- Thread_Control *the_thread;
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ POSIX_API_Control *api;
- if ( !attr )
+ if ( attr == NULL ) {
return EINVAL;
+ }
- the_thread = _Thread_Get( id, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- api = the_thread->API_Extensions[ THREAD_API_POSIX ];
- _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
- _Objects_Put( &the_thread->Object );
- return 0;
+ the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
+ if ( the_thread == NULL ) {
+ return ESRCH;
}
- return ESRCH;
+ _Thread_State_acquire_critical( the_thread, &lock_context );
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
+
+ _Thread_State_release( the_thread, &lock_context );
+ return 0;
}
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index d3fa9d4..d769d8a 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -34,35 +34,29 @@ int pthread_getschedparam(
struct sched_param *param
)
{
- Objects_Locations location;
- POSIX_API_Control *api;
- Thread_Control *the_thread;
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ POSIX_API_Control *api;
- if ( !policy || !param )
+ if ( policy == NULL || param == NULL ) {
return EINVAL;
+ }
- the_thread = _Thread_Get( thread, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- api = the_thread->API_Extensions[ THREAD_API_POSIX ];
- if ( policy )
- *policy = api->schedpolicy;
- if ( param ) {
- *param = api->schedparam;
- param->sched_priority =
- _POSIX_Priority_From_core( the_thread->current_priority );
- }
- _Objects_Put( &the_thread->Object );
- return 0;
+ the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
+ if ( the_thread == NULL ) {
+ return ESRCH;
}
- return ESRCH;
+ _Thread_State_acquire_critical( the_thread, &lock_context );
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ *policy = api->schedpolicy;
+ *param = api->schedparam;
+ param->sched_priority = _POSIX_Priority_From_core(
+ the_thread->current_priority
+ );
+ _Thread_State_release( the_thread, &lock_context );
+ return 0;
}
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index 57a2bc8..8f3cc20 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -38,11 +38,11 @@ int pthread_setschedparam(
)
{
Thread_Control *the_thread;
+ Per_CPU_Control *cpu_self;
POSIX_API_Control *api;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
- Objects_Locations location;
- int rc;
+ int eno;
Priority_Control unused;
ISR_lock_Context lock_context;
Priority_Control new_priority;
@@ -50,79 +50,76 @@ int pthread_setschedparam(
/*
* Check all the parameters
*/
- if ( !param )
+
+ if ( param == NULL ) {
return EINVAL;
+ }
- rc = _POSIX_Thread_Translate_sched_param(
+ eno = _POSIX_Thread_Translate_sched_param(
policy,
param,
&budget_algorithm,
&budget_callout
);
- if ( rc )
- return rc;
+ if ( eno != 0 ) {
+ return eno;
+ }
+
+ the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
+
+ if ( the_thread == NULL ) {
+ return ESRCH;
+ }
/*
* Actually change the scheduling policy and parameters
*/
- the_thread = _Thread_Get( thread, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
- _POSIX_Threads_Scheduler_acquire( api, &lock_context );
-
- if ( api->schedpolicy == SCHED_SPORADIC ) {
- _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
- }
-
- api->schedpolicy = policy;
- api->schedparam = *param;
- api->Attributes.schedpolicy = policy;
- api->Attributes.schedparam = *param;
-
- the_thread->budget_algorithm = budget_algorithm;
- the_thread->budget_callout = budget_callout;
-
- switch ( policy ) {
- case SCHED_OTHER:
- case SCHED_FIFO:
- case SCHED_RR:
- the_thread->cpu_time_budget =
- rtems_configuration_get_ticks_per_timeslice();
- new_priority =
- _POSIX_Priority_To_core( api->schedparam.sched_priority );
- break;
-
- case SCHED_SPORADIC:
- api->ss_high_priority = api->schedparam.sched_priority;
- break;
- }
-
- _POSIX_Threads_Scheduler_release( api, &lock_context );
-
- switch ( policy ) {
- case SCHED_OTHER:
- case SCHED_FIFO:
- case SCHED_RR:
- _Thread_Set_priority( the_thread, new_priority, &unused, true );
- break;
-
- case SCHED_SPORADIC:
- _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer );
- break;
- }
-
- _Objects_Put( &the_thread->Object );
- return 0;
-
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
+
+ cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+ _Thread_State_acquire_critical( the_thread, &lock_context );
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( api->schedpolicy == SCHED_SPORADIC ) {
+ _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+ }
+
+ api->schedpolicy = policy;
+ api->schedparam = *param;
+ api->Attributes.schedpolicy = policy;
+ api->Attributes.schedparam = *param;
+
+ the_thread->budget_algorithm = budget_algorithm;
+ the_thread->budget_callout = budget_callout;
+
+ switch ( policy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ the_thread->cpu_time_budget =
+ rtems_configuration_get_ticks_per_timeslice();
+ new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
+ break;
+
+ case SCHED_SPORADIC:
+ api->ss_high_priority = api->schedparam.sched_priority;
+ break;
+ }
+
+ _Thread_State_release( the_thread, &lock_context );
+
+ switch ( policy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ _Thread_Set_priority( the_thread, new_priority, &unused, true );
+ break;
+
+ case SCHED_SPORADIC:
+ _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer );
break;
}
- return ESRCH;
+ _Thread_Dispatch_enable( cpu_self );
+ return 0;
}
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 18e0f54..b8e0e00 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -719,7 +719,12 @@ struct _Thread_Control {
* the following fields
*
* - POSIX_API_Control::Attributes,
+ * - POSIX_API_Control::schedparam,
+ * - POSIX_API_Control::schedpolicy,
* - RTEMS_API_Control::Signal,
+ * - Thread_Control::budget_algorithm,
+ * - Thread_Control::budget_callout,
+ * - Thread_Control::cpu_time_budget,
* - Thread_Control::current_state,
* - Thread_Control::Post_switch_actions,
* - Thread_Control::Scheduler::control, and
--
1.8.4.5
More information about the devel
mailing list