[rtems-central commit] spec: Specify rtems_task_mode()

Sebastian Huber sebh at rtems.org
Fri Mar 19 14:24:30 UTC 2021


Module:    rtems-central
Branch:    master
Commit:    87bd00f21d1d8f958d10402d9662706941c73419
Changeset: http://git.rtems.org/rtems-central/commit/?id=87bd00f21d1d8f958d10402d9662706941c73419

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Mar 18 09:03:05 2021 +0100

spec: Specify rtems_task_mode()

---

 spec/rtems/task/req/mode.yml | 930 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 930 insertions(+)

diff --git a/spec/rtems/task/req/mode.yml b/spec/rtems/task/req/mode.yml
new file mode 100644
index 0000000..5fc3bc4
--- /dev/null
+++ b/spec/rtems/task/req/mode.yml
@@ -0,0 +1,930 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+functional-type: action
+links:
+- role: interface-function
+  uid: ../if/mode
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      T_rsc_success( ctx->status );
+    text: |
+      The return status of ${../if/mode:/name} shall be
+      ${../../status/if/successful:/name}.
+  - name: InvAddr
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+    text: |
+      The return status of ${../if/mode:/name} shall be
+      ${../../status/if/invalid-address:/name}.
+  - name: NotImplIntLvl
+    test-code: |
+      T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+    text: |
+      The return status of ${../if/mode:/name} shall be
+      ${../../status/if/not-implemented:/name}.
+  - name: NotImplIntLvlSMP
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+      } else {
+        T_rsc_success( ctx->status );
+      }
+    text: |
+      Where the system needs inter-processor interrupts, the return status of
+      ${../if/mode:/name} shall be ${../../status/if/not-implemented:/name}.
+
+      Where the system does not need inter-processor interrupts, the return
+      status of ${../if/mode:/name} shall be
+      ${../../status/if/successful:/name}.
+  - name: NotImplNoPreempt
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+      } else {
+        T_rsc_success( ctx->status );
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, the return
+      status of ${../if/mode:/name} shall be
+      ${../../status/if/not-implemented:/name}.
+
+      Where the scheduler does support the no-preempt mode, the return status
+      of ${../if/mode:/name} shall be ${../../status/if/successful:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Preempt
+  states:
+  - name: 'Yes'
+    test-code: |
+      T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before + 1 );
+    text: |
+      The calling task shall be preempted by a higher priority ready task
+      during the ${../if/mode:/name} call.
+  - name: 'No'
+    test-code: |
+      T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before );
+    text: |
+      The calling task shall not be preempted during the ${../if/mode:/name}
+      call.
+  - name: Maybe
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before );
+      } else {
+        T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before + 1 );
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, the calling
+      task shall not be preempted during the ${../if/mode:/name} call.
+
+      Where the scheduler does support the no-preempt mode, the calling task
+      shall be preempted by a higher priority ready task during the
+      ${../if/mode:/name} call.
+  test-epilogue: null
+  test-prologue: null
+- name: ASR
+  states:
+  - name: 'Yes'
+    test-code: |
+      T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before + 1 );
+    text: |
+      The calling task shall process pending signals during the
+      ${../if/mode:/name} call.
+  - name: 'No'
+    test-code: |
+      T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before );
+    text: |
+      The calling task shall not process signals during the ${../if/mode:/name}
+      call.
+  - name: Maybe
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before );
+      } else {
+        T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before + 1 );
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, the calling
+      task shall not process signals during the ${../if/mode:/name} call.
+
+      Where the scheduler does support the no-preempt mode, the calling task
+      shall process pending signals during the ${../if/mode:/name} call.
+  test-epilogue: null
+  test-prologue: null
+- name: PMVar
+  states:
+  - name: Set
+    test-code: |
+      T_eq_ptr( ctx->previous_mode_set, &ctx->previous_mode_set_value );
+      T_eq_u32( ctx->previous_mode_set_value, ctx->current_mode );
+    text: |
+      The value of the object referenced by the ${../if/mode:/params[2]/name}
+      parameter shall be set to the task modes of the calling task on entry of
+      the call to ${../if/mode:/name}.
+  - name: Nop
+    test-code: |
+      T_eq_u32( ctx->previous_mode_set_value, INVALID_MODE );
+    text: |
+      Objects referenced by the ${../if/create:/params[2]/name} parameter in
+      past calls to ${../if/mode:/name} shall not be accessed by the
+      ${../if/mode:/name} call.
+  - name: Maybe
+    test-code: |
+      T_eq_ptr( ctx->previous_mode_set, &ctx->previous_mode_set_value );
+
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        T_eq_u32( ctx->previous_mode_set_value, INVALID_MODE );
+      } else {
+        T_eq_u32( ctx->previous_mode_set_value, ctx->current_mode );
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, objects
+      referenced by the ${../if/create:/params[2]/name} parameter in past calls
+      to ${../if/mode:/name} shall not be accessed by the ${../if/mode:/name}
+      call.
+
+      Where the scheduler does support the no-preempt mode, the value of the
+      object referenced by the ${../if/mode:/params[2]/name} parameter shall be
+      set to the task modes of the calling task on entry of the call to
+      ${../if/mode:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Mode
+  states:
+  - name: Set
+    test-code: |
+      CheckMode( ctx, ctx->current_mode, ctx->mode_mask, ctx->mode_set );
+    text: |
+      The task modes of the calling task indicated by the
+      ${../if/mode:/params[1]/name} parameter shall be set to the corrsponding
+      modes specified by the ${../if/mode:/params[0]/name} parameter.
+  - name: Nop
+    test-code: |
+      CheckMode( ctx, ctx->current_mode, 0, 0 );
+    text: |
+      The task modes of the calling task shall not be modified by the
+      ${../if/mode:/name} call.
+  - name: Maybe
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        CheckMode( ctx, ctx->current_mode, 0, 0 );
+      } else {
+        CheckMode( ctx, ctx->current_mode, ctx->mode_mask, ctx->mode_set );
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, the task modes
+      of the calling task shall not be modified by the ${../if/mode:/name}
+      call.
+
+      Where the scheduler does support the no-preempt mode, the task modes of
+      the calling task indicated by the ${../if/mode:/params[1]/name} parameter
+      shall be set to the corrsponding modes specified by the
+      ${../if/mode:/params[0]/name} parameter.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: PrevMode
+  states:
+  - name: Valid
+    test-code: |
+      ctx->previous_mode_set = &ctx->previous_mode_set_value;
+    text: |
+      While the ${../if/mode:/params[2]/name} parameter references an object of
+      type ${../../mode/if/mode:/name}.
+  - name: 'Null'
+    test-code: |
+      ctx->previous_mode_set = NULL;
+    text: |
+      While the ${../if/mode:/params[2]/name} parameter is ${/c/if/null:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: PreemptCur
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->current_mode |= RTEMS_PREEMPT;
+    text: |
+      While the calling task has preemption enabled.
+  - name: 'No'
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        ctx->current_mode |= RTEMS_PREEMPT;
+      } else {
+        ctx->current_mode |= RTEMS_NO_PREEMPT;
+      }
+    text: |
+      Where the scheduler does not support the no-preempt mode, while the
+      calling task has preemption enabled.
+
+      Where the scheduler does support the no-preempt mode, while the calling
+      task has preemption disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: TimesliceCur
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->current_mode |= RTEMS_TIMESLICE;
+    text: |
+      While the calling task has timeslicing enabled.
+  - name: 'No'
+    test-code: |
+      ctx->current_mode |= RTEMS_NO_TIMESLICE;
+    text: |
+      While the calling task has timeslicing disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: ASRCur
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->current_mode |= RTEMS_ASR;
+    text: |
+      While the calling task has ASR processing enabled.
+  - name: 'No'
+    test-code: |
+      ctx->current_mode |= RTEMS_NO_ASR;
+    text: |
+      While the calling task has ASR processing disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: IntLvlCur
+  states:
+  - name: Zero
+    test-code: |
+      ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 0 );
+    text: |
+      While the calling task executes with an interrupt level of zero.
+  - name: Positive
+    test-code: |
+      if ( rtems_configuration_get_maximum_processors() > 1 ) {
+        ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 0 );
+      } else {
+        ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 1 );
+      }
+    text: |
+      Where the system needs inter-processor interrupts, while the calling task
+      executes with an interrupt level of zero.
+
+      Where the system does not need inter-processor interrupts, while the
+      calling task executes with an an interrupt level greater than zero and
+      less than or equal to ${/score/cpu/if/modes-interrupt-mask:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Preempt
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_set |= RTEMS_PREEMPT;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      preemption is enabled.
+  - name: 'No'
+    test-code: |
+      ctx->mode_set |= RTEMS_NO_PREEMPT;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      preemption is disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: Timeslice
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_set |= RTEMS_TIMESLICE;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      timeslicing is enabled.
+  - name: 'No'
+    test-code: |
+      ctx->mode_set |= RTEMS_NO_TIMESLICE;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      timeslicing is disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: ASR
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_set |= RTEMS_ASR;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      ASR processing is enabled.
+  - name: 'No'
+    test-code: |
+      ctx->mode_set |= RTEMS_NO_ASR;
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies that
+      ASR processing is disabled.
+  test-epilogue: null
+  test-prologue: null
+- name: IntLvl
+  states:
+  - name: Zero
+    test-code: |
+      ctx->mode_set |= RTEMS_INTERRUPT_LEVEL( 0 );
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies an interrupt
+      level of zero.
+  - name: Positive
+    test-code: |
+      ctx->mode_set |= RTEMS_INTERRUPT_LEVEL( 1 );
+    text: |
+      While the ${../if/mode:/params[0]/name} parameter specifies an interrupt
+      level greater than zero and less than or equal to
+      ${/score/cpu/if/modes-interrupt-mask:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: PreemptMsk
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_mask |= RTEMS_PREEMPT_MASK;
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      preemption mode shall be set.
+  - name: 'No'
+    test-code: |
+      /* This is the default mode mask */
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      preemption mode shall not be set.
+  test-epilogue: null
+  test-prologue: null
+- name: TimesliceMsk
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_mask |= RTEMS_TIMESLICE_MASK;
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      timeslicing mode shall be set.
+  - name: 'No'
+    test-code: |
+      /* This is the default mode mask */
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      timeslicing mode shall not be set.
+  test-epilogue: null
+  test-prologue: null
+- name: ASRMsk
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_mask |= RTEMS_ASR_MASK;
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      ASR processing mode shall be set.
+  - name: 'No'
+    test-code: |
+      /* This is the default mode mask */
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      ASR processing mode shall not be set.
+  test-epilogue: null
+  test-prologue: null
+- name: IntLvlMsk
+  states:
+  - name: 'Yes'
+    test-code: |
+      ctx->mode_mask |= RTEMS_INTERRUPT_MASK;
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      interrupt level shall be set.
+  - name: 'No'
+    test-code: |
+      /* This is the default mode mask */
+    text: |
+      While the ${../if/mode:/params[1]/name} parameter specifies that the
+      interrupt level shall not be set.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+  RobustThreadDispatching: |
+    Where the system enabled robust thread dispatching, the interrupt level
+    mode of a task shall be exactly zero.
+test-action: |
+  rtems_status_code sc;
+  rtems_mode        mode;
+
+  sc = rtems_task_mode( ctx->current_mode, RTEMS_ALL_MODE_MASKS, &mode );
+  T_rsc_success( sc );
+
+  SendEvent( ctx, EVENT_MAKE_READY );
+
+  sc = rtems_signal_catch( SignalHandler, ctx->current_mode | RTEMS_NO_ASR );
+  T_rsc_success( sc );
+
+  sc = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
+  T_rsc_success( sc );
+
+  ctx->worker_counter_before = ctx->worker_counter;
+  ctx->signal_counter_before = ctx->signal_counter;
+  ctx->status = rtems_task_mode(
+    ctx->mode_set,
+    ctx->mode_mask,
+    ctx->previous_mode_set
+  );
+  ctx->worker_counter_after = ctx->worker_counter;
+  ctx->signal_counter_after = ctx->signal_counter;
+test-brief: null
+test-cleanup: |
+  rtems_status_code sc;
+  rtems_mode        mode;
+
+  sc = rtems_task_mode( RTEMS_DEFAULT_MODES, RTEMS_ALL_MODE_MASKS, &mode );
+  T_rsc_success( sc );
+
+  sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
+  T_rsc_success( sc );
+
+  sc = rtems_signal_catch( NULL, RTEMS_DEFAULT_MODES );
+  T_rsc_success( sc );
+test-context:
+- brief: |
+    This member contains the object identifier of the worker task.
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: null
+    If this member is contains the initial mode of the runner.
+  description: null
+  member: |
+    rtems_mode runner_mode
+- brief: |
+    This member provides a value for the previous mode set.
+  description: null
+  member: |
+    rtems_mode previous_mode_set_value
+- brief: |
+    This member specifies the task mode in which rtems_task_mode() is called.
+  description: null
+  member: |
+    rtems_mode current_mode
+- brief: |
+    This member counts worker activity.
+  description: null
+  member: |
+    uint32_t worker_counter
+- brief: |
+    This member contains worker counter before the rtems_task_mode() call.
+  description: null
+  member: |
+    uint32_t worker_counter_before
+- brief: |
+    This member contains worker counter after the rtems_task_mode() call.
+  description: null
+  member: |
+    uint32_t worker_counter_after
+- brief: |
+    This member counts signal handler activity.
+  description: null
+  member: |
+    uint32_t signal_counter
+- brief: |
+    This member contains signal counter before the rtems_task_mode() call.
+  description: null
+  member: |
+    uint32_t signal_counter_before
+- brief: |
+    This member contains signal counter after the rtems_task_mode() call.
+  description: null
+  member: |
+    uint32_t signal_counter_after
+- brief: |
+    This member specifies the ${../if/mode:/params[0]/name} parameter for
+    rtems_task_mode().
+  description: null
+  member: |
+    rtems_mode mode_set
+- brief: |
+    This member specifies the mode mask ${../if/mode:/params[1]/name} parameter
+    for rtems_task_mode() for the action.
+  description: null
+  member: |
+    rtems_mode mode_mask
+- brief: |
+    This member specifies the previous mode set ${../if/mode:/params[2]/name}
+    parameter for rtems_task_mode().
+  description: null
+  member: |
+    rtems_mode *previous_mode_set
+- brief: |
+    This member contains the return status of the rtems_task_mode() call.
+  description: null
+  member: |
+    rtems_status_code status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- string.h
+- rtems/score/percpu.h
+- rtems/score/threaddispatch.h
+- rtems/score/watchdogimpl.h
+test-local-includes: []
+test-prepare: |
+  ctx->current_mode = RTEMS_DEFAULT_MODES;
+  ctx->mode_set = RTEMS_DEFAULT_MODES;
+  ctx->mode_mask = RTEMS_CURRENT_MODE;
+  ctx->previous_mode_set_value = INVALID_MODE;
+test-setup:
+  brief: null
+  code: |
+    rtems_status_code sc;
+
+    memset( ctx, 0, sizeof( *ctx ) );
+
+    sc = rtems_task_mode(
+      RTEMS_DEFAULT_MODES,
+      RTEMS_CURRENT_MODE,
+      &ctx->runner_mode
+    );
+    T_rsc_success( sc );
+
+    SetPriority( PRIO_NORMAL );
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_HIGH,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start(
+      ctx->worker_id,
+      Worker,
+      (rtems_task_argument) ctx
+    );
+    T_assert_rsc_success( sc );
+  description: null
+test-stop: null
+test-support: |
+  #define INVALID_MODE 0xffffffff
+
+  #define EVENT_MAKE_READY RTEMS_EVENT_0
+
+  #define EVENT_TIMESLICE RTEMS_EVENT_1
+
+  typedef RtemsTaskReqMode_Context Context;
+
+  typedef enum {
+    PRIO_HIGH = 1,
+    PRIO_NORMAL
+  } Priority;
+
+  static void SendEvent( Context *ctx, rtems_event_set event )
+  {
+    rtems_status_code sc;
+
+    sc = rtems_event_send( ctx->worker_id, event );
+    T_rsc_success( sc );
+  }
+
+  static void SetPriority( Priority priority )
+  {
+    rtems_status_code   sc;
+    rtems_task_priority previous;
+
+    sc = rtems_task_set_priority( RTEMS_SELF, priority, &previous );
+    T_rsc_success( sc );
+  }
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_status_code sc;
+      rtems_event_set   events;
+
+      events = 0;
+      sc = rtems_event_receive(
+        RTEMS_ALL_EVENTS,
+        RTEMS_EVENT_ANY | RTEMS_WAIT,
+        RTEMS_NO_TIMEOUT,
+        &events
+      );
+      T_rsc_success( sc );
+
+      if ( ( events & EVENT_TIMESLICE ) != 0 ) {
+        SetPriority( PRIO_NORMAL );
+        SetPriority( PRIO_HIGH );
+      }
+
+      ++ctx->worker_counter;
+    }
+  }
+
+  static void SignalHandler( rtems_signal_set signal_set )
+  {
+    Context *ctx;
+
+    ctx = T_fixture_context();
+    ++ctx->signal_counter;
+    T_eq_u32( signal_set, 0xdeadbeef );
+  }
+
+  static void ExhaustTimeslice( void )
+  {
+    Per_CPU_Control *cpu_self;
+    uint32_t         ticks;
+
+    cpu_self = _Thread_Dispatch_disable();
+
+    for (
+      ticks = 0;
+      ticks < rtems_configuration_get_ticks_per_timeslice();
+      ++ticks
+    ) {
+      uint32_t cpu_index;
+
+      for (
+        cpu_index = 0;
+        cpu_index < rtems_scheduler_get_processor_maximum();
+        ++cpu_index
+      ) {
+        _Watchdog_Tick( _Per_CPU_Get_by_index( cpu_index ) );
+      }
+    }
+
+    _Thread_Dispatch_enable( cpu_self );
+  }
+
+  static void CheckMode(
+    Context   *ctx,
+    rtems_mode mode,
+    rtems_mode mask,
+    rtems_mode set
+  )
+  {
+    rtems_status_code sc;
+    uint32_t          counter;
+
+    mode &= ~mask;
+    mode |= set & mask;
+
+    counter = ctx->worker_counter;
+    SendEvent( ctx, EVENT_MAKE_READY );
+
+    if ( ( mode & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ) {
+      T_eq_u32( ctx->worker_counter, counter + 1 );
+    } else {
+      T_eq_u32( ctx->worker_counter, counter );
+    }
+
+    counter = ctx->worker_counter;
+    SendEvent( ctx, EVENT_TIMESLICE );
+    ExhaustTimeslice();
+
+    if ( ( mode & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ) {
+      if ( ( mode & RTEMS_TIMESLICE_MASK ) == RTEMS_TIMESLICE ) {
+        T_eq_u32( ctx->worker_counter, counter + 1 );
+      } else {
+        T_eq_u32( ctx->worker_counter, counter );
+      }
+    } else {
+      T_eq_u32( ctx->worker_counter, counter );
+    }
+
+    counter = ctx->signal_counter;
+    sc = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
+    T_rsc_success( sc );
+
+    if ( ( mode & RTEMS_ASR_MASK ) == RTEMS_ASR ) {
+      T_eq_u32( ctx->signal_counter, counter + 1 );
+    } else {
+      T_eq_u32( ctx->signal_counter, counter );
+    }
+
+    T_eq_u32( mode & RTEMS_INTERRUPT_MASK, _ISR_Get_level() );
+  }
+test-target: testsuites/validation/tc-task-mode.c
+test-teardown:
+  brief: null
+  code: |
+    rtems_status_code sc;
+
+    if ( ctx->worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->worker_id );
+      T_rsc_success( sc );
+    }
+
+    sc = rtems_task_mode(
+      ctx->runner_mode,
+      RTEMS_ALL_MODE_MASKS,
+      &ctx->runner_mode
+    );
+    T_rsc_success( sc );
+
+    SetPriority( PRIO_HIGH );
+  description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status:
+    - if:
+        pre-conditions:
+          PrevMode: 'Null'
+      then: InvAddr
+    - else: Ok
+    Preempt:
+    - if:
+        and:
+        - post-conditions:
+            Status: Ok
+        - pre-conditions:
+            PreemptCur: 'No'
+            Preempt: 'Yes'
+            PreemptMsk: 'Yes'
+      then: 'Yes'
+    - else: 'No'
+    ASR:
+    - if:
+        and:
+        - post-conditions:
+            Status: Ok
+        - pre-conditions:
+            ASRCur: 'No'
+            ASR: 'Yes'
+            ASRMsk: 'Yes'
+      then: 'Yes'
+    - else: 'No'
+    PMVar:
+    - if:
+        pre-conditions:
+          PrevMode: 'Null'
+      then: Nop
+    - else: Set
+    Mode:
+    - if:
+        pre-conditions:
+          PrevMode: 'Null'
+      then: Nop
+    - else: Set
+  pre-conditions:
+    PreemptCur: all
+    TimesliceCur: all
+    ASRCur: all
+    IntLvlCur: all
+    Preempt: all
+    Timeslice: all
+    ASR: all
+    IntLvl: all
+    PreemptMsk: all
+    TimesliceMsk: all
+    ASRMsk: all
+    IntLvlMsk: all
+    PrevMode: all
+- enabled-by: CPU_ENABLE_ROBUST_THREAD_DISPATCH
+  post-conditions:
+    Status: NotImplIntLvl
+    Preempt: 'No'
+    ASR: 'No'
+    PMVar: Nop
+    Mode: Nop
+  pre-conditions:
+    PreemptCur: all
+    TimesliceCur: all
+    ASRCur: all
+    IntLvlCur:
+    - Zero
+    Preempt: all
+    Timeslice: all
+    ASR: all
+    IntLvl:
+    - Positive
+    PreemptMsk: all
+    TimesliceMsk: all
+    ASRMsk: all
+    IntLvlMsk:
+    - 'Yes'
+    PrevMode:
+    - Valid
+- enabled-by: CPU_ENABLE_ROBUST_THREAD_DISPATCH
+  post-conditions: RobustThreadDispatching
+  pre-conditions:
+    PreemptCur: all
+    TimesliceCur: all
+    ASRCur: all
+    IntLvlCur:
+    - Positive
+    Preempt: all
+    Timeslice: all
+    ASR: all
+    IntLvl: all
+    PreemptMsk: all
+    TimesliceMsk: all
+    ASRMsk: all
+    IntLvlMsk: all
+    PrevMode: all
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Status:
+    - if:
+        pre-conditions:
+          Preempt: 'No'
+          PreemptMsk: 'Yes'
+      then: NotImplNoPreempt
+    - if:
+        pre-conditions:
+          IntLvl: Positive
+          IntLvlMsk: 'Yes'
+      then: NotImplIntLvlSMP
+    - else: Ok
+    Preempt:
+    - if:
+        pre-conditions:
+          PreemptCur: 'No'
+          Preempt: 'Yes'
+          PreemptMsk: 'Yes'
+      then: Maybe
+    - else: 'No'
+    ASR:
+    - if:
+        and:
+          - pre-conditions:
+              ASRCur: 'No'
+              ASR: 'Yes'
+              ASRMsk: 'Yes'
+          - or:
+            - pre-conditions:
+                Preempt: 'No'
+                PreemptMsk: 'Yes'
+            - pre-conditions:
+                IntLvl: Positive
+                IntLvlMsk: 'Yes'
+      then: Maybe
+    - if:
+        and:
+          - pre-conditions:
+              ASRCur: 'No'
+              ASR: 'Yes'
+              ASRMsk: 'Yes'
+          - or:
+            - pre-conditions:
+                PreemptMsk: 'No'
+                IntLvlMsk: 'No'
+            - pre-conditions:
+                Preempt: 'Yes'
+                IntLvlMsk: 'No'
+            - pre-conditions:
+                PreemptMsk: 'No'
+                IntLvl: Zero
+            - pre-conditions:
+                Preempt: 'Yes'
+                IntLvl: Zero
+      then: 'Yes'
+    - else: 'No'
+    PMVar:
+    - if:
+      - pre-conditions:
+          Preempt: 'No'
+          PreemptMsk: 'Yes'
+      - pre-conditions:
+          IntLvl: Positive
+          IntLvlMsk: 'Yes'
+      then: Maybe
+    - else: Set
+    Mode:
+    - if:
+      - pre-conditions:
+          Preempt: 'No'
+          PreemptMsk: 'Yes'
+      - pre-conditions:
+          IntLvl: Positive
+          IntLvlMsk: 'Yes'
+      then: Maybe
+    - else: Set
+  pre-conditions:
+    PreemptCur: all
+    TimesliceCur: all
+    ASRCur: all
+    IntLvlCur: all
+    Preempt: all
+    Timeslice: all
+    ASR: all
+    IntLvl: all
+    PreemptMsk: all
+    TimesliceMsk: all
+    ASRMsk: all
+    IntLvlMsk: all
+    PrevMode:
+    - Valid
+type: requirement



More information about the vc mailing list