diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-08 22:22:46 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-22 14:44:56 +0200 |
commit | 9bfad8cd519f17cbb26a672868169fcd304d5bd5 (patch) | |
tree | 3a07add3fb0cdf47fe4d5c9432ad931429c05d65 /testsuites | |
parent | score: Move _RBTree_Find() (diff) | |
download | rtems-9bfad8cd519f17cbb26a672868169fcd304d5bd5.tar.bz2 |
score: Add thread priority to scheduler nodes
The thread priority is manifest in two independent areas. One area is
the user visible thread priority along with a potential thread queue.
The other is the scheduler. Currently, a thread priority update via
_Thread_Change_priority() first updates the user visble thread priority
and the thread queue, then the scheduler is notified if necessary. The
priority is passed to the scheduler via a local variable. A generation
counter ensures that the scheduler discards out-of-date priorities.
This use of a local variable ties the update in these two areas close
together. For later enhancements and the OMIP locking protocol
implementation we need more flexibility. Add a thread priority
information block to Scheduler_Node and synchronize priority value
updates via a sequence lock on SMP configurations.
Update #2556.
Diffstat (limited to 'testsuites')
-rw-r--r-- | testsuites/smptests/smpscheduler03/init.c | 25 | ||||
-rw-r--r-- | testsuites/sptests/spintrcritical23/init.c | 57 |
2 files changed, 21 insertions, 61 deletions
diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c index d6a145c3d5..f610b62532 100644 --- a/testsuites/smptests/smpscheduler03/init.c +++ b/testsuites/smptests/smpscheduler03/init.c @@ -187,7 +187,7 @@ static void test_change_priority(void) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } -static Thread_Control *change_priority_op( +static Thread_Control *update_priority_op( Thread_Control *thread, Priority_Control new_priority, bool prepend_it @@ -197,18 +197,17 @@ static Thread_Control *change_priority_op( ISR_lock_Context state_lock_context; ISR_lock_Context scheduler_lock_context; Thread_Control *needs_help; + Scheduler_Node *node; + + thread->current_priority = new_priority; + node = _Scheduler_Thread_get_node(thread); + _Scheduler_Node_set_priority(node, new_priority, prepend_it); _Thread_State_acquire( thread, &state_lock_context ); scheduler = _Scheduler_Get( thread ); _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context ); - thread->current_priority = new_priority; - needs_help = (*scheduler->Operations.change_priority)( - scheduler, - thread, - new_priority, - prepend_it - ); + needs_help = (*scheduler->Operations.update_priority)( scheduler, thread); _Scheduler_Release_critical( scheduler, &scheduler_lock_context ); _Thread_State_release( thread, &state_lock_context ); @@ -216,7 +215,7 @@ static Thread_Control *change_priority_op( return needs_help; } -static void test_case_change_priority_op( +static void test_case_update_priority_op( Thread_Control *executing, Scheduler_SMP_Node *executing_node, Thread_Control *other, @@ -244,7 +243,7 @@ static void test_case_change_priority_op( } rtems_test_assert(executing_node->state == start_state); - needs_help = change_priority_op(executing, prio, prepend_it); + needs_help = update_priority_op(executing, prio, prepend_it); rtems_test_assert(executing_node->state == new_state); if (start_state != new_state) { @@ -269,7 +268,7 @@ static void test_case_change_priority_op( _Thread_Dispatch_enable( cpu_self ); } -static void test_change_priority_op(void) +static void test_update_priority_op(void) { rtems_status_code sc; rtems_id task_id; @@ -289,7 +288,7 @@ static void test_change_priority_op(void) for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) { for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) { - test_case_change_priority_op( + test_case_update_priority_op( executing, executing_node, other, @@ -555,7 +554,7 @@ static void test_unblock_op(void) static void tests(void) { test_change_priority(); - test_change_priority_op(); + test_update_priority_op(); test_yield_op(); test_unblock_op(); } diff --git a/testsuites/sptests/spintrcritical23/init.c b/testsuites/sptests/spintrcritical23/init.c index 7b0078657b..b4856749ff 100644 --- a/testsuites/sptests/spintrcritical23/init.c +++ b/testsuites/sptests/spintrcritical23/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -22,7 +22,7 @@ #include <string.h> #include <rtems.h> -#include <rtems/score/schedulerpriority.h> +#include <rtems/score/schedulerpriorityimpl.h> #include <rtems/score/threadimpl.h> const char rtems_test_name[] = "SPINTRCRITICAL 23"; @@ -30,37 +30,14 @@ const char rtems_test_name[] = "SPINTRCRITICAL 23"; typedef struct { RTEMS_INTERRUPT_LOCK_MEMBER(lock) rtems_id task_id; - Thread_Control *tcb; + Scheduler_priority_Node *scheduler_node; rtems_task_priority priority_task; rtems_task_priority priority_interrupt; - uint32_t priority_generation; - Scheduler_priority_Node scheduler_node; bool done; } test_context; static test_context ctx_instance; -static Thread_Control *get_tcb(rtems_id id) -{ - ISR_lock_Context lock_context; - Thread_Control *tcb; - - tcb = _Thread_Get(id, &lock_context); - rtems_test_assert(tcb != NULL); - _ISR_lock_ISR_enable(&lock_context); - - return tcb; -} - -static bool scheduler_node_unchanged(const test_context *ctx) -{ - return memcmp( - &ctx->scheduler_node, - ctx->tcb->Scheduler.node, - sizeof(ctx->scheduler_node) - ) == 0; -} - static void change_priority(rtems_id timer, void *arg) { /* The arg is NULL */ @@ -69,8 +46,8 @@ static void change_priority(rtems_id timer, void *arg) rtems_interrupt_lock_acquire(&ctx->lock, &lock_context); if ( - ctx->priority_generation != ctx->tcb->priority_generation - && scheduler_node_unchanged(ctx) + ctx->scheduler_node->Ready_queue.current_priority + != ctx->scheduler_node->Base.Priority.value ) { rtems_task_priority priority_interrupt; rtems_task_priority priority_task; @@ -112,12 +89,6 @@ static bool test_body(void *arg) priority_interrupt = 1 + (priority_task + 1) % 3; ctx->priority_task = priority_task; ctx->priority_interrupt = priority_interrupt; - ctx->priority_generation = ctx->tcb->priority_generation; - memcpy( - &ctx->scheduler_node, - ctx->tcb->Scheduler.node, - sizeof(ctx->scheduler_node) - ); rtems_interrupt_lock_release(&ctx->lock, &lock_context); sc = rtems_task_set_priority( @@ -144,24 +115,14 @@ static bool test_body(void *arg) static void Init(rtems_task_argument arg) { test_context *ctx = &ctx_instance; - rtems_status_code sc; TEST_BEGIN(); rtems_interrupt_lock_initialize(&ctx->lock, "Test"); ctx->priority_task = 1; - - sc = rtems_task_create( - rtems_build_name('T', 'E', 'S', 'T'), - ctx->priority_task, - RTEMS_MINIMUM_STACK_SIZE, - RTEMS_DEFAULT_MODES, - RTEMS_DEFAULT_ATTRIBUTES, - &ctx->task_id - ); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); - - ctx->tcb = get_tcb(ctx->task_id); + ctx->task_id = rtems_task_self(); + ctx->scheduler_node = + _Scheduler_priority_Thread_get_node(_Thread_Get_executing()); interrupt_critical_section_test(test_body, ctx, change_priority); rtems_test_assert(ctx->done); @@ -175,7 +136,7 @@ static void Init(rtems_task_argument arg) #define CONFIGURE_MICROSECONDS_PER_TICK 1000 -#define CONFIGURE_MAXIMUM_TASKS 2 +#define CONFIGURE_MAXIMUM_TASKS 1 #define CONFIGURE_MAXIMUM_TIMERS 1 #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 |