[PATCH 04/12] posix: Use a dedicated lock for scheduler changes
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Apr 8 06:49:19 UTC 2016
Update #2555.
---
cpukit/posix/include/rtems/posix/pthreadimpl.h | 17 +++++++
cpukit/posix/include/rtems/posix/threadsup.h | 3 ++
cpukit/posix/src/pthread.c | 65 ++++++++++++++++----------
cpukit/posix/src/pthreadcreate.c | 4 +-
cpukit/posix/src/pthreadsetschedparam.c | 34 ++++++++------
5 files changed, 83 insertions(+), 40 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index 42f10b0..ef5821e 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -223,6 +223,23 @@ 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 7cd2354..93ba2c1 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -19,6 +19,7 @@
#define _RTEMS_POSIX_THREADSUP_H
#include <rtems/score/coresem.h>
+#include <rtems/score/isrlock.h>
#include <rtems/score/thread.h>
#include <rtems/score/threadq.h>
#include <rtems/score/watchdog.h>
@@ -51,6 +52,8 @@ 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 12f02df..f3d45c9 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -106,39 +106,37 @@ static bool _POSIX_Threads_Sporadic_budget_TSR_filter(
*/
void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
{
- uint32_t ticks;
POSIX_API_Control *api;
Thread_Control *the_thread;
- ISR_Level level;
+ ISR_lock_Context lock_context;
+ Priority_Control new_priority;
api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
the_thread = api->thread;
- /* ticks is guaranteed to be at least one */
- ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
+ _POSIX_Threads_Scheduler_acquire( api, &lock_context );
- the_thread->cpu_time_budget = ticks;
+ the_thread->cpu_time_budget =
+ _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
+
+ _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+ _Watchdog_Per_CPU_insert_relative(
+ &api->Sporadic_timer,
+ _Per_CPU_Get(),
+ _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period )
+ );
+
+ new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
+
+ _POSIX_Threads_Scheduler_acquire( api, &lock_context );
_Thread_Change_priority(
the_thread,
- _POSIX_Priority_To_core( api->schedparam.sched_priority ),
+ new_priority,
NULL,
_POSIX_Threads_Sporadic_budget_TSR_filter,
true
);
-
- /* ticks is guaranteed to be at least one */
- ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period );
-
- _Thread_Disable_dispatch();
- _ISR_Disable( level );
- _Watchdog_Per_CPU_insert_relative(
- &api->Sporadic_timer,
- _Per_CPU_Get(),
- ticks
- );
- _ISR_Enable( level );
- _Thread_Unnest_dispatch();
}
static bool _POSIX_Threads_Sporadic_budget_callout_filter(
@@ -202,6 +200,8 @@ 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 );
@@ -244,12 +244,26 @@ static bool _POSIX_Threads_Create_extension(
return true;
}
+static void _POSIX_Threads_Delete_extension(
+ Thread_Control *executing,
+ Thread_Control *deleted
+)
+{
+ POSIX_API_Control *api;
+
+ api = deleted->API_Extensions[ THREAD_API_POSIX ];
+
+ _ISR_lock_Destroy( &api->Scheduler_lock );
+ _Thread_queue_Destroy( &api->Join_List );
+}
+
static void _POSIX_Threads_Terminate_extension(
Thread_Control *executing
)
{
Thread_Control *the_thread;
POSIX_API_Control *api;
+ ISR_lock_Context lock_context;
void **value_ptr;
api = executing->API_Extensions[ THREAD_API_POSIX ];
@@ -265,12 +279,15 @@ static void _POSIX_Threads_Terminate_extension(
*(void **)the_thread->Wait.return_argument = value_ptr;
}
- if ( api->schedpolicy == SCHED_SPORADIC )
- _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+ _Thread_Enable_dispatch();
- _Thread_queue_Destroy( &api->Join_List );
+ _POSIX_Threads_Scheduler_acquire( api, &lock_context );
- _Thread_Enable_dispatch();
+ if ( api->schedpolicy == SCHED_SPORADIC ) {
+ _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+ }
+
+ _POSIX_Threads_Scheduler_release( api, &lock_context );
}
/*
@@ -296,7 +313,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
{ _POSIX_Threads_Create_extension, /* create */
NULL, /* start */
NULL, /* restart */
- NULL, /* delete */
+ _POSIX_Threads_Delete_extension, /* delete */
NULL, /* switch */
NULL, /* begin */
_POSIX_Threads_Exitted_extension, /* exitted */
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index fc07b1f..2533345 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -247,13 +247,13 @@ int pthread_create(
#endif
if ( schedpolicy == SCHED_SPORADIC ) {
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
_Watchdog_Per_CPU_insert_relative(
&api->Sporadic_timer,
_Per_CPU_Get(),
_Timespec_To_ticks( &api->schedparam.sched_ss_repl_period )
);
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
}
_Thread_Enable_dispatch();
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index c9560f5..57a2bc8 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -44,7 +44,8 @@ int pthread_setschedparam(
Objects_Locations location;
int rc;
Priority_Control unused;
- ISR_Level level;
+ ISR_lock_Context lock_context;
+ Priority_Control new_priority;
/*
* Check all the parameters
@@ -70,10 +71,10 @@ int pthread_setschedparam(
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+
if ( api->schedpolicy == SCHED_SPORADIC ) {
- _ISR_Disable( level );
_Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
- _ISR_Enable( level );
}
api->schedpolicy = policy;
@@ -84,26 +85,31 @@ int pthread_setschedparam(
the_thread->budget_algorithm = budget_algorithm;
the_thread->budget_callout = budget_callout;
- switch ( api->schedpolicy ) {
+ switch ( policy ) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
the_thread->cpu_time_budget =
rtems_configuration_get_ticks_per_timeslice();
-
- _Thread_Set_priority(
- the_thread,
- _POSIX_Priority_To_core( api->schedparam.sched_priority ),
- &unused,
- true
- );
+ new_priority =
+ _POSIX_Priority_To_core( api->schedparam.sched_priority );
break;
case SCHED_SPORADIC:
api->ss_high_priority = api->schedparam.sched_priority;
- _ISR_Disable( level );
- _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
- _ISR_Enable( level );
+ 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;
}
--
1.8.4.5
More information about the devel
mailing list