[rtems-central commit] spec: Specify signal manager
Sebastian Huber
sebh at rtems.org
Fri Feb 19 06:05:32 UTC 2021
Module: rtems-central
Branch: master
Commit: b70d121ac69f6e627481d25ecf7d22eeb690ba0c
Changeset: http://git.rtems.org/rtems-central/commit/?id=b70d121ac69f6e627481d25ecf7d22eeb690ba0c
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Mon Feb 15 14:02:22 2021 +0100
spec: Specify signal manager
---
spec/rtems/signal/req/catch.yml | 982 ++++++++++++++++++++++++++++++++++++++++
spec/rtems/signal/req/send.yml | 647 ++++++++++++++++++++++++++
2 files changed, 1629 insertions(+)
diff --git a/spec/rtems/signal/req/catch.yml b/spec/rtems/signal/req/catch.yml
new file mode 100644
index 0000000..fb1509c
--- /dev/null
+++ b/spec/rtems/signal/req/catch.yml
@@ -0,0 +1,982 @@
+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/catch
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->catch_status );
+ text: |
+ The return status of ${../if/catch:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: NotImplNoPreempt
+ test-code: |
+ #if defined(RTEMS_SMP)
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
+ } else {
+ T_rsc_success( ctx->catch_status );
+ }
+ #else
+ T_rsc_success( ctx->catch_status );
+ #endif
+ text: |
+ Where the system is configured with SMP support, if the scheduler does
+ not support the no-preempt mode, then the return status of
+ ${../if/catch:/name} shall be ${../../status/if/not-implemented:/name},
+ otherwise the return status shall be ${../../status/if/successful:/name}.
+ - name: NotImplIntLvl
+ test-code: |
+ #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
+ #elif defined(RTEMS_SMP)
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
+ } else {
+ T_rsc_success( ctx->catch_status );
+ }
+ #else
+ T_rsc_success( ctx->catch_status );
+ #endif
+ text: |
+ Where the system is configured with SMP support and the configured
+ processor maximum is greater than one, or the CPU port enabled robust
+ thread dispatching, the return status of ${../if/catch:/name} shall be
+ ${../../status/if/not-implemented:/name}, otherwise the return status
+ shall be ${../../status/if/successful:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Send
+ states:
+ - name: New
+ test-code: |
+ T_rsc_success( ctx->send_status );
+
+ if ( ctx->catch_status == RTEMS_SUCCESSFUL ) {
+ T_eq_u32( ctx->default_handler_calls, 0 );
+ T_eq_u32( ctx->handler_calls, 1 );
+ T_ne_u32( ctx->handler_mode, 0xffffffff );
+ } else {
+ T_eq_u32( ctx->default_handler_calls, 1 );
+ T_eq_u32( ctx->handler_calls, 0 );
+ T_eq_u32( ctx->handler_mode, 0xffffffff );
+ }
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call was successful, the ASR processing shall be done with the specified
+ handler, otherwise the ASR information of the caller shall be unchanged.
+ - name: NotDef
+ test-code: |
+ if ( ctx->catch_status == RTEMS_SUCCESSFUL ) {
+ T_rsc( ctx->send_status, RTEMS_NOT_DEFINED );
+ T_eq_u32( ctx->default_handler_calls, 0 );
+ T_eq_u32( ctx->handler_calls, 0 );
+ T_eq_u32( ctx->handler_mode, 0xffffffff );
+ } else {
+ T_rsc_success( ctx->send_status );
+ T_eq_u32( ctx->default_handler_calls, 1 );
+ T_eq_u32( ctx->handler_calls, 0 );
+ T_eq_u32( ctx->handler_mode, 0xffffffff );
+ }
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call was successful, the ASR processing shall be deactivated and all
+ pending signals shall be cleared, otherwise the ASR information of the
+ caller shall be unchanged.
+ test-epilogue: null
+ test-prologue: null
+- name: Preempt
+ states:
+ - name: 'Yes'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_PREEMPT_MASK, RTEMS_PREEMPT );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with preemption enabled.
+ - name: 'No'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_PREEMPT_MASK, RTEMS_NO_PREEMPT );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with preemption disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: Timeslice
+ states:
+ - name: 'Yes'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_TIMESLICE_MASK, RTEMS_TIMESLICE );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with timeslicing enabled.
+ - name: 'No'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_TIMESLICE_MASK, RTEMS_NO_TIMESLICE );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with timeslicing disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: ASR
+ states:
+ - name: 'Yes'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_ASR_MASK, RTEMS_ASR );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with ASR processing enabled.
+ - name: 'No'
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_ASR_MASK, RTEMS_NO_ASR );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with ASR processing disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: IntLvl
+ states:
+ - name: Zero
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_INTERRUPT_MASK, RTEMS_INTERRUPT_LEVEL( 0 ) );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with interrupts enabled.
+ - name: Positive
+ test-code: |
+ CheckHandlerMode( ctx, RTEMS_INTERRUPT_MASK, RTEMS_INTERRUPT_LEVEL( 1 ) );
+ text: |
+ When a signal set is sent to the caller of ${../if/catch:/name} and the
+ call with a valid handler was successful, the ASR processing shall be
+ done with interrupts disabled according to the specified interrupt level.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Handler
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->handler = NULL;
+ text: |
+ The ${../if/catch:/params[0]/name} parameter shall be ${/c/if/null:/name}.
+ - name: Valid
+ test-code: |
+ ctx->handler = SignalHandler;
+ text: |
+ The ${../if/catch:/params[0]/name} parameter shall be a valid ASR handler.
+ test-epilogue: null
+ test-prologue: null
+- name: Preempt
+ states:
+ - name: 'Yes'
+ test-code: |
+ #if defined(RTEMS_SMP)
+ if ( rtems_configuration_get_maximum_processors() == 1 ) {
+ ctx->normal_mode |= RTEMS_NO_PREEMPT;
+ }
+ #else
+ ctx->normal_mode |= RTEMS_NO_PREEMPT;
+ #endif
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ preemption is enabled.
+ - name: 'No'
+ test-code: |
+ ctx->mode |= RTEMS_NO_PREEMPT;
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ preemption is disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: Timeslice
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->mode |= RTEMS_TIMESLICE;
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ timeslicing is enabled.
+ - name: 'No'
+ test-code: |
+ ctx->normal_mode |= RTEMS_TIMESLICE;
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ timeslicing is disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: ASR
+ states:
+ - name: 'Yes'
+ test-code: |
+ /* We cannot disable ASR processing at normal task level for this test */
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ ASR processing is enabled.
+ - name: 'No'
+ test-code: |
+ ctx->mode |= RTEMS_NO_ASR;
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify that
+ ASR processing is disabled.
+ test-epilogue: null
+ test-prologue: null
+- name: IntLvl
+ states:
+ - name: Zero
+ test-code: |
+ #if !defined(RTEMS_SMP) && CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+ ctx->normal_mode |= RTEMS_INTERRUPT_LEVEL( 1 );
+ #endif
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify an interrupt
+ level of zero.
+ - name: Positive
+ test-code: |
+ ctx->mode |= RTEMS_INTERRUPT_LEVEL( 1 );
+ text: |
+ The ${../if/catch:/params[1]/name} parameter shall specify a positive
+ interrupt level.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ rtems_status_code sc;
+ rtems_mode mode;
+
+ ctx->catch_status = rtems_signal_catch( ctx->handler, ctx->mode );
+
+ sc = rtems_task_mode( ctx->normal_mode, RTEMS_ALL_MODE_MASKS, &mode );
+ T_rsc_success( sc );
+
+ ctx->send_status = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
+
+ sc = rtems_task_mode( mode, RTEMS_ALL_MODE_MASKS, &mode );
+ T_rsc_success( sc );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: null
+ description: null
+ member: |
+ uint32_t default_handler_calls
+- brief: null
+ description: null
+ member: |
+ uint32_t handler_calls
+- brief: null
+ description: null
+ member: |
+ rtems_mode handler_mode
+- brief: null
+ description: null
+ member: |
+ rtems_mode normal_mode
+- brief: null
+ description: null
+ member: |
+ rtems_asr_entry handler
+- brief: null
+ description: null
+ member: |
+ rtems_mode mode
+- brief: null
+ description: null
+ member: |
+ rtems_status_code catch_status
+- brief: null
+ description: null
+ member: |
+ rtems_status_code send_status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes: []
+test-prepare: |
+ rtems_status_code sc;
+
+ ctx->default_handler_calls = 0;
+ ctx->handler_calls = 0;
+ ctx->handler_mode = 0xffffffff;
+ ctx->normal_mode = RTEMS_DEFAULT_MODES;
+ ctx->handler = NULL;
+ ctx->mode = RTEMS_DEFAULT_MODES;
+
+ sc = rtems_signal_catch( DefaultHandler, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+test-setup: null
+test-stop: null
+test-support: |
+ typedef RtemsSignalReqCatch_Context Context;
+
+ static void DefaultHandler( rtems_signal_set signal_set )
+ {
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->default_handler_calls;
+
+ T_eq_u32( signal_set, 0xdeadbeef );
+ }
+
+ static void SignalHandler( rtems_signal_set signal_set )
+ {
+ Context *ctx;
+ rtems_status_code sc;
+
+ ctx = T_fixture_context();
+ ++ctx->handler_calls;
+
+ sc = rtems_task_mode(
+ RTEMS_DEFAULT_MODES,
+ RTEMS_CURRENT_MODE,
+ &ctx->handler_mode
+ );
+ T_rsc_success( sc );
+
+ T_eq_u32( signal_set, 0xdeadbeef );
+ }
+
+ static void CheckHandlerMode( Context *ctx, rtems_mode mask, rtems_mode mode )
+ {
+ if ( ctx->catch_status == RTEMS_SUCCESSFUL && ctx->handler != NULL ) {
+ T_ne_u32( ctx->handler_mode, 0xffffffff );
+ T_eq_u32( ctx->handler_mode & mask, mode );
+ }
+ }
+test-target: testsuites/validation/tc-signal-catch.c
+test-teardown:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_signal_catch( NULL, RTEMS_DEFAULT_MODES );
+ T_rsc_success( sc );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: NotDef
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Invalid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'Yes'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'Yes'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'Yes'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'Yes'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'Yes'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'Yes'
+ IntLvl:
+ - Positive
+- enabled-by: true
+ post-conditions:
+ Status: NotImplNoPreempt
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Zero
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Zero
+- enabled-by: true
+ post-conditions:
+ Status: NotImplIntLvl
+ Send: New
+ Preempt: 'No'
+ Timeslice: 'No'
+ ASR: 'No'
+ IntLvl: Positive
+ pre-conditions:
+ Handler:
+ - Valid
+ Preempt:
+ - 'No'
+ Timeslice:
+ - 'No'
+ ASR:
+ - 'No'
+ IntLvl:
+ - Positive
+type: requirement
diff --git a/spec/rtems/signal/req/send.yml b/spec/rtems/signal/req/send.yml
new file mode 100644
index 0000000..ff74b14
--- /dev/null
+++ b/spec/rtems/signal/req/send.yml
@@ -0,0 +1,647 @@
+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/send
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/send:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvNum
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ text: |
+ The return status of ${../if/send:/name} shall be
+ ${../../status/if/invalid-number:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/send:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: NotDef
+ test-code: |
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ text: |
+ The return status of ${../if/send:/name} shall be
+ ${../../status/if/not-defined:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Handler
+ states:
+ - name: NoCall
+ test-code: |
+ T_eq_sz( ctx->calls_after_send, ctx->nested );
+ T_eq_sz( ctx->calls_after_dispatch, ctx->nested );
+ T_eq_sz( ctx->calls_after_enable, ctx->nested );
+ text: |
+ While the ASR processing is disabled, the ASR handler shall not be
+ called.
+ - name: DuringSend
+ test-code: |
+ ++expected_calls;
+ T_eq_sz( ctx->calls_after_send, ctx->nested + 1 );
+ T_eq_sz( ctx->calls_after_dispatch, ctx->nested + 1 );
+ T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
+ text: |
+ The ASR handler shall be called during the ${../if/send:/name} call.
+ - name: AfterDispatch
+ test-code: |
+ ++expected_calls;
+ T_eq_sz( ctx->calls_after_send, ctx->nested );
+ T_eq_sz( ctx->calls_after_dispatch, ctx->nested + 1 );
+ T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
+ text: |
+ When the next thread dispatch of the target task of the
+ ${../if/send:/name} call takes place, the ASR handler shall be called.
+ - name: AfterEnable
+ test-code: |
+ ++expected_calls;
+ T_eq_sz( ctx->calls_after_send, ctx->nested );
+ T_eq_sz( ctx->calls_after_dispatch, ctx->nested );
+ T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
+ text: |
+ When the target task of the ${../if/send:/name} call re-enables ASR
+ processing, the ASR handler shall be called.
+ test-epilogue: |
+ T_eq_sz( ctx->handler_calls, expected_calls );
+
+ if ( ctx->nested != 0 ) {
+ T_eq_u32( ctx->processed_signal_sets[ 0 ], 0x600df00d );
+ }
+
+ if ( expected_calls > ctx->nested ) {
+ T_eq_u32( ctx->processed_signal_sets[ ctx->nested ], 0xdeadbeef );
+ }
+ test-prologue: |
+ size_t expected_calls;
+
+ expected_calls = ctx->nested;
+- name: Recursive
+ states:
+ - name: 'Yes'
+ test-code: |
+ T_eq_sz( ctx->handler_calls, 2 );
+ T_ne_uptr( ctx->stack_pointers[ 0 ], 0 );
+ T_ne_uptr( ctx->stack_pointers[ 1 ], 0 );
+ T_ne_uptr( ctx->stack_pointers[ 0 ], ctx->stack_pointers[ 1 ] );
+ text: |
+ The ASR handler shall be called recursively.
+ - name: 'No'
+ test-code: |
+ if ( ctx->handler_calls == 2 ) {
+ T_ne_uptr( ctx->stack_pointers[ 0 ], 0 );
+ T_ne_uptr( ctx->stack_pointers[ 1 ], 0 );
+ T_eq_uptr( ctx->stack_pointers[ 0 ], ctx->stack_pointers[ 1 ] );
+ }
+ text: |
+ The ASR handler shall not be called recursively.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Task
+ states:
+ - name: NoObj
+ test-code: |
+ ctx->id = 0xffffffff;
+ text: |
+ The ${../if/send:/params[0]/name} parameter shall be invalid.
+ - name: Self
+ test-code: |
+ ctx->id = RTEMS_SELF;
+ text: |
+ The ${../if/send:/params[0]/name} parameter shall be associated with
+ the calling task.
+ - name: Other
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ The ${../if/send:/params[0]/name} parameter shall be associated with a
+ task other than the calling task.
+ test-epilogue: null
+ test-prologue: null
+- name: Set
+ states:
+ - name: Zero
+ test-code: |
+ ctx->signal_set = 0;
+ text: |
+ The ${../if/send:/params[1]/name} parameter shall be zero.
+ - name: NonZero
+ test-code: |
+ ctx->signal_set = 0xdeadbeef;
+ text: |
+ The ${../if/send:/params[1]/name} parameter shall be non-zero.
+ test-epilogue: null
+ test-prologue: null
+- name: Handler
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->handler = NULL;
+ text: |
+ When the target task has no valid ASR handler installed, the
+ ${../if/send:/name} directive shall be called.
+ - name: Valid
+ test-code: |
+ ctx->handler = SignalHandler;
+ text: |
+ When the target task has a valid ASR handler installed, the
+ ${../if/send:/name} directive shall be called.
+ test-epilogue: null
+ test-prologue: null
+- name: ASR
+ states:
+ - name: Enabled
+ test-code: |
+ ctx->mode = RTEMS_DEFAULT_MODES;
+ text: |
+ When the target task has ASR processing enabled, the ${../if/send:/name}
+ directive shall be called.
+ - name: Disabled
+ test-code: |
+ ctx->mode = RTEMS_NO_ASR;
+ text: |
+ When the target task has ASR processing disabled, the ${../if/send:/name}
+ directive shall be called.
+ test-epilogue: null
+ test-prologue: null
+- name: Nested
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->nested = 1;
+ text: |
+ When the target task processes an asynchronous signal set, the
+ ${../if/send:/name} directive shall be called.
+ - name: 'No'
+ test-code: |
+ ctx->nested = 0;
+ text: |
+ When the target task does not process an asynchronous signal set, the
+ ${../if/send:/name} directive shall be called.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ rtems_status_code sc;
+
+ if ( ctx->id == ctx->worker_id ) {
+ SendEventsToWorker( ctx, EVENT_START );
+
+ ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
+ ctx->calls_after_send = ctx->handler_calls;
+
+ SendEventsToWorker( ctx, EVENT_SEND_DONE );
+ ctx->calls_after_dispatch = ctx->handler_calls;
+ SendEventsToWorker( ctx, EVENT_DO_ENABLE );
+ ctx->calls_after_enable = ctx->handler_calls;
+ SendEventsToWorker( ctx, EVENT_END );
+ } else if ( ctx->nested != 0 ) {
+ sc = rtems_signal_catch( SignalHandler, ctx->mode );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_send( RTEMS_SELF, 0x600df00d );
+ T_rsc_success( sc );
+
+ ctx->calls_after_enable = ctx->handler_calls;
+ } else {
+ rtems_mode mode;
+
+ sc = rtems_task_mode( ctx->mode, RTEMS_ASR_MASK, &mode );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
+ ctx->calls_after_send = ctx->handler_calls;
+ ctx->calls_after_dispatch = ctx->handler_calls;
+
+ sc = rtems_task_mode( mode, RTEMS_ASR_MASK, &mode );
+ T_rsc_success( sc );
+
+ ctx->calls_after_enable = ctx->handler_calls;
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: null
+ description: null
+ member: |
+ rtems_id runner_id
+- brief: null
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: null
+ description: null
+ member: |
+ rtems_asr_entry handler
+- brief: null
+ description: null
+ member: |
+ size_t nested
+- brief: null
+ description: null
+ member: |
+ size_t handler_calls
+- brief: null
+ description: null
+ member: |
+ size_t calls_after_send
+- brief: null
+ description: null
+ member: |
+ size_t calls_after_dispatch
+- brief: null
+ description: null
+ member: |
+ size_t calls_after_enable
+- brief: null
+ description: null
+ member: |
+ rtems_signal_set processed_signal_sets[ 2 ]
+- brief: null
+ description: null
+ member: |
+ uintptr_t stack_pointers[ 2 ];
+- brief: null
+ description: null
+ member: |
+ rtems_mode mode;
+- brief: null
+ description: null
+ member: |
+ rtems_status_code status
+- brief: null
+ description: null
+ member: |
+ rtems_id id
+- brief: null
+ description: null
+ member: |
+ rtems_signal_set signal_set
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes: []
+test-prepare: |
+ ctx->handler_calls = 0;
+ ctx->calls_after_send = 0;
+ ctx->calls_after_dispatch = 0;
+ ctx->calls_after_enable = 0;
+ memset( &ctx->processed_signal_sets, 0, sizeof( ctx->processed_signal_sets ) );
+ memset( &ctx->stack_pointers, 0, sizeof( ctx->stack_pointers ) );
+test-setup:
+ brief: null
+ code: |
+ rtems_status_code sc;
+ rtems_task_priority prio;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->runner_id = rtems_task_self();
+
+ prio = 0;
+ sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
+ T_rsc_success( sc );
+ T_eq_u32( prio, PRIO_HIGH );
+
+ 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 );
+
+ #if defined(RTEMS_SMP)
+ if ( rtems_scheduler_get_processor_maximum() > 1 ) {
+ rtems_id scheduler_id;
+
+ sc = rtems_scheduler_ident_by_processor( 1, &scheduler_id );
+ T_assert_rsc_success( sc );
+
+ sc = rtems_task_set_scheduler( ctx->worker_id, scheduler_id, PRIO_HIGH );
+ T_assert_rsc_success( sc );
+ }
+ #endif
+
+ 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 EVENT_START RTEMS_EVENT_0
+
+ #define EVENT_SEND_DONE RTEMS_EVENT_1
+
+ #define EVENT_DO_ENABLE RTEMS_EVENT_2
+
+ #define EVENT_END RTEMS_EVENT_3
+
+ #define EVENT_WORKER_DONE RTEMS_EVENT_4
+
+ typedef RtemsSignalReqSend_Context Context;
+
+ typedef enum {
+ PRIO_HIGH = 1,
+ PRIO_NORMAL
+ } Priorities;
+
+ static rtems_event_set Wait( void )
+ {
+ 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 );
+
+ return events;
+ }
+
+ static void SendEvents( rtems_id id, rtems_event_set events )
+ {
+ rtems_status_code sc;
+
+ sc = rtems_event_send( id, events );
+ T_rsc_success( sc );
+ }
+
+ static void WorkerDone( const Context *ctx )
+ {
+ #if defined(RTEMS_SMP)
+ if ( rtems_scheduler_get_processor_maximum() > 1 ) {
+ SendEvents( ctx->runner_id, EVENT_WORKER_DONE );
+ }
+ #endif
+ }
+
+ static void SendEventsToWorker( const Context *ctx, rtems_event_set events )
+ {
+ SendEvents( ctx->worker_id, events );
+
+ #if defined(RTEMS_SMP)
+ if ( rtems_scheduler_get_processor_maximum() > 1 ) {
+ events = Wait();
+ T_eq_u32( events, EVENT_WORKER_DONE );
+ }
+ #endif
+ }
+
+ static void SignalHandler( rtems_signal_set signal_set )
+ {
+ Context *ctx;
+ size_t i;
+ size_t n;
+
+ ctx = T_fixture_context();
+ i = ctx->handler_calls;
+ n = RTEMS_ARRAY_SIZE( ctx->processed_signal_sets );
+ ctx->processed_signal_sets[ i % n ] = signal_set;
+ ctx->stack_pointers[ i % n ] = (uintptr_t) __builtin_frame_address( 0 );
+ T_lt_sz( i, n );
+ ctx->handler_calls = i + 1;
+
+ if ( ctx->nested != 0 && i == 0 ) {
+ rtems_status_code sc;
+
+ if ( ctx->id == ctx->worker_id ) {
+ rtems_event_set events;
+
+ sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ WorkerDone( ctx );
+
+ events = Wait();
+ T_eq_u32( events, EVENT_SEND_DONE );
+
+ WorkerDone( ctx );
+
+ events = Wait();
+ T_eq_u32( events, EVENT_DO_ENABLE );
+ } else {
+ sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
+ ctx->calls_after_send = ctx->handler_calls;
+ ctx->calls_after_dispatch = ctx->handler_calls;
+ }
+ }
+ }
+
+ static void Worker( rtems_task_argument arg )
+ {
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_status_code sc;
+ rtems_event_set events;
+
+ events = Wait();
+ T_eq_u32( events, EVENT_START );
+
+ if ( ctx->nested != 0 ) {
+ sc = rtems_signal_catch( SignalHandler, ctx->mode );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_send( RTEMS_SELF, 0x600df00d );
+ T_rsc_success( sc );
+
+ WorkerDone( ctx );
+ } else {
+ rtems_mode mode;
+
+ sc = rtems_task_mode( ctx->mode, RTEMS_ASR_MASK, &mode );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ WorkerDone( ctx );
+
+ events = Wait();
+ T_eq_u32( events, EVENT_SEND_DONE );
+
+ WorkerDone( ctx );
+
+ events = Wait();
+ T_eq_u32( events, EVENT_DO_ENABLE );
+
+ sc = rtems_task_mode( mode, RTEMS_ASR_MASK, &mode );
+ T_rsc_success( sc );
+
+ WorkerDone( ctx );
+ }
+
+ events = Wait();
+ T_eq_u32( events, EVENT_END );
+
+ WorkerDone( ctx );
+ }
+ }
+test-target: testsuites/validation/tc-signal-send.c
+test-teardown:
+ brief: null
+ code: |
+ rtems_status_code sc;
+ rtems_task_priority prio;
+
+ prio = 0;
+ sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
+ T_rsc_success( sc );
+ T_eq_u32( prio, PRIO_NORMAL );
+
+ if ( ctx->worker_id != 0 ) {
+ sc = rtems_task_delete( ctx->worker_id );
+ T_rsc_success( sc );
+ }
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: InvNum
+ Handler: NoCall
+ Recursive: 'No'
+ pre-conditions:
+ Task: all
+ Set:
+ - Zero
+ Handler: all
+ ASR: all
+ Nested: all
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Handler: NoCall
+ Recursive: 'No'
+ pre-conditions:
+ Task:
+ - NoObj
+ Set:
+ - NonZero
+ Handler: all
+ ASR: all
+ Nested: all
+- enabled-by: true
+ post-conditions:
+ Status: NotDef
+ Handler: NoCall
+ Recursive: 'No'
+ pre-conditions:
+ Task:
+ - Self
+ - Other
+ Set:
+ - NonZero
+ Handler:
+ - Invalid
+ ASR: all
+ Nested: all
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Handler: AfterEnable
+ Recursive: 'No'
+ pre-conditions:
+ Task:
+ - Self
+ - Other
+ Set:
+ - NonZero
+ Handler:
+ - Valid
+ ASR:
+ - Disabled
+ Nested: all
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Handler: DuringSend
+ Recursive: 'No'
+ pre-conditions:
+ Task:
+ - Self
+ Set:
+ - NonZero
+ Handler:
+ - Valid
+ ASR:
+ - Enabled
+ Nested:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Handler: AfterDispatch
+ Recursive: 'No'
+ pre-conditions:
+ Task:
+ - Other
+ Set:
+ - NonZero
+ Handler:
+ - Valid
+ ASR:
+ - Enabled
+ Nested:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Handler: DuringSend
+ Recursive: 'Yes'
+ pre-conditions:
+ Task:
+ - Self
+ Set:
+ - NonZero
+ Handler:
+ - Valid
+ ASR:
+ - Enabled
+ Nested:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Handler: AfterDispatch
+ Recursive: 'Yes'
+ pre-conditions:
+ Task:
+ - Other
+ Set:
+ - NonZero
+ Handler:
+ - Valid
+ ASR:
+ - Enabled
+ Nested:
+ - 'Yes'
+type: requirement
More information about the vc
mailing list