From 27270b0d6c1ec6ff7bca2ffc5a8c25b45d260165 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 9 Apr 2014 10:09:39 +0200 Subject: rtems: Add task get/set scheduler --- cpukit/rtems/Makefile.am | 2 + cpukit/rtems/include/rtems/rtems/tasks.h | 35 +++++++++++ cpukit/rtems/src/taskgetscheduler.c | 60 ++++++++++++++++++ cpukit/rtems/src/tasksetscheduler.c | 58 ++++++++++++++++++ cpukit/score/include/rtems/score/schedulerimpl.h | 25 ++++++++ testsuites/sptests/spscheduler01/init.c | 78 +++++++++++++++++++++++- 6 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 cpukit/rtems/src/taskgetscheduler.c create mode 100644 cpukit/rtems/src/tasksetscheduler.c diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index ff3e60588f..4b84fa1343 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -94,6 +94,7 @@ librtems_a_SOURCES += src/taskcreate.c librtems_a_SOURCES += src/taskdelete.c librtems_a_SOURCES += src/taskgetaffinity.c librtems_a_SOURCES += src/taskgetnote.c +librtems_a_SOURCES += src/taskgetscheduler.c librtems_a_SOURCES += src/taskident.c librtems_a_SOURCES += src/taskinitusers.c librtems_a_SOURCES += src/taskissuspended.c @@ -104,6 +105,7 @@ librtems_a_SOURCES += src/taskself.c librtems_a_SOURCES += src/tasksetaffinity.c librtems_a_SOURCES += src/tasksetnote.c librtems_a_SOURCES += src/tasksetpriority.c +librtems_a_SOURCES += src/tasksetscheduler.c librtems_a_SOURCES += src/taskstart.c librtems_a_SOURCES += src/tasksuspend.c librtems_a_SOURCES += src/taskwakeafter.c diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index 21c0166981..9101d9c063 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -541,6 +541,41 @@ rtems_status_code rtems_task_set_affinity( ); #endif +/** + * @brief Gets the scheduler of a task. + * + * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the + * executing task. + * @param[out] scheduler_id Identifier of the scheduler. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a scheduler_id parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task identifier. + */ +rtems_status_code rtems_task_get_scheduler( + rtems_id id, + rtems_id *scheduler_id +); + +/** + * @brief Sets the scheduler of a task. + * + * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the + * executing task. + * @param[in] scheduler_id Identifier of the scheduler. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier. + * @retval RTEMS_INCORRECT_STATE The task is in the wrong state to perform a + * scheduler change. + * + * @see rtems_scheduler_ident(). + */ +rtems_status_code rtems_task_set_scheduler( + rtems_id id, + rtems_id scheduler_id +); + /** * @brief RTEMS Get Self Task Id * diff --git a/cpukit/rtems/src/taskgetscheduler.c b/cpukit/rtems/src/taskgetscheduler.c new file mode 100644 index 0000000000..711109304d --- /dev/null +++ b/cpukit/rtems/src/taskgetscheduler.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +rtems_status_code rtems_task_get_scheduler( + rtems_id id, + 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( 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; +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT; + break; +#endif + default: + sc = RTEMS_INVALID_ID; + break; + } + } else { + sc = RTEMS_INVALID_ADDRESS; + } + + return sc; +} diff --git a/cpukit/rtems/src/tasksetscheduler.c b/cpukit/rtems/src/tasksetscheduler.c new file mode 100644 index 0000000000..42c08bbb80 --- /dev/null +++ b/cpukit/rtems/src/tasksetscheduler.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +rtems_status_code rtems_task_set_scheduler( + rtems_id id, + rtems_id scheduler_id +) +{ + rtems_status_code sc; + const Scheduler_Control *scheduler; + + if ( _Scheduler_Get_by_id( scheduler_id, &scheduler ) ) { + Thread_Control *the_thread; + Objects_Locations location; + bool ok; + + the_thread = _Thread_Get( id, &location ); + + switch ( location ) { + case OBJECTS_LOCAL: + ok = _Scheduler_Set( scheduler, the_thread ); + _Objects_Put( &the_thread->Object ); + sc = ok ? RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE; + break; +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT; + break; +#endif + default: + sc = RTEMS_INVALID_ID; + break; + } + } else { + sc = RTEMS_INVALID_ID; + } + + return sc; +} diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 2b8782fe7d..8b80db78c1 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -451,6 +451,24 @@ RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get( return &_Scheduler_Table[ 0 ]; } +RTEMS_INLINE_ROUTINE bool _Scheduler_Set( + const Scheduler_Control *scheduler, + Thread_Control *the_thread +) +{ + bool ok; + + (void) scheduler; + + if ( _States_Is_dormant( the_thread->current_state ) ) { + ok = true; + } else { + ok = false; + } + + return ok; +} + RTEMS_INLINE_ROUTINE Objects_Id _Scheduler_Build_id( uint32_t scheduler_index ) { return _Objects_Build_id( @@ -474,6 +492,13 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Get_by_id( return index < _Scheduler_Count; } +RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index( + const Scheduler_Control *scheduler +) +{ + return (uint32_t) (scheduler - &_Scheduler_Table[ 0 ]); +} + /** @} */ #ifdef __cplusplus diff --git a/testsuites/sptests/spscheduler01/init.c b/testsuites/sptests/spscheduler01/init.c index 655568da15..6c19abcfd0 100644 --- a/testsuites/sptests/spscheduler01/init.c +++ b/testsuites/sptests/spscheduler01/init.c @@ -102,6 +102,81 @@ static void test_task_get_set_affinity(void) #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */ } +static void task(rtems_task_argument arg) +{ + (void) arg; + + rtems_test_assert(0); +} + +static void test_task_get_set_scheduler(void) +{ + rtems_status_code sc; + rtems_id self_id = rtems_task_self(); + rtems_name name = BLUE; + rtems_id scheduler_id; + rtems_id scheduler_by_name; + rtems_id task_id; + + sc = rtems_scheduler_ident(name, &scheduler_by_name); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_get_scheduler(RTEMS_SELF, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_task_get_scheduler(invalid_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(self_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + sc = rtems_task_set_scheduler(invalid_id, scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_task_set_scheduler(self_id, invalid_id); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_task_set_scheduler(self_id, scheduler_id); + rtems_test_assert(sc == RTEMS_INCORRECT_STATE); + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(task_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + sc = rtems_task_set_scheduler(task_id, scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(task_id, task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_scheduler(task_id, scheduler_id); + rtems_test_assert(sc == RTEMS_INCORRECT_STATE); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + static void test_scheduler_ident(void) { rtems_status_code sc; @@ -184,6 +259,7 @@ static void Init(rtems_task_argument arg) rtems_resource_snapshot_take(&snapshot); test_task_get_set_affinity(); + test_task_get_set_scheduler(); test_scheduler_ident(); test_scheduler_get_processors(); @@ -198,7 +274,7 @@ static void Init(rtems_task_argument arg) #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM -#define CONFIGURE_MAXIMUM_TASKS 1 +#define CONFIGURE_MAXIMUM_TASKS 2 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION -- cgit v1.2.3