mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-25 08:59:32 +08:00
score: _Thread_Set_life_protection()
Enable usage of _Thread_Set_life_protection() in thread dispatch critical sections. This can be used to enable the thread life-protection with thread dispatching disabled and then enable thread dispatching.
This commit is contained in:
@@ -373,8 +373,6 @@ bool _Thread_Set_life_protection( bool protect )
|
||||
) {
|
||||
_Thread_Disable_dispatch();
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
_Assert_Not_reached();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -385,8 +383,6 @@ bool _Thread_Set_life_protection( bool protect )
|
||||
_Thread_Disable_dispatch();
|
||||
_Thread_Start_life_change_for_executing( executing );
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
_Assert_Not_reached();
|
||||
}
|
||||
|
||||
return previous_life_protection;
|
||||
|
||||
@@ -182,7 +182,7 @@ static void test_delete(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void delay_ipi_task(rtems_task_argument arg)
|
||||
static void delay_ipi_task(rtems_task_argument variant)
|
||||
{
|
||||
test_context *ctx = &test_instance;
|
||||
rtems_interrupt_level level;
|
||||
@@ -198,12 +198,24 @@ static void delay_ipi_task(rtems_task_argument arg)
|
||||
*/
|
||||
rtems_counter_delay_nanoseconds(100000000);
|
||||
|
||||
/* We get deleted as a side effect of enabling the thread life protection */
|
||||
if (variant != 0) {
|
||||
_Thread_Disable_dispatch();
|
||||
}
|
||||
|
||||
/*
|
||||
* We get deleted as a side effect of enabling the thread life protection or
|
||||
* later if we enable the thread dispatching.
|
||||
*/
|
||||
_Thread_Set_life_protection(true);
|
||||
|
||||
if (variant != 0) {
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
rtems_test_assert(0);
|
||||
}
|
||||
|
||||
static void test_set_life_protection(void)
|
||||
static void test_set_life_protection(rtems_task_argument variant)
|
||||
{
|
||||
test_context *ctx = &test_instance;
|
||||
rtems_status_code sc;
|
||||
@@ -222,7 +234,7 @@ static void test_set_life_protection(void)
|
||||
);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
sc = rtems_task_start(id, delay_ipi_task, 0);
|
||||
sc = rtems_task_start(id, delay_ipi_task, variant);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
_SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
|
||||
@@ -301,7 +313,8 @@ static void Init(rtems_task_argument arg)
|
||||
if (rtems_get_processor_count() >= CPU_COUNT) {
|
||||
test_restart();
|
||||
test_delete();
|
||||
test_set_life_protection();
|
||||
test_set_life_protection(0);
|
||||
test_set_life_protection(1);
|
||||
test_wait_for_execution_stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <rtems.h>
|
||||
#include <rtems/libcsupport.h>
|
||||
|
||||
#include <rtems/score/threadimpl.h>
|
||||
|
||||
#include "tmacros.h"
|
||||
|
||||
#define PRIO_INIT 1
|
||||
@@ -48,6 +50,12 @@ typedef enum {
|
||||
DELETE_1,
|
||||
DELETE_2,
|
||||
DELETE_3,
|
||||
SET_PROTECTION,
|
||||
SET_PROTECTION_DONE,
|
||||
CLEAR_PROTECTION,
|
||||
DELETE_4,
|
||||
DELETE_5,
|
||||
DELETE_6,
|
||||
INVALID
|
||||
} test_state;
|
||||
|
||||
@@ -157,8 +165,17 @@ static void delete_extension(
|
||||
|
||||
assert_priority(PRIO_INIT);
|
||||
|
||||
rtems_test_assert(ctx->current == DELETE_2);
|
||||
ctx->current = DELETE_3;
|
||||
switch (ctx->current) {
|
||||
case DELETE_2:
|
||||
ctx->current = DELETE_3;
|
||||
break;
|
||||
case DELETE_5:
|
||||
ctx->current = DELETE_6;
|
||||
break;
|
||||
default:
|
||||
rtems_test_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void terminate_extension(Thread_Control *executing)
|
||||
@@ -179,6 +196,9 @@ static void terminate_extension(Thread_Control *executing)
|
||||
case DELETE_1:
|
||||
ctx->current = DELETE_2;
|
||||
break;
|
||||
case DELETE_4:
|
||||
ctx->current = DELETE_5;
|
||||
break;
|
||||
default:
|
||||
rtems_test_assert(0);
|
||||
break;
|
||||
@@ -192,6 +212,7 @@ static void worker_task(rtems_task_argument arg)
|
||||
while (true) {
|
||||
test_state state = ctx->current;
|
||||
rtems_status_code sc;
|
||||
bool previous_thread_life_protection;
|
||||
|
||||
switch (state) {
|
||||
case SET_PRIO:
|
||||
@@ -231,6 +252,19 @@ static void worker_task(rtems_task_argument arg)
|
||||
case RESTART_2:
|
||||
assert_priority(PRIO_HIGH);
|
||||
break;
|
||||
case SET_PROTECTION:
|
||||
_Thread_Disable_dispatch();
|
||||
previous_thread_life_protection = _Thread_Set_life_protection(true);
|
||||
rtems_test_assert(!previous_thread_life_protection);
|
||||
_Thread_Enable_dispatch();
|
||||
break;
|
||||
case CLEAR_PROTECTION:
|
||||
_Thread_Disable_dispatch();
|
||||
previous_thread_life_protection = _Thread_Set_life_protection(false);
|
||||
rtems_test_assert(previous_thread_life_protection);
|
||||
ctx->current = DELETE_4;
|
||||
_Thread_Enable_dispatch();
|
||||
break;
|
||||
default:
|
||||
rtems_test_assert(0);
|
||||
break;
|
||||
@@ -255,17 +289,9 @@ static void create_sema(test_context *ctx)
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
static void create_and_start_worker(test_context *ctx)
|
||||
{
|
||||
test_context *ctx = &test_instance;
|
||||
rtems_status_code sc;
|
||||
rtems_resource_snapshot snapshot;
|
||||
|
||||
ctx->main_task_id = rtems_task_self();
|
||||
|
||||
rtems_resource_snapshot_take(&snapshot);
|
||||
|
||||
create_sema(ctx);
|
||||
|
||||
sc = rtems_task_create(
|
||||
rtems_build_name('W', 'O', 'R', 'K'),
|
||||
@@ -279,6 +305,20 @@ static void test(void)
|
||||
|
||||
sc = rtems_task_start(ctx->worker_task_id, worker_task, 0);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
test_context *ctx = &test_instance;
|
||||
rtems_status_code sc;
|
||||
rtems_resource_snapshot snapshot;
|
||||
|
||||
ctx->main_task_id = rtems_task_self();
|
||||
|
||||
rtems_resource_snapshot_take(&snapshot);
|
||||
|
||||
create_sema(ctx);
|
||||
create_and_start_worker(ctx);
|
||||
|
||||
change_state_and_wait(ctx, INIT, SET_PRIO, SET_PRIO_DONE);
|
||||
change_state_and_wait(ctx, SET_PRIO_DONE, DO_OBTAIN_0, OBTAIN_DONE_0);
|
||||
@@ -316,7 +356,17 @@ static void test(void)
|
||||
|
||||
rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
|
||||
|
||||
rtems_test_assert(ctx->current == DELETE_3);
|
||||
create_and_start_worker(ctx);
|
||||
|
||||
change_state_and_wait(ctx, DELETE_3, SET_PROTECTION, SET_PROTECTION_DONE);
|
||||
change_state(ctx, SET_PROTECTION_DONE, CLEAR_PROTECTION, INVALID);
|
||||
|
||||
sc = rtems_task_delete(ctx->worker_task_id);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
|
||||
|
||||
rtems_test_assert(ctx->current == DELETE_6);
|
||||
}
|
||||
|
||||
static void Init(rtems_task_argument arg)
|
||||
|
||||
Reference in New Issue
Block a user