From 67a366b987b5ffba251443b42d9a9df6f6aeb596 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 19 May 2021 16:22:36 +0200 Subject: validation: Test rtems_task_restart() --- testsuites/validation/tc-task-restart.c | 2482 ++++++++++++++++++++++++++++--- 1 file changed, 2258 insertions(+), 224 deletions(-) diff --git a/testsuites/validation/tc-task-restart.c b/testsuites/validation/tc-task-restart.c index da27412285..a09c8ba62c 100644 --- a/testsuites/validation/tc-task-restart.c +++ b/testsuites/validation/tc-task-restart.c @@ -52,8 +52,14 @@ #include "config.h" #endif +#include #include +#include #include +#include +#include +#include +#include #include "tx-support.h" @@ -69,16 +75,11 @@ typedef enum { RtemsTaskReqRestart_Pre_Id_Invalid, - RtemsTaskReqRestart_Pre_Id_Task, + RtemsTaskReqRestart_Pre_Id_Executing, + RtemsTaskReqRestart_Pre_Id_Other, RtemsTaskReqRestart_Pre_Id_NA } RtemsTaskReqRestart_Pre_Id; -typedef enum { - RtemsTaskReqRestart_Pre_Argument_Pointer, - RtemsTaskReqRestart_Pre_Argument_Number, - RtemsTaskReqRestart_Pre_Argument_NA -} RtemsTaskReqRestart_Pre_Argument; - typedef enum { RtemsTaskReqRestart_Pre_Dormant_Yes, RtemsTaskReqRestart_Pre_Dormant_No, @@ -91,13 +92,70 @@ typedef enum { RtemsTaskReqRestart_Pre_Suspended_NA } RtemsTaskReqRestart_Pre_Suspended; +typedef enum { + RtemsTaskReqRestart_Pre_Restarting_Yes, + RtemsTaskReqRestart_Pre_Restarting_No, + RtemsTaskReqRestart_Pre_Restarting_NA +} RtemsTaskReqRestart_Pre_Restarting; + +typedef enum { + RtemsTaskReqRestart_Pre_Terminating_Yes, + RtemsTaskReqRestart_Pre_Terminating_No, + RtemsTaskReqRestart_Pre_Terminating_NA +} RtemsTaskReqRestart_Pre_Terminating; + +typedef enum { + RtemsTaskReqRestart_Pre_Protected_Yes, + RtemsTaskReqRestart_Pre_Protected_No, + RtemsTaskReqRestart_Pre_Protected_NA +} RtemsTaskReqRestart_Pre_Protected; + +typedef enum { + RtemsTaskReqRestart_Pre_Context_Task, + RtemsTaskReqRestart_Pre_Context_Interrupt, + RtemsTaskReqRestart_Pre_Context_NestedRequest, + RtemsTaskReqRestart_Pre_Context_NA +} RtemsTaskReqRestart_Pre_Context; + +typedef enum { + RtemsTaskReqRestart_Pre_State_Ready, + RtemsTaskReqRestart_Pre_State_Blocked, + RtemsTaskReqRestart_Pre_State_Enqueued, + RtemsTaskReqRestart_Pre_State_NA +} RtemsTaskReqRestart_Pre_State; + +typedef enum { + RtemsTaskReqRestart_Pre_Timer_Inactive, + RtemsTaskReqRestart_Pre_Timer_Active, + RtemsTaskReqRestart_Pre_Timer_NA +} RtemsTaskReqRestart_Pre_Timer; + +typedef enum { + RtemsTaskReqRestart_Pre_RealPriority_Initial, + RtemsTaskReqRestart_Pre_RealPriority_Changed, + RtemsTaskReqRestart_Pre_RealPriority_NA +} RtemsTaskReqRestart_Pre_RealPriority; + +typedef enum { + RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled, + RtemsTaskReqRestart_Pre_ThreadDispatch_Enabled, + RtemsTaskReqRestart_Pre_ThreadDispatch_NA +} RtemsTaskReqRestart_Pre_ThreadDispatch; + typedef enum { RtemsTaskReqRestart_Post_Status_Ok, RtemsTaskReqRestart_Post_Status_InvId, RtemsTaskReqRestart_Post_Status_IncStat, + RtemsTaskReqRestart_Post_Status_NoReturn, RtemsTaskReqRestart_Post_Status_NA } RtemsTaskReqRestart_Post_Status; +typedef enum { + RtemsTaskReqRestart_Post_FatalError_Yes, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_FatalError_NA +} RtemsTaskReqRestart_Post_FatalError; + typedef enum { RtemsTaskReqRestart_Post_Argument_Set, RtemsTaskReqRestart_Post_Argument_Nop, @@ -105,10 +163,44 @@ typedef enum { } RtemsTaskReqRestart_Post_Argument; typedef enum { - RtemsTaskReqRestart_Post_Unblock_Yes, - RtemsTaskReqRestart_Post_Unblock_Nop, - RtemsTaskReqRestart_Post_Unblock_NA -} RtemsTaskReqRestart_Post_Unblock; + RtemsTaskReqRestart_Post_State_Dormant, + RtemsTaskReqRestart_Post_State_DormantSuspended, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_State_Ready, + RtemsTaskReqRestart_Post_State_Zombie, + RtemsTaskReqRestart_Post_State_Nop, + RtemsTaskReqRestart_Post_State_NA +} RtemsTaskReqRestart_Post_State; + +typedef enum { + RtemsTaskReqRestart_Post_Enqueued_Yes, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Enqueued_NA +} RtemsTaskReqRestart_Post_Enqueued; + +typedef enum { + RtemsTaskReqRestart_Post_Timer_Active, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Timer_NA +} RtemsTaskReqRestart_Post_Timer; + +typedef enum { + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Restarting_No, + RtemsTaskReqRestart_Post_Restarting_NA +} RtemsTaskReqRestart_Post_Restarting; + +typedef enum { + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Terminating_NA +} RtemsTaskReqRestart_Post_Terminating; + +typedef enum { + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_Protected_NA +} RtemsTaskReqRestart_Post_Protected; typedef enum { RtemsTaskReqRestart_Post_RestartExtensions_Yes, @@ -123,22 +215,92 @@ typedef struct { /** * @brief This member provides the scheduler operation records. */ - T_scheduler_log_2 scheduler_log; + T_scheduler_log_10 scheduler_log; + + /** + * @brief This member provides a jump context to resume a thread dispatch. + */ + jmp_buf thread_dispatch_context;; + + /** + * @brief This member provides an call within ISR request. + */ + CallWithinISRRequest isr_request; + + /** + * @brief This member may reference wrapped thread queue operations used to + * trigger a nested request. + */ + const Thread_queue_Operations *wrapped_operations; + + /** + * @brief This member provides a thread queue used to trigger a nested + * request. + */ + Thread_queue_Control thread_queue; + + /** + * @brief This member contains the identifier of the runner scheduler. + */ + rtems_id scheduler_id; + + /** + * @brief This member contains the identifier of the runner task. + */ + rtems_id runner_id; /** - * @brief This member contains the identifier of a task. + * @brief This member contains the identifier of the mutex. + */ + rtems_id mutex_id; + + /** + * @brief This member contains the identifier of the worker task. */ rtems_id worker_id; + /** + * @brief This member references the TCB of the worker task. + */ + rtems_tcb *worker_tcb; + + /** + * @brief This member contains the worker state at the end of the + * rtems_task_restart() call. + */ + States_Control worker_state; + + /** + * @brief This member contains the worker thread life state at the end of the + * rtems_task_restart() call. + */ + Thread_Life_state worker_life_state; + + /** + * @brief This member contains the identifier of the deleter task. + */ + rtems_id deleter_id; + + /** + * @brief This member references the TCB of the deleter task. + */ + rtems_tcb *deleter_tcb; + /** * @brief This member contains the identifier of the test user extensions. */ rtems_id extension_id; /** - * @brief This member contains the count of thread restart extension calls. + * @brief This member contains extension calls. + */ + ExtensionCalls calls;; + + /** + * @brief This member contains extension calls after the rtems_task_restart() + * call. */ - uint32_t restart_extension_calls; + ExtensionCalls calls_after_restart;; /** * @brief This member contains the actual argument passed to the entry point. @@ -146,21 +308,87 @@ typedef struct { rtems_task_argument actual_argument; /** - * @brief This member contains the entry point counter. + * @brief This member contains the restart counter. */ - uint32_t counter; + uint32_t restart_counter; /** - * @brief If this member is true, then the worker is started before the + * @brief If this member is true, then the worker shall be dormant before the * rtems_task_restart() call. */ - bool start; + bool dormant; + + /** + * @brief If this member is true, then the worker shall be suspended before + * the rtems_task_restart() call. + */ + bool suspended; + + /** + * @brief If this member is true, then the thread life of the worker shall be + * protected before the rtems_task_restart() call. + */ + bool protected; + + /** + * @brief If this member is true, then the worker shall be restarting before + * the rtems_task_restart() call. + */ + bool restarting; + + /** + * @brief If this member is true, then the worker shall be terminating before + * the rtems_task_restart() call. + */ + bool terminating; + + /** + * @brief If this member is true, then the rtems_task_restart() shall be + * called from within interrupt context. + */ + bool interrupt; + + /** + * @brief If this member is true, then the rtems_task_restart() shall be + * called during another rtems_task_restart() call with the same task as a + * nested request. + */ + bool nested_request; /** - * @brief If this member is true, then the worker is suspended before the + * @brief If this member is true, then the worker shall be blocked before the * rtems_task_restart() call. */ - bool suspend; + bool blocked; + + /** + * @brief If this member is true, then the worker shall be enqueued on a wait + * queue before the rtems_task_restart() call. + */ + bool enqueued; + + /** + * @brief If this member is true, then the timer of the worker shall be + * active before the rtems_task_restart() call. + */ + bool timer_active; + + /** + * @brief If this member is true, then the real priority of the worker shall + * be equal to its initial priority before the rtems_task_restart() call. + */ + bool real_priority_is_initial; + + /** + * @brief If this member is true, then thread dispatching is disabled by the + * worker task before the rtems_task_restart() call. + */ + bool dispatch_disabled; + + /** + * @brief If this member is true, then it is expected to delete the worker. + */ + bool delete_worker_expected; /** * @brief This member contains the return value of the rtems_task_restart() @@ -173,15 +401,10 @@ typedef struct { */ rtems_id id; - /** - * @brief This member specifies if the ``argument`` parameter value. - */ - rtems_task_argument argument; - /** * @brief This member defines the pre-condition states for the next action. */ - size_t pcs[ 4 ]; + size_t pcs[ 11 ]; /** * @brief This member indicates if the test action loop is currently @@ -195,286 +418,1291 @@ static RtemsTaskReqRestart_Context static const char * const RtemsTaskReqRestart_PreDesc_Id[] = { "Invalid", - "Task", + "Executing", + "Other", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_Dormant[] = { + "Yes", + "No", "NA" }; -static const char * const RtemsTaskReqRestart_PreDesc_Argument[] = { - "Pointer", - "Number", +static const char * const RtemsTaskReqRestart_PreDesc_Suspended[] = { + "Yes", + "No", "NA" }; -static const char * const RtemsTaskReqRestart_PreDesc_Dormant[] = { +static const char * const RtemsTaskReqRestart_PreDesc_Restarting[] = { "Yes", "No", "NA" }; -static const char * const RtemsTaskReqRestart_PreDesc_Suspended[] = { +static const char * const RtemsTaskReqRestart_PreDesc_Terminating[] = { "Yes", "No", "NA" }; +static const char * const RtemsTaskReqRestart_PreDesc_Protected[] = { + "Yes", + "No", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_Context[] = { + "Task", + "Interrupt", + "NestedRequest", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_State[] = { + "Ready", + "Blocked", + "Enqueued", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_Timer[] = { + "Inactive", + "Active", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_RealPriority[] = { + "Initial", + "Changed", + "NA" +}; + +static const char * const RtemsTaskReqRestart_PreDesc_ThreadDispatch[] = { + "Disabled", + "Enabled", + "NA" +}; + static const char * const * const RtemsTaskReqRestart_PreDesc[] = { RtemsTaskReqRestart_PreDesc_Id, - RtemsTaskReqRestart_PreDesc_Argument, RtemsTaskReqRestart_PreDesc_Dormant, RtemsTaskReqRestart_PreDesc_Suspended, + RtemsTaskReqRestart_PreDesc_Restarting, + RtemsTaskReqRestart_PreDesc_Terminating, + RtemsTaskReqRestart_PreDesc_Protected, + RtemsTaskReqRestart_PreDesc_Context, + RtemsTaskReqRestart_PreDesc_State, + RtemsTaskReqRestart_PreDesc_Timer, + RtemsTaskReqRestart_PreDesc_RealPriority, + RtemsTaskReqRestart_PreDesc_ThreadDispatch, NULL }; +#if CPU_SIZEOF_POINTER > 4 +#define RESTART_ARGUMENT 0xfedcba0987654321U +#else +#define RESTART_ARGUMENT 0x87654321U +#endif + +#define UNSET_ARGUMENT 1 + typedef RtemsTaskReqRestart_Context Context; -static void Worker( rtems_task_argument arg ) +static void PrepareRealPriority( Context *ctx ) +{ + if ( !ctx->real_priority_is_initial ) { + SetScheduler( ctx->worker_id, ctx->scheduler_id, PRIO_LOW ); + SetPriority( ctx->worker_id, PRIO_NORMAL ); + } +} + +static void CaptureWorkerState( Context *ctx ) +{ + T_scheduler_log *log; + + log = T_scheduler_record( NULL ); + + if ( log != NULL ) { + T_eq_ptr( &log->header, &ctx->scheduler_log.header ); + + ctx->worker_state = ctx->worker_tcb->current_state; + ctx->worker_life_state = ctx->worker_tcb->Life.state; + CopyExtensionCalls( &ctx->calls, &ctx->calls_after_restart ); + } +} + +static void VerifyTaskPreparation( const Context *ctx ) +{ + if ( ctx->id != INVALID_ID ) { + States_Control state; + Thread_Life_state life_state; + + state = STATES_READY; + life_state = ctx->worker_tcb->Life.state; + + if ( ctx->suspended ) { + state |= STATES_SUSPENDED; + } + + if ( ctx->dormant ) { + T_eq_int( life_state, 0 ); + state |= STATES_DORMANT; + } else { + T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 ); + T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 ); + T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 ); + + if ( ctx->blocked ) { + if ( ctx->enqueued ) { + state |= STATES_WAITING_FOR_MUTEX; + } else { + state |= STATES_WAITING_FOR_EVENT; + } + } + + if ( ctx->nested_request ) { + state |= STATES_LIFE_IS_CHANGING; + } + } + + T_eq_u32( ctx->worker_tcb->current_state, state ); + } +} + +static void Restart( void *arg ) +{ + Context *ctx; + T_scheduler_log *log; + + ctx = arg; + + if ( ctx->suspended && ctx->id != INVALID_ID ) { + if ( ctx->id != RTEMS_SELF || ctx->interrupt ) { + SuspendTask( ctx->worker_id ); + } else { + Per_CPU_Control *cpu_self; + + /* + * Where the system was built with SMP support enabled, a suspended + * executing thread during the rtems_task_restart() call can happen + * if the thread was suspended by another processor and the inter + * interrupt interrupt did not yet arrive. Where the system was built + * with SMP support disabled, this state cannot happen with the current + * implementation. However, we still specify and validate this + * behaviour unconditionally since there exist alternative + * implementations which would lead to such a state if the executing + * thread is suspended by an ISR. + */ + cpu_self = _Thread_Dispatch_disable(); + SuspendSelf(); + cpu_self->dispatch_necessary = false; + _Thread_Dispatch_enable( cpu_self ); + } + } + + if ( ctx->dispatch_disabled ) { + _Thread_Dispatch_disable(); + } + + VerifyTaskPreparation( ctx ); + ClearExtensionCalls( &ctx->calls ); + + log = T_scheduler_record_10( &ctx->scheduler_log ); + T_null( log ); + + ctx->status = rtems_task_restart( ctx->id, RESTART_ARGUMENT ); + + CaptureWorkerState( ctx ); + + if ( ctx->dispatch_disabled ) { + _Thread_Dispatch_enable( _Per_CPU_Get() ); + } +} + +static void Block( const Context *ctx ) +{ + rtems_interval ticks; + + if ( ctx->timer_active ) { + ticks = UINT32_MAX; + } else { + ticks = RTEMS_NO_TIMEOUT; + } + + if ( ctx->enqueued ) { + ObtainMutexTimed( ctx->mutex_id, ticks ); + } else { + (void) ReceiveAnyEventsTimed( ticks ); + } +} + +static void BlockDone( const Context *ctx ) +{ + if ( ctx->enqueued ) { + ReleaseMutex( ctx->mutex_id ); + } +} + +static void Fatal( + rtems_fatal_source source, + bool always_set_to_false, + rtems_fatal_code code +) +{ + Context *ctx; + Per_CPU_Control *cpu_self; + + T_eq_int( source, INTERNAL_ERROR_CORE ); + T_false( always_set_to_false ); + T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL ); + + ctx = T_fixture_context(); + ++ctx->calls.fatal; + T_assert_eq_int( ctx->calls.fatal, 1 ); + + CaptureWorkerState( ctx ); + + cpu_self = _Per_CPU_Get(); + _Thread_Dispatch_unnest( cpu_self ); + _Thread_Dispatch_direct_no_return( cpu_self ); +} + +static void ResumeThreadDispatch( + rtems_fatal_source source, + bool always_set_to_false, + rtems_fatal_code code +) +{ + Context *ctx; + + T_eq_int( source, INTERNAL_ERROR_CORE ); + T_false( always_set_to_false ); + T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL ); + + SetFatalExtension( Fatal ); + + ctx = T_fixture_context(); + longjmp( ctx->thread_dispatch_context, 1 ); +} + +static void TriggerNestedRequest( + Thread_queue_Queue *queue, + Thread_Control *thread, + Thread_queue_Context *queue_context +) +{ + Context *ctx; + + ctx = T_fixture_context(); + CallWithinISRSubmit( &ctx->isr_request ); + + if ( ctx->wrapped_operations ) { + thread->Wait.operations = ctx->wrapped_operations; + ( *thread->Wait.operations->extract )( queue, thread, queue_context ); + } +} + +const Thread_queue_Operations trigger_nested_request = { + .extract = TriggerNestedRequest +}; + +static void PrepareNestedRequest( Context *ctx ) +{ + Thread_Control *thread; + + thread = ctx->worker_tcb; + + if ( thread->Wait.queue != NULL ) { + ctx->wrapped_operations = thread->Wait.operations; + thread->Wait.operations = &trigger_nested_request; + } else { + Thread_queue_Context queue_context; + + ctx->wrapped_operations = NULL; + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Acquire( &ctx->thread_queue, &queue_context ); + _Thread_Wait_flags_set( + thread, + THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK + ); + _Thread_Wait_claim( thread, &ctx->thread_queue.Queue ); + _Thread_Wait_claim_finalize( thread, &trigger_nested_request ); + _Thread_queue_Release( &ctx->thread_queue, &queue_context ); + } +} + +static void TriggerNestedRequestViaSelfRestart( + Context *ctx, + Per_CPU_Control *cpu_self +) +{ + PrepareNestedRequest( ctx ); + SetFatalExtension( ResumeThreadDispatch ); + + if ( setjmp( ctx->thread_dispatch_context ) == 0 ) { + (void) rtems_task_restart( + RTEMS_SELF, + (rtems_task_argument) ctx + ); + } else { + _Thread_Dispatch_unnest( cpu_self ); + } +} + +static void Signal( rtems_signal_set signals ) { Context *ctx; - ctx = &RtemsTaskReqRestart_Instance; + (void) signals; + ctx = T_fixture_context(); + + if ( ctx->id == RTEMS_SELF ) { + Per_CPU_Control *cpu_self; + + SetPriority( ctx->runner_id, PRIO_VERY_LOW ); + SetPriority( ctx->deleter_id, PRIO_VERY_LOW ); + + if ( ctx->interrupt || ctx->nested_request ) { + if ( ctx->blocked ) { + SetFatalExtension( ResumeThreadDispatch ); + cpu_self = _Thread_Dispatch_disable(); + + if ( setjmp( ctx->thread_dispatch_context ) == 0 ) { + Block( ctx ); + } else { + _Thread_Dispatch_unnest( cpu_self ); + } + + if ( ctx->interrupt ) { + CallWithinISR( Restart, ctx ); + } else { + TriggerNestedRequestViaSelfRestart( ctx, cpu_self ); + } + + _Thread_Dispatch_direct( cpu_self ); + BlockDone( ctx ); + } else { + if ( ctx->interrupt ) { + CallWithinISR( Restart, ctx ); + } else { + cpu_self = _Thread_Dispatch_disable(); + TriggerNestedRequestViaSelfRestart( ctx, cpu_self ); + _Thread_Dispatch_direct( cpu_self ); + } + } + } else { + Restart( ctx ); + } + } else { + if ( ctx->blocked ) { + Block( ctx ); + BlockDone( ctx ); + } else if ( ctx->nested_request ) { + Yield(); + } else { + SetPriority( ctx->runner_id, PRIO_VERY_HIGH ); + } + } + + if ( ctx->protected ) { + _Thread_Set_life_protection( 0 ); + } +} + +static void Deleter( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + if ( ctx != NULL ) { + if ( ctx->real_priority_is_initial ) { + /* + * We have to prevent a potential priority boost in the task delete + * below. + */ + if ( ctx->nested_request ) { + rtems_status_code sc; + rtems_id id; + + /* + * This sequence lowers the priority to PRIO_NORMAL without an + * implicit yield. + */ + + sc = rtems_semaphore_create( + rtems_build_name( 'M', 'U', 'T', 'X' ), + 0, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING, + PRIO_HIGH, + &id + ); + T_rsc_success( sc ); + + SetSelfPriority( PRIO_NORMAL ); + ReleaseMutex( id ); + DeleteMutex( id ); + } else { + SetScheduler( ctx->worker_id, ctx->scheduler_id, PRIO_HIGH ); + } + } + + if ( ctx->nested_request ) { + PrepareNestedRequest( ctx ); + DeleteTask( ctx->worker_id ); + } else { + DeleteTask( ctx->worker_id ); + } + } + + SuspendSelf(); +} + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + rtems_status_code sc; + + ctx = T_fixture_context(); + + if ( arg == 0 ) { + sc = rtems_signal_catch( Signal, RTEMS_NO_ASR ); + T_rsc_success( sc ); + + if ( ctx->protected ) { + _Thread_Set_life_protection( THREAD_LIFE_PROTECTED ); + } + + Yield(); + } else { + ctx->actual_argument = arg; + ++ctx->restart_counter; + + CaptureWorkerState( ctx ); + SuspendSelf(); + } +} + +static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted ) +{ + Context *ctx; + + ctx = T_fixture_context(); + ++ctx->calls.thread_delete; + + T_eq_u32( executing->Object.id, ctx->runner_id ); + + if ( ctx->delete_worker_expected ) { + T_eq_u32( deleted->Object.id, ctx->worker_id ); + } +} + +static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted ) +{ + Context *ctx; + + ctx = T_fixture_context(); + ++ctx->calls.thread_restart; +} + +static void ThreadTerminate( rtems_tcb *executing ) +{ + Context *ctx; + + ctx = T_fixture_context(); + ++ctx->calls.thread_terminate; + + T_eq_u32( executing->Object.id, ctx->worker_id ); +} + +static const rtems_extensions_table extensions = { + .thread_delete = ThreadDelete, + .thread_restart = ThreadRestart, + .thread_terminate = ThreadTerminate +}; + +static void RtemsTaskReqRestart_Pre_Id_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Id state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Id_Invalid: { + /* + * While the ``id`` parameter is not associated with a task. + */ + ctx->id = INVALID_ID; + break; + } + + case RtemsTaskReqRestart_Pre_Id_Executing: { + /* + * While the ``id`` parameter is associated with the calling task. + */ + ctx->id = RTEMS_SELF; + break; + } + + case RtemsTaskReqRestart_Pre_Id_Other: { + /* + * While the ``id`` parameter is associated with a task other than the + * calling task. + */ + ctx->id = ctx->worker_id; + break; + } + + case RtemsTaskReqRestart_Pre_Id_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Dormant_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Dormant state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Dormant_Yes: { + /* + * While the task specified by the ``id`` parameter is dormant. + */ + ctx->dormant = true; + break; + } + + case RtemsTaskReqRestart_Pre_Dormant_No: { + /* + * While the task specified by the ``id`` parameter is not dormant. + */ + ctx->dormant = false; + break; + } + + case RtemsTaskReqRestart_Pre_Dormant_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Suspended_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Suspended state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Suspended_Yes: { + /* + * While the task specified by the ``id`` parameter is suspended. + */ + ctx->suspended = true; + break; + } + + case RtemsTaskReqRestart_Pre_Suspended_No: { + /* + * While the task specified by the ``id`` parameter is not suspended. + */ + ctx->suspended = false; + break; + } + + case RtemsTaskReqRestart_Pre_Suspended_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Restarting_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Restarting state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Restarting_Yes: { + /* + * While the task specified by the ``id`` parameter is restarting. + */ + ctx->restarting = true; + break; + } + + case RtemsTaskReqRestart_Pre_Restarting_No: { + /* + * While the task specified by the ``id`` parameter is not restarting. + */ + ctx->restarting = false; + break; + } + + case RtemsTaskReqRestart_Pre_Restarting_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Terminating_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Terminating state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Terminating_Yes: { + /* + * While the task specified by the ``id`` parameter is terminating. + */ + ctx->terminating = true; + break; + } + + case RtemsTaskReqRestart_Pre_Terminating_No: { + /* + * While the task specified by the ``id`` parameter is not terminating. + */ + ctx->terminating = false; + break; + } + + case RtemsTaskReqRestart_Pre_Terminating_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Protected_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Protected state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Protected_Yes: { + /* + * While thread life of the the task specified by the ``id`` parameter is + * protected. + */ + ctx->protected = true; + break; + } + + case RtemsTaskReqRestart_Pre_Protected_No: { + /* + * While thread life of the the task specified by the ``id`` parameter is + * not protected. + */ + ctx->protected = false; + break; + } + + case RtemsTaskReqRestart_Pre_Protected_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Context_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Context state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Context_Task: { + /* + * While the rtems_task_restart() directive is called from within task + * context. + */ + ctx->interrupt = false; + ctx->nested_request = false; + break; + } + + case RtemsTaskReqRestart_Pre_Context_Interrupt: { + /* + * While the rtems_task_restart() directive is called from within + * interrupt context. + */ + ctx->interrupt = true; + ctx->nested_request = false; + break; + } + + case RtemsTaskReqRestart_Pre_Context_NestedRequest: { + /* + * While the rtems_task_restart() directive is called during another + * rtems_task_restart() call with the same task as a nested request. + */ + ctx->interrupt = false; + ctx->nested_request = true; + break; + } + + case RtemsTaskReqRestart_Pre_Context_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_State_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_State state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_State_Ready: { + /* + * While the task specified by the ``id`` parameter is a ready task or + * scheduled task. + */ + ctx->blocked = false; + break; + } + + case RtemsTaskReqRestart_Pre_State_Blocked: { + /* + * While the task specified by the ``id`` parameter is blocked. + */ + ctx->blocked = true; + ctx->enqueued = false; + break; + } + + case RtemsTaskReqRestart_Pre_State_Enqueued: { + /* + * While the task specified by the ``id`` parameter is enqueued on a wait + * queue. + */ + ctx->blocked = true; + ctx->enqueued = true; + break; + } + + case RtemsTaskReqRestart_Pre_State_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_Timer_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_Timer state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_Timer_Inactive: { + /* + * While timer of the task specified by the ``id`` parameter is inactive. + */ + ctx->timer_active = false; + break; + } + + case RtemsTaskReqRestart_Pre_Timer_Active: { + /* + * While timer of the task specified by the ``id`` parameter is active. + */ + ctx->timer_active = true; + break; + } + + case RtemsTaskReqRestart_Pre_Timer_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_RealPriority_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_RealPriority state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_RealPriority_Initial: { + /* + * While real priority of the task specified by the ``id`` parameter is + * equal to the initial priority. + */ + ctx->real_priority_is_initial = true; + break; + } + + case RtemsTaskReqRestart_Pre_RealPriority_Changed: { + /* + * While real priority of the task specified by the ``id`` parameter is + * not equal to the initial priority. + */ + ctx->real_priority_is_initial = false; + break; + } + + case RtemsTaskReqRestart_Pre_RealPriority_NA: + break; + } +} + +static void RtemsTaskReqRestart_Pre_ThreadDispatch_Prepare( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Pre_ThreadDispatch state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled: { + /* + * While thread dispatching is disabled for the calling task. + */ + ctx->dispatch_disabled = true; + break; + } + + case RtemsTaskReqRestart_Pre_ThreadDispatch_Enabled: { + /* + * While thread dispatching is enabled for the calling task. + */ + ctx->dispatch_disabled = false; + break; + } - while ( true ) { - ctx->actual_argument += arg; - ++ctx->counter; - Yield(); + case RtemsTaskReqRestart_Pre_ThreadDispatch_NA: + break; } } -static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted ) +static void RtemsTaskReqRestart_Post_Status_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Status state +) { - (void) executing; - (void) restarted; + switch ( state ) { + case RtemsTaskReqRestart_Post_Status_Ok: { + /* + * The return status of rtems_task_restart() shall be RTEMS_SUCCESSFUL. + */ + T_rsc_success( ctx->status ); + break; + } - ++RtemsTaskReqRestart_Instance.restart_extension_calls; -} + case RtemsTaskReqRestart_Post_Status_InvId: { + /* + * The return status of rtems_task_restart() shall be RTEMS_INVALID_ID. + */ + T_rsc( ctx->status, RTEMS_INVALID_ID ); + break; + } -static const rtems_extensions_table extensions = { - .thread_restart = ThreadRestart -}; + case RtemsTaskReqRestart_Post_Status_IncStat: { + /* + * The return status of rtems_task_restart() shall be + * RTEMS_INCORRECT_STATE. + */ + T_rsc( ctx->status, RTEMS_INCORRECT_STATE ); + break; + } -static void RtemsTaskReqRestart_Pre_Id_Prepare( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Pre_Id state + case RtemsTaskReqRestart_Post_Status_NoReturn: { + /* + * The rtems_task_restart() call shall not return. + */ + T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED ); + break; + } + + case RtemsTaskReqRestart_Post_Status_NA: + break; + } +} + +static void RtemsTaskReqRestart_Post_FatalError_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_FatalError state ) { switch ( state ) { - case RtemsTaskReqRestart_Pre_Id_Invalid: { + case RtemsTaskReqRestart_Post_FatalError_Yes: { /* - * While the ``id`` parameter is not associated with a task. + * The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal + * code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur + * by the rtems_task_restart() call. */ - ctx->id = INVALID_ID; + T_eq_u32( ctx->calls.fatal, 1 ); break; } - case RtemsTaskReqRestart_Pre_Id_Task: { + case RtemsTaskReqRestart_Post_FatalError_Nop: { /* - * While the ``id`` parameter is associated with a task. + * No fatal error shall occur by the rtems_task_restart() call. */ - ctx->id = ctx->worker_id; + T_eq_u32( ctx->calls.fatal, 0 ); break; } - case RtemsTaskReqRestart_Pre_Id_NA: + case RtemsTaskReqRestart_Post_FatalError_NA: break; } } -static void RtemsTaskReqRestart_Pre_Argument_Prepare( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Pre_Argument state +static void RtemsTaskReqRestart_Post_Argument_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Argument state ) { switch ( state ) { - case RtemsTaskReqRestart_Pre_Argument_Pointer: { + case RtemsTaskReqRestart_Post_Argument_Set: { /* - * While the entry point argument specified by the ``argument`` parameter - * is a pointer. + * The entry point argument of the task specified by the ``id`` parameter + * shall be set to the value specified by the ``argument`` parameter + * before the task is unblocked by the rtems_task_restart() call. */ - ctx->argument = (rtems_task_argument) ctx; + if ( ctx->restart_counter != 0 ) { + #if CPU_SIZEOF_POINTER > 4 + T_eq_u64( ctx->actual_argument, RESTART_ARGUMENT ); + #else + T_eq_u32( ctx->actual_argument, RESTART_ARGUMENT ); + #endif + + T_eq_u32( ctx->restart_counter, 1 ); + } else { + #if CPU_SIZEOF_POINTER > 4 + T_eq_u64( + ctx->worker_tcb->Start.Entry.Kinds.Numeric.argument, + RESTART_ARGUMENT + ); + T_eq_u64( ctx->actual_argument, UNSET_ARGUMENT ); + #else + T_eq_u32( + ctx->worker_tcb->Start.Entry.Kinds.Numeric.argument, + RESTART_ARGUMENT + ); + T_eq_u32( ctx->actual_argument, UNSET_ARGUMENT ); + #endif + } break; } - case RtemsTaskReqRestart_Pre_Argument_Number: { + case RtemsTaskReqRestart_Post_Argument_Nop: { /* - * While the entry point argument specified by the ``argument`` parameter - * is a 32-bit number. + * No entry point argument of a task shall be modified by the + * rtems_task_restart() call. */ - ctx->argument = UINT32_C( 0x87654321 ); + T_eq_u32( ctx->actual_argument, UNSET_ARGUMENT ); + T_eq_u32( ctx->restart_counter, 0 ); break; } - case RtemsTaskReqRestart_Pre_Argument_NA: + case RtemsTaskReqRestart_Post_Argument_NA: break; } } -static void RtemsTaskReqRestart_Pre_Dormant_Prepare( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Pre_Dormant state +static void RtemsTaskReqRestart_Post_State_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_State state ) { + const T_scheduler_event *event; + size_t index; + + index = 0; + switch ( state ) { - case RtemsTaskReqRestart_Pre_Dormant_Yes: { + case RtemsTaskReqRestart_Post_State_Dormant: { /* - * While the task specified by the ``id`` parameter is dormant. + * The state of the task specified by the ``id`` parameter shall be + * dormant after the rtems_task_restart() call. */ - ctx->start = false; + T_eq_u32( ctx->worker_state, STATES_DORMANT ) + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); break; } - case RtemsTaskReqRestart_Pre_Dormant_No: { + case RtemsTaskReqRestart_Post_State_DormantSuspended: { /* - * While the task specified by the ``id`` parameter is not dormant. + * The state of the task specified by the ``id`` parameter shall be + * dormant and suspended after the rtems_task_restart() call. */ - ctx->start = true; + T_eq_u32( ctx->worker_state, STATES_DORMANT | STATES_SUSPENDED ) + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); break; } - case RtemsTaskReqRestart_Pre_Dormant_NA: + case RtemsTaskReqRestart_Post_State_Blocked: { + /* + * The state of the task specified by the ``id`` parameter shall be + * blocked after the rtems_task_restart() call. + */ + T_ne_u32( ctx->worker_state & STATES_BLOCKED, 0 ) + T_eq_u32( ctx->worker_state & STATES_BLOCKED, ctx->worker_state ) + + if ( ctx->suspended && !ctx->blocked ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + + if ( !ctx->real_priority_is_initial ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); + break; + } + + case RtemsTaskReqRestart_Post_State_Ready: { + /* + * The state of the task specified by the ``id`` parameter shall be ready + * after the rtems_task_restart() call. + */ + T_eq_u32( ctx->worker_state, STATES_READY ) + + if ( ctx->protected ) { + if ( ctx->suspended ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + } else { + if ( ctx->suspended || ctx->blocked ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } else { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_BLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + } + + if ( !ctx->real_priority_is_initial ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); + break; + } + + case RtemsTaskReqRestart_Post_State_Zombie: { + /* + * The state of the task specified by the ``id`` parameter shall be the + * zombie state after the rtems_task_restart() call. + */ + T_eq_u32( ctx->worker_state, STATES_ZOMBIE ) + + if ( ctx->protected ) { + if ( ctx->suspended ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + } else { + if ( ctx->suspended ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } else { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_BLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + } + + if ( !ctx->real_priority_is_initial ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + + /* Set zombie state */ + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_BLOCK ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + + /* Wake up deleter */ + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UNBLOCK ); + T_eq_ptr( event->thread, ctx->deleter_tcb ); + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); + break; + } + + case RtemsTaskReqRestart_Post_State_Nop: { + /* + * The state of the task specified by the ``id`` parameter shall not be + * modified by the rtems_task_restart() call. + */ + T_ne_u32( ctx->worker_state & STATES_LIFE_IS_CHANGING, 0 ) + + if ( !ctx->real_priority_is_initial ) { + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY ); + T_eq_ptr( event->thread, ctx->worker_tcb ); + } + + event = T_scheduler_next_any( &ctx->scheduler_log.header, &index ); + T_eq_int( event->operation, T_SCHEDULER_NOP ); + break; + } + + case RtemsTaskReqRestart_Post_State_NA: break; } } -static void RtemsTaskReqRestart_Pre_Suspended_Prepare( +static void RtemsTaskReqRestart_Post_Enqueued_Check( RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Pre_Suspended state + RtemsTaskReqRestart_Post_Enqueued state ) { switch ( state ) { - case RtemsTaskReqRestart_Pre_Suspended_Yes: { + case RtemsTaskReqRestart_Post_Enqueued_Yes: { /* - * While the task specified by the ``id`` parameter is suspended. + * The task specified by the ``id`` parameter shall be enqueued on a wait + * queue after the rtems_task_restart() call. */ - ctx->suspend = true; + T_not_null( ctx->worker_tcb->Wait.queue ); break; } - case RtemsTaskReqRestart_Pre_Suspended_No: { + case RtemsTaskReqRestart_Post_Enqueued_No: { /* - * While the task specified by the ``id`` parameter is not suspended. + * The task specified by the ``id`` parameter shall not be enqueued on a + * wait queue after the rtems_task_restart() call. */ - ctx->suspend = false; + T_null( ctx->worker_tcb->Wait.queue ); break; } - case RtemsTaskReqRestart_Pre_Suspended_NA: + case RtemsTaskReqRestart_Post_Enqueued_NA: break; } } -static void RtemsTaskReqRestart_Post_Status_Check( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Post_Status state +static void RtemsTaskReqRestart_Post_Timer_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Timer state ) { + TaskTimerInfo info; + switch ( state ) { - case RtemsTaskReqRestart_Post_Status_Ok: { + case RtemsTaskReqRestart_Post_Timer_Active: { /* - * The return status of rtems_task_restart() shall be RTEMS_SUCCESSFUL. + * The timer of the task specified by the ``id`` parameter shall be + * active after the rtems_task_restart() call. */ - T_rsc_success( ctx->status ); + GetTaskTimerInfoByThread( ctx->worker_tcb, &info); + T_eq_int( info.state, TASK_TIMER_TICKS ); break; } - case RtemsTaskReqRestart_Post_Status_InvId: { + case RtemsTaskReqRestart_Post_Timer_Inactive: { /* - * The return status of rtems_task_restart() shall be RTEMS_INVALID_ID. + * The timer of the task specified by the ``id`` parameter shall be + * inactive after the rtems_task_restart() call. */ - T_rsc( ctx->status, RTEMS_INVALID_ID ); + GetTaskTimerInfoByThread( ctx->worker_tcb, &info); + T_eq_int( info.state, TASK_TIMER_INACTIVE ); break; } - case RtemsTaskReqRestart_Post_Status_IncStat: { + case RtemsTaskReqRestart_Post_Timer_NA: + break; + } +} + +static void RtemsTaskReqRestart_Post_Restarting_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Restarting state +) +{ + switch ( state ) { + case RtemsTaskReqRestart_Post_Restarting_Yes: { /* - * The return status of rtems_task_restart() shall be - * RTEMS_INCORRECT_STATE. + * The task specified by the ``id`` parameter shall be restarting after + * the rtems_task_restart() call. */ - T_rsc( ctx->status, RTEMS_INCORRECT_STATE ); + T_ne_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 ); break; } - case RtemsTaskReqRestart_Post_Status_NA: + case RtemsTaskReqRestart_Post_Restarting_No: { + /* + * The task specified by the ``id`` parameter shall not be restarting + * after the rtems_task_restart() call. + */ + T_eq_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 ); + break; + } + + case RtemsTaskReqRestart_Post_Restarting_NA: break; } } -static void RtemsTaskReqRestart_Post_Argument_Check( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Post_Argument state +static void RtemsTaskReqRestart_Post_Terminating_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Terminating state ) { switch ( state ) { - case RtemsTaskReqRestart_Post_Argument_Set: { + case RtemsTaskReqRestart_Post_Terminating_Yes: { /* - * The entry point argument of the task specified by the ``id`` parameter - * shall be set to the value specified by the ``argument`` parameter - * before the task is unblocked by the rtems_task_restart() call. + * The task specified by the ``id`` parameter shall be terminating after + * the rtems_task_restart() call. */ - T_eq_u32( ctx->actual_argument, ctx->argument ); - T_eq_u32( ctx->counter, 2 ); + T_ne_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 ); break; } - case RtemsTaskReqRestart_Post_Argument_Nop: { + case RtemsTaskReqRestart_Post_Terminating_No: { /* - * No entry point argument of a task shall be modified by the - * rtems_task_restart() call. + * The task specified by the ``id`` parameter shall not be terminating + * after the rtems_task_restart() call. */ - T_eq_u32( ctx->actual_argument, 0 ); - - if ( ctx->start ) { - T_eq_u32( ctx->counter, 1 ); - } else { - T_eq_u32( ctx->counter, 0 ); - } + T_eq_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 ); break; } - case RtemsTaskReqRestart_Post_Argument_NA: + case RtemsTaskReqRestart_Post_Terminating_NA: break; } } -static void RtemsTaskReqRestart_Post_Unblock_Check( - RtemsTaskReqRestart_Context *ctx, - RtemsTaskReqRestart_Post_Unblock state +static void RtemsTaskReqRestart_Post_Protected_Check( + RtemsTaskReqRestart_Context *ctx, + RtemsTaskReqRestart_Post_Protected state ) { switch ( state ) { - case RtemsTaskReqRestart_Post_Unblock_Yes: { + case RtemsTaskReqRestart_Post_Protected_Yes: { /* - * The task specified by the ``id`` parameter shall be unblocked by the - * rtems_task_restart() call. + * The thread life of the task specified by the ``id`` parameter be + * protected after the rtems_task_restart() call. */ - if ( ctx->suspend ) { - T_eq_sz( ctx->scheduler_log.header.recorded, 1 ); - T_eq_int( - ctx->scheduler_log.events[ 0 ].operation, - T_SCHEDULER_UNBLOCK - ); - } else { - T_eq_sz( ctx->scheduler_log.header.recorded, 2 ); - T_eq_int( - ctx->scheduler_log.events[ 0 ].operation, - T_SCHEDULER_BLOCK - ); - T_eq_int( - ctx->scheduler_log.events[ 1 ].operation, - T_SCHEDULER_UNBLOCK - ); - } + T_ne_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 ); break; } - case RtemsTaskReqRestart_Post_Unblock_Nop: { + case RtemsTaskReqRestart_Post_Protected_No: { /* - * No task shall be unblocked by the rtems_task_restart() call. + * The thread life of the task specified by the ``id`` parameter shall + * not be protected after the rtems_task_restart() call. */ - T_eq_sz( ctx->scheduler_log.header.recorded, 0 ); + T_eq_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 ); break; } - case RtemsTaskReqRestart_Post_Unblock_NA: + case RtemsTaskReqRestart_Post_Protected_NA: break; } } @@ -490,7 +1718,7 @@ static void RtemsTaskReqRestart_Post_RestartExtensions_Check( * The thread restart user extensions shall be invoked by the * rtems_task_restart() call. */ - T_eq_u32( ctx->restart_extension_calls, 1 ); + T_eq_u32( ctx->calls_after_restart.thread_restart, 1 ); break; } @@ -499,7 +1727,7 @@ static void RtemsTaskReqRestart_Post_RestartExtensions_Check( * The thread restart user extensions shall not be invoked by the * rtems_task_restart() call. */ - T_eq_u32( ctx->restart_extension_calls, 0 ); + T_eq_u32( ctx->calls_after_restart.thread_restart, 0 ); break; } @@ -512,12 +1740,29 @@ static void RtemsTaskReqRestart_Setup( RtemsTaskReqRestart_Context *ctx ) { rtems_status_code sc; + ctx->runner_id = rtems_task_self(); + ctx->scheduler_id = GetSelfScheduler(); + ctx->mutex_id = CreateMutexNoProtocol(); + ObtainMutex( ctx->mutex_id ); + + ctx->isr_request.handler = Restart; + ctx->isr_request.arg = ctx; + + _Thread_queue_Initialize( &ctx->thread_queue, "Nested Request" ); + sc = rtems_extension_create( rtems_build_name( 'T', 'E', 'S', 'T' ), &extensions, &ctx->extension_id ); T_rsc_success( sc ); + + SetFatalExtension( Fatal ); + SetSelfPriority( PRIO_NORMAL ); + + ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH ); + ctx->deleter_tcb = GetThread( ctx->deleter_id ); + StartTask( ctx->deleter_id, Deleter, NULL ); } static void RtemsTaskReqRestart_Setup_Wrap( void *arg ) @@ -535,6 +1780,14 @@ static void RtemsTaskReqRestart_Teardown( RtemsTaskReqRestart_Context *ctx ) sc = rtems_extension_delete( ctx->extension_id ); T_rsc_success( sc ); + + SetFatalExtension( NULL ); + DeleteTask( ctx->deleter_id ); + ReleaseMutex( ctx->mutex_id ); + DeleteMutex( ctx->mutex_id ); + RestoreRunnerASR(); + RestoreRunnerPriority(); + _Thread_queue_Destroy( &ctx->thread_queue ); } static void RtemsTaskReqRestart_Teardown_Wrap( void *arg ) @@ -548,73 +1801,711 @@ static void RtemsTaskReqRestart_Teardown_Wrap( void *arg ) static void RtemsTaskReqRestart_Prepare( RtemsTaskReqRestart_Context *ctx ) { - ctx->actual_argument = 0; - ctx->counter = 0; - ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT ); + ctx->status = RTEMS_NOT_IMPLEMENTED; + ctx->actual_argument = UNSET_ARGUMENT; + ctx->restart_counter = 0; + + ctx->delete_worker_expected = false; + ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL ); + ctx->delete_worker_expected = true; + + ctx->worker_tcb = GetThread( ctx->worker_id ); + ctx->worker_state = UINT32_MAX; + ctx->worker_life_state = INT_MAX; + + SetPriority( ctx->deleter_id, PRIO_HIGH ); } static void RtemsTaskReqRestart_Action( RtemsTaskReqRestart_Context *ctx ) { - T_scheduler_log *log; + rtems_status_code sc; - if ( ctx->start ) { - StartTask( ctx->worker_id, Worker, 0 ); - Yield(); - } + if ( ctx->id != INVALID_ID ) { + if ( ctx->dormant ) { + PrepareRealPriority( ctx ); + } else { + StartTask( ctx->worker_id, Worker, NULL ); - if ( ctx->suspend ) { - SuspendTask( ctx->worker_id ); - } + /* Let the worker catch signals and set the thread life protection state */ + Yield(); - ctx->restart_extension_calls = 0; + sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 ); + T_rsc_success( sc ); - log = T_scheduler_record_2( &ctx->scheduler_log ); - T_null( log ); + if ( + ctx->restarting && + ( !ctx->nested_request || ( ctx->nested_request && ctx->terminating ) ) + ) { + sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx ); + T_rsc_success( sc ); + } + + if ( ctx->terminating && !ctx->nested_request ) { + sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx ); + T_rsc_success( sc ); + } else { + PrepareRealPriority( ctx ); + Yield(); + } + } + } - ctx->status = rtems_task_restart( ctx->id, ctx->argument ); + if ( ctx->id == RTEMS_SELF ) { + CaptureWorkerState( ctx ); + } else { + if ( ctx->nested_request ) { + if ( ctx->terminating ) { + sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx ); + T_rsc_success( sc ); + } else { + PrepareNestedRequest( ctx ); - log = T_scheduler_record( NULL ); - T_eq_ptr( &log->header, &ctx->scheduler_log.header ); + sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx ); + T_rsc_success( sc ); + } + } else { + SetSelfPriority( PRIO_VERY_HIGH ); - Yield(); + if ( ctx->interrupt ) { + CallWithinISR( Restart, ctx ); + } else { + Restart( ctx ); + } + } + } } static void RtemsTaskReqRestart_Cleanup( RtemsTaskReqRestart_Context *ctx ) { - DeleteTask( ctx->worker_id ); + SetSelfPriority( PRIO_VERY_LOW ); + + if ( ctx->protected && ctx->blocked ) { + if ( ctx->enqueued ) { + ReleaseMutex( ctx->mutex_id ); + ObtainMutex( ctx->mutex_id ); + } else { + SendEvents( ctx->worker_id, RTEMS_EVENT_0 ); + } + } + + if ( ctx->id == INVALID_ID || ctx->dormant || !ctx->terminating ) { + DeleteTask( ctx->worker_id ); + } + + SetSelfPriority( PRIO_NORMAL ); } typedef struct { - uint16_t Skip : 1; - uint16_t Pre_Id_NA : 1; - uint16_t Pre_Argument_NA : 1; - uint16_t Pre_Dormant_NA : 1; - uint16_t Pre_Suspended_NA : 1; - uint16_t Post_Status : 2; - uint16_t Post_Argument : 2; - uint16_t Post_Unblock : 2; - uint16_t Post_RestartExtensions : 2; + uint64_t Skip : 1; + uint64_t Pre_Id_NA : 1; + uint64_t Pre_Dormant_NA : 1; + uint64_t Pre_Suspended_NA : 1; + uint64_t Pre_Restarting_NA : 1; + uint64_t Pre_Terminating_NA : 1; + uint64_t Pre_Protected_NA : 1; + uint64_t Pre_Context_NA : 1; + uint64_t Pre_State_NA : 1; + uint64_t Pre_Timer_NA : 1; + uint64_t Pre_RealPriority_NA : 1; + uint64_t Pre_ThreadDispatch_NA : 1; + uint64_t Post_Status : 3; + uint64_t Post_FatalError : 2; + uint64_t Post_Argument : 2; + uint64_t Post_State : 3; + uint64_t Post_Enqueued : 2; + uint64_t Post_Timer : 2; + uint64_t Post_Restarting : 2; + uint64_t Post_Terminating : 2; + uint64_t Post_Protected : 2; + uint64_t Post_RestartExtensions : 2; } RtemsTaskReqRestart_Entry; static const RtemsTaskReqRestart_Entry RtemsTaskReqRestart_Entries[] = { - { 0, 0, 0, 1, 1, RtemsTaskReqRestart_Post_Status_InvId, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, RtemsTaskReqRestart_Post_Status_InvId, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, + RtemsTaskReqRestart_Post_Status_IncStat, + RtemsTaskReqRestart_Post_FatalError_Nop, RtemsTaskReqRestart_Post_Argument_Nop, - RtemsTaskReqRestart_Post_Unblock_Nop, + RtemsTaskReqRestart_Post_State_DormantSuspended, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_No, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, RtemsTaskReqRestart_Post_RestartExtensions_Nop }, - { 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_IncStat, + { 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, + RtemsTaskReqRestart_Post_Status_IncStat, + RtemsTaskReqRestart_Post_FatalError_Nop, RtemsTaskReqRestart_Post_Argument_Nop, - RtemsTaskReqRestart_Post_Unblock_Nop, + RtemsTaskReqRestart_Post_State_Dormant, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_No, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA, + RtemsTaskReqRestart_Post_FatalError_NA, + RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA, + RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA, + RtemsTaskReqRestart_Post_Restarting_NA, + RtemsTaskReqRestart_Post_Terminating_NA, + RtemsTaskReqRestart_Post_Protected_NA, + RtemsTaskReqRestart_Post_RestartExtensions_NA }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, RtemsTaskReqRestart_Post_State_Nop, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, RtemsTaskReqRestart_Post_State_Nop, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Active, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_Yes, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_Yes, + RtemsTaskReqRestart_Post_Timer_Active, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Active, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_Yes, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Blocked, + RtemsTaskReqRestart_Post_Enqueued_Yes, + RtemsTaskReqRestart_Post_Timer_Active, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Zombie, + RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Nop, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_No, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Yes }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Yes, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Yes, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_Yes, + RtemsTaskReqRestart_Post_Protected_No, RtemsTaskReqRestart_Post_RestartExtensions_Nop }, - { 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Yes, RtemsTaskReqRestart_Post_Argument_Set, - RtemsTaskReqRestart_Post_Unblock_Yes, - RtemsTaskReqRestart_Post_RestartExtensions_Yes } + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_Yes, + RtemsTaskReqRestart_Post_RestartExtensions_Nop }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + RtemsTaskReqRestart_Post_Status_NoReturn, + RtemsTaskReqRestart_Post_FatalError_Yes, + RtemsTaskReqRestart_Post_Argument_Set, + RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No, + RtemsTaskReqRestart_Post_Timer_Inactive, + RtemsTaskReqRestart_Post_Restarting_Yes, + RtemsTaskReqRestart_Post_Terminating_No, + RtemsTaskReqRestart_Post_Protected_No, + RtemsTaskReqRestart_Post_RestartExtensions_Nop } }; static const uint8_t RtemsTaskReqRestart_Map[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, + 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, + 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, + 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 28, 26, 28, 26, 10, 10, + 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10, 0, + 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26, 10, + 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0, 10, + 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30, 27, + 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0, 21, 0, + 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 31, 27, 31, + 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13, 0, + 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, + 14, 0, 14, 0, 10, 0, 10, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, + 14, 0, 28, 26, 28, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, + 0, 20, 0, 20, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 29, 26, 29, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, + 12, 0, 12, 0, 12, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 30, 27, 30, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, + 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 31, 27, 31, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, + 13, 0, 13, 0, 13, 0, 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 28, 26, 28, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, + 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, + 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30, 27, 10, 10, 10, 10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, + 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 31, 27, 31, 27, 10, 10, 10, 10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, + 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0, 10, 0, + 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 28, 26, 28, 26, 10, + 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10, + 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26, + 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0, + 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30, + 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0, + 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 31, + 27, 31, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, + 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, + 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, + 7, 0, 7, 0, 7, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, + 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 16, 16, 16, 16, 10, 10, 10, 10, 17, 17, 17, 17, 18, + 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17, + 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, 10, 10, 10, + 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, + 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, + 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, + 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23, 23, 24, + 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, + 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0, 10, 0, + 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0, + 10, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 16, 16, 16, + 16, 10, 10, 10, 10, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, + 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, + 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 12, 12, 12, 12, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, + 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0, + 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22, + 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10, + 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, + 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, + 0, 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 16, 16, 16, 16, 10, 10, 10, 10, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, + 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, + 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, 10, 10, 10, 10, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 12, 0, 10, 0, 10, 0, + 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 15, 0, 15, 0, 10, 0, + 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 21, 21, 21, + 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, + 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, + 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, + 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0, 10, 0, 14, 0, 14, 0, + 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 16, 16, 16, 16, 10, 10, 10, 10, 17, + 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10, + 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, + 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, + 0, 12, 0, 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23, + 23, 24, 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, + 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0, + 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }; static size_t RtemsTaskReqRestart_Scope( void *arg, char *buf, size_t n ) @@ -665,51 +2556,194 @@ T_TEST_CASE_FIXTURE( RtemsTaskReqRestart, &RtemsTaskReqRestart_Fixture ) ++ctx->pcs[ 0 ] ) { for ( - ctx->pcs[ 1 ] = RtemsTaskReqRestart_Pre_Argument_Pointer; - ctx->pcs[ 1 ] < RtemsTaskReqRestart_Pre_Argument_NA; + ctx->pcs[ 1 ] = RtemsTaskReqRestart_Pre_Dormant_Yes; + ctx->pcs[ 1 ] < RtemsTaskReqRestart_Pre_Dormant_NA; ++ctx->pcs[ 1 ] ) { for ( - ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Dormant_Yes; - ctx->pcs[ 2 ] < RtemsTaskReqRestart_Pre_Dormant_NA; + ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Suspended_Yes; + ctx->pcs[ 2 ] < RtemsTaskReqRestart_Pre_Suspended_NA; ++ctx->pcs[ 2 ] ) { for ( - ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Suspended_Yes; - ctx->pcs[ 3 ] < RtemsTaskReqRestart_Pre_Suspended_NA; + ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Restarting_Yes; + ctx->pcs[ 3 ] < RtemsTaskReqRestart_Pre_Restarting_NA; ++ctx->pcs[ 3 ] ) { - RtemsTaskReqRestart_Entry entry; - size_t pcs[ 4 ]; - - entry = RtemsTaskReqRestart_GetEntry( index ); - ++index; - - memcpy( pcs, ctx->pcs, sizeof( pcs ) ); - - if ( entry.Pre_Dormant_NA ) { - ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Dormant_NA; - } - - if ( entry.Pre_Suspended_NA ) { - ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Suspended_NA; + for ( + ctx->pcs[ 4 ] = RtemsTaskReqRestart_Pre_Terminating_Yes; + ctx->pcs[ 4 ] < RtemsTaskReqRestart_Pre_Terminating_NA; + ++ctx->pcs[ 4 ] + ) { + for ( + ctx->pcs[ 5 ] = RtemsTaskReqRestart_Pre_Protected_Yes; + ctx->pcs[ 5 ] < RtemsTaskReqRestart_Pre_Protected_NA; + ++ctx->pcs[ 5 ] + ) { + for ( + ctx->pcs[ 6 ] = RtemsTaskReqRestart_Pre_Context_Task; + ctx->pcs[ 6 ] < RtemsTaskReqRestart_Pre_Context_NA; + ++ctx->pcs[ 6 ] + ) { + for ( + ctx->pcs[ 7 ] = RtemsTaskReqRestart_Pre_State_Ready; + ctx->pcs[ 7 ] < RtemsTaskReqRestart_Pre_State_NA; + ++ctx->pcs[ 7 ] + ) { + for ( + ctx->pcs[ 8 ] = RtemsTaskReqRestart_Pre_Timer_Inactive; + ctx->pcs[ 8 ] < RtemsTaskReqRestart_Pre_Timer_NA; + ++ctx->pcs[ 8 ] + ) { + for ( + ctx->pcs[ 9 ] = RtemsTaskReqRestart_Pre_RealPriority_Initial; + ctx->pcs[ 9 ] < RtemsTaskReqRestart_Pre_RealPriority_NA; + ++ctx->pcs[ 9 ] + ) { + for ( + ctx->pcs[ 10 ] = RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled; + ctx->pcs[ 10 ] < RtemsTaskReqRestart_Pre_ThreadDispatch_NA; + ++ctx->pcs[ 10 ] + ) { + RtemsTaskReqRestart_Entry entry; + size_t pcs[ 11 ]; + + entry = RtemsTaskReqRestart_GetEntry( index ); + ++index; + + if ( entry.Skip ) { + continue; + } + + memcpy( pcs, ctx->pcs, sizeof( pcs ) ); + + if ( entry.Pre_Dormant_NA ) { + ctx->pcs[ 1 ] = RtemsTaskReqRestart_Pre_Dormant_NA; + } + + if ( entry.Pre_Suspended_NA ) { + ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Suspended_NA; + } + + if ( entry.Pre_Restarting_NA ) { + ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Restarting_NA; + } + + if ( entry.Pre_Terminating_NA ) { + ctx->pcs[ 4 ] = RtemsTaskReqRestart_Pre_Terminating_NA; + } + + if ( entry.Pre_Protected_NA ) { + ctx->pcs[ 5 ] = RtemsTaskReqRestart_Pre_Protected_NA; + } + + if ( entry.Pre_State_NA ) { + ctx->pcs[ 7 ] = RtemsTaskReqRestart_Pre_State_NA; + } + + if ( entry.Pre_Timer_NA ) { + ctx->pcs[ 8 ] = RtemsTaskReqRestart_Pre_Timer_NA; + } + + if ( entry.Pre_RealPriority_NA ) { + ctx->pcs[ 9 ] = RtemsTaskReqRestart_Pre_RealPriority_NA; + } + + RtemsTaskReqRestart_Prepare( ctx ); + RtemsTaskReqRestart_Pre_Id_Prepare( + ctx, + ctx->pcs[ 0 ] + ); + RtemsTaskReqRestart_Pre_Dormant_Prepare( + ctx, + ctx->pcs[ 1 ] + ); + RtemsTaskReqRestart_Pre_Suspended_Prepare( + ctx, + ctx->pcs[ 2 ] + ); + RtemsTaskReqRestart_Pre_Restarting_Prepare( + ctx, + ctx->pcs[ 3 ] + ); + RtemsTaskReqRestart_Pre_Terminating_Prepare( + ctx, + ctx->pcs[ 4 ] + ); + RtemsTaskReqRestart_Pre_Protected_Prepare( + ctx, + ctx->pcs[ 5 ] + ); + RtemsTaskReqRestart_Pre_Context_Prepare( + ctx, + ctx->pcs[ 6 ] + ); + RtemsTaskReqRestart_Pre_State_Prepare( + ctx, + ctx->pcs[ 7 ] + ); + RtemsTaskReqRestart_Pre_Timer_Prepare( + ctx, + ctx->pcs[ 8 ] + ); + RtemsTaskReqRestart_Pre_RealPriority_Prepare( + ctx, + ctx->pcs[ 9 ] + ); + RtemsTaskReqRestart_Pre_ThreadDispatch_Prepare( + ctx, + ctx->pcs[ 10 ] + ); + RtemsTaskReqRestart_Action( ctx ); + RtemsTaskReqRestart_Post_Status_Check( + ctx, + entry.Post_Status + ); + RtemsTaskReqRestart_Post_FatalError_Check( + ctx, + entry.Post_FatalError + ); + RtemsTaskReqRestart_Post_Argument_Check( + ctx, + entry.Post_Argument + ); + RtemsTaskReqRestart_Post_State_Check( + ctx, + entry.Post_State + ); + RtemsTaskReqRestart_Post_Enqueued_Check( + ctx, + entry.Post_Enqueued + ); + RtemsTaskReqRestart_Post_Timer_Check( + ctx, + entry.Post_Timer + ); + RtemsTaskReqRestart_Post_Restarting_Check( + ctx, + entry.Post_Restarting + ); + RtemsTaskReqRestart_Post_Terminating_Check( + ctx, + entry.Post_Terminating + ); + RtemsTaskReqRestart_Post_Protected_Check( + ctx, + entry.Post_Protected + ); + RtemsTaskReqRestart_Post_RestartExtensions_Check( + ctx, + entry.Post_RestartExtensions + ); + RtemsTaskReqRestart_Cleanup( ctx ); + memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) ); + } + } + } + } + } + } } - - RtemsTaskReqRestart_Prepare( ctx ); - RtemsTaskReqRestart_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] ); - RtemsTaskReqRestart_Pre_Argument_Prepare( ctx, ctx->pcs[ 1 ] ); - RtemsTaskReqRestart_Pre_Dormant_Prepare( ctx, ctx->pcs[ 2 ] ); - RtemsTaskReqRestart_Pre_Suspended_Prepare( ctx, ctx->pcs[ 3 ] ); - RtemsTaskReqRestart_Action( ctx ); - RtemsTaskReqRestart_Post_Status_Check( ctx, entry.Post_Status ); - RtemsTaskReqRestart_Post_Argument_Check( ctx, entry.Post_Argument ); - RtemsTaskReqRestart_Post_Unblock_Check( ctx, entry.Post_Unblock ); - RtemsTaskReqRestart_Post_RestartExtensions_Check( - ctx, - entry.Post_RestartExtensions - ); - RtemsTaskReqRestart_Cleanup( ctx ); - memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) ); } } } -- cgit v1.2.3