From 8123cae864579219e5003a67b451ca4cc07d998b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 8 Sep 2016 15:32:22 +0200 Subject: rtems: Add rtems_task_get_priority() Update #2556. Update #2784. --- cpukit/rtems/Makefile.am | 1 + cpukit/rtems/include/rtems/rtems/tasks.h | 29 ++++++++ cpukit/rtems/src/taskgetpriority.c | 77 ++++++++++++++++++++++ testsuites/smptests/smpmutex01/init.c | 16 +++++ testsuites/sptests/spscheduler01/init.c | 39 +++++++++++ testsuites/sptests/spscheduler01/spscheduler01.doc | 10 +++ 6 files changed, 172 insertions(+) create mode 100644 cpukit/rtems/src/taskgetpriority.c diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index 0a452c8121..4be426620c 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -88,6 +88,7 @@ librtems_a_SOURCES += src/tasks.c librtems_a_SOURCES += src/taskcreate.c librtems_a_SOURCES += src/taskdelete.c librtems_a_SOURCES += src/taskgetaffinity.c +librtems_a_SOURCES += src/taskgetpriority.c librtems_a_SOURCES += src/taskgetscheduler.c librtems_a_SOURCES += src/taskident.c librtems_a_SOURCES += src/taskinitusers.c diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index e690e60557..0eaaeca4a3 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -319,6 +319,35 @@ rtems_status_code rtems_task_set_priority( rtems_task_priority *old_priority ); +/** + * @brief Gets the current priority of the specified task with respect to the + * specified scheduler instance. + * + * The current priority reflects temporary priority adjustments due to locking + * protocols, the rate-monotonic period objects on some schedulers and other + * mechanisms. + * + * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select + * the executing task. + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[out] priority Returns the current priority of the specified task with + * respect to the specified scheduler instance. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks. + * @retval RTEMS_INVALID_ADDRESS The priority parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier. + * @retval RTEMS_NOT_DEFINED The task has no priority within the specified + * scheduler instance. This error is only possible on SMP configurations. + * + * @see rtems_scheduler_ident(). + */ +rtems_status_code rtems_task_get_priority( + rtems_id task_id, + rtems_id scheduler_id, + rtems_task_priority *priority +); + /** * @brief RTEMS Start Task * diff --git a/cpukit/rtems/src/taskgetpriority.c b/cpukit/rtems/src/taskgetpriority.c new file mode 100644 index 0000000000..b6800e2133 --- /dev/null +++ b/cpukit/rtems/src/taskgetpriority.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 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 +#include + +rtems_status_code rtems_task_get_priority( + rtems_id task_id, + rtems_id scheduler_id, + rtems_task_priority *priority +) +{ + Thread_Control *the_thread; + Thread_queue_Context queue_context; + const Scheduler_Control *scheduler; + const Scheduler_Node *scheduler_node; + Priority_Control core_priority; + + if ( priority == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) { + return RTEMS_INVALID_ID; + } + + _Thread_queue_Context_initialize( &queue_context ); + the_thread = _Thread_Get( task_id, + &queue_context.Lock_context.Lock_context + ); + + if ( the_thread == NULL ) { +#if defined(RTEMS_MULTIPROCESSING) + if ( _Thread_MP_Is_remote( task_id ) ) { + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; + } +#endif + + return RTEMS_INVALID_ID; + } + + scheduler_node = _Thread_Scheduler_get_node_by_index( + the_thread, + _Scheduler_Get_index( scheduler ) + ); + + _Thread_Wait_acquire_critical( the_thread, &queue_context ); + +#if defined(RTEMS_SMP) + if ( _Priority_Is_empty( &scheduler_node->Wait.Priority ) ) { + _Thread_Wait_release( the_thread, &queue_context ); + return RTEMS_NOT_DEFINED; + } +#endif + + core_priority = _Priority_Get_priority( &scheduler_node->Wait.Priority ); + + _Thread_Wait_release( the_thread, &queue_context ); + *priority = _RTEMS_Priority_From_core( scheduler, core_priority ); + return RTEMS_SUCCESSFUL; +} diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c index c6b1b48c9d..d88b7b8113 100644 --- a/testsuites/smptests/smpmutex01/init.c +++ b/testsuites/smptests/smpmutex01/init.c @@ -57,6 +57,21 @@ typedef struct { static test_context test_instance; +static void test_task_get_priority_not_defined(test_context *ctx) +{ + rtems_status_code sc; + rtems_id scheduler_id; + rtems_task_priority priority; + + sc = rtems_scheduler_ident(SCHED_B, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + priority = 0; + sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, &priority); + rtems_test_assert(sc == RTEMS_NOT_DEFINED); + rtems_test_assert(priority == 0); +} + static void start_task( test_context *ctx, task_id id, @@ -340,6 +355,7 @@ static void test(void) test_context *ctx = &test_instance; test_init(ctx); + test_task_get_priority_not_defined(ctx); test_simple_inheritance(ctx); test_dequeue_order_one_scheduler_instance(ctx); test_simple_boosting(ctx); diff --git a/testsuites/sptests/spscheduler01/init.c b/testsuites/sptests/spscheduler01/init.c index bb0c16def6..d6213c6bcc 100644 --- a/testsuites/sptests/spscheduler01/init.c +++ b/testsuites/sptests/spscheduler01/init.c @@ -411,6 +411,44 @@ static void test_scheduler_get_processors(void) #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */ } +static void test_task_get_priority(void) +{ + rtems_status_code sc; + rtems_id scheduler_id; + rtems_task_priority priority; + rtems_task_priority priority_2; + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + priority = 0; + + sc = rtems_task_get_priority(RTEMS_SELF, invalid_id, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 0); + + sc = rtems_task_get_priority(invalid_id, scheduler_id, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 0); + + sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority != 0); + + priority_2 = 0; + sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, &priority_2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority_2 == priority); + + priority_2 = 0; + sc = rtems_task_get_priority(rtems_task_self(), scheduler_id, &priority_2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority_2 == priority); +} + static void Init(rtems_task_argument arg) { rtems_resource_snapshot snapshot; @@ -425,6 +463,7 @@ static void Init(rtems_task_argument arg) test_task_get_set_scheduler(); test_scheduler_ident(); test_scheduler_get_processors(); + test_task_get_priority(); rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); diff --git a/testsuites/sptests/spscheduler01/spscheduler01.doc b/testsuites/sptests/spscheduler01/spscheduler01.doc index d398315b13..2182928722 100644 --- a/testsuites/sptests/spscheduler01/spscheduler01.doc +++ b/testsuites/sptests/spscheduler01/spscheduler01.doc @@ -6,8 +6,18 @@ directives: - rtems_task_get_affinity() - rtems_task_set_affinity() + - rtems_task_get_scheduler() + - rtems_task_set_scheduler() + - rtems_scheduler_ident() + - rtems_scheduler_get_processor_set() + - rtems_task_get_priority() concepts: - Ensure that the task set/get affinity functions work on uni-processor configurations. + - Ensure that the task set/get scheduler functions work on uni-processor + configurations. + - Ensure that the scheduler functions work on uni-processor configurations. + - Ensure that the task get priority function works on uni-processor + configurations. -- cgit v1.2.3