rtems: Add task get/set scheduler

This commit is contained in:
Sebastian Huber
2014-04-09 10:09:39 +02:00
parent 1b67535d86
commit 27270b0d6c
6 changed files with 257 additions and 1 deletions

View File

@@ -94,6 +94,7 @@ librtems_a_SOURCES += src/taskcreate.c
librtems_a_SOURCES += src/taskdelete.c librtems_a_SOURCES += src/taskdelete.c
librtems_a_SOURCES += src/taskgetaffinity.c librtems_a_SOURCES += src/taskgetaffinity.c
librtems_a_SOURCES += src/taskgetnote.c librtems_a_SOURCES += src/taskgetnote.c
librtems_a_SOURCES += src/taskgetscheduler.c
librtems_a_SOURCES += src/taskident.c librtems_a_SOURCES += src/taskident.c
librtems_a_SOURCES += src/taskinitusers.c librtems_a_SOURCES += src/taskinitusers.c
librtems_a_SOURCES += src/taskissuspended.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/tasksetaffinity.c
librtems_a_SOURCES += src/tasksetnote.c librtems_a_SOURCES += src/tasksetnote.c
librtems_a_SOURCES += src/tasksetpriority.c librtems_a_SOURCES += src/tasksetpriority.c
librtems_a_SOURCES += src/tasksetscheduler.c
librtems_a_SOURCES += src/taskstart.c librtems_a_SOURCES += src/taskstart.c
librtems_a_SOURCES += src/tasksuspend.c librtems_a_SOURCES += src/tasksuspend.c
librtems_a_SOURCES += src/taskwakeafter.c librtems_a_SOURCES += src/taskwakeafter.c

View File

@@ -541,6 +541,41 @@ rtems_status_code rtems_task_set_affinity(
); );
#endif #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 * @brief RTEMS Get Self Task Id
* *

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* 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 <rtems/rtems/tasks.h>
#include <rtems/score/schedulerimpl.h>
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;
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* 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 <rtems/rtems/tasks.h>
#include <rtems/score/schedulerimpl.h>
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;
}

View File

@@ -451,6 +451,24 @@ RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get(
return &_Scheduler_Table[ 0 ]; 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 ) RTEMS_INLINE_ROUTINE Objects_Id _Scheduler_Build_id( uint32_t scheduler_index )
{ {
return _Objects_Build_id( return _Objects_Build_id(
@@ -474,6 +492,13 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Get_by_id(
return index < _Scheduler_Count; 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 #ifdef __cplusplus

View File

@@ -102,6 +102,81 @@ static void test_task_get_set_affinity(void)
#endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */ #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) static void test_scheduler_ident(void)
{ {
rtems_status_code sc; rtems_status_code sc;
@@ -184,6 +259,7 @@ static void Init(rtems_task_argument arg)
rtems_resource_snapshot_take(&snapshot); rtems_resource_snapshot_take(&snapshot);
test_task_get_set_affinity(); test_task_get_set_affinity();
test_task_get_set_scheduler();
test_scheduler_ident(); test_scheduler_ident();
test_scheduler_get_processors(); test_scheduler_get_processors();
@@ -198,7 +274,7 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM #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 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION