summaryrefslogtreecommitdiffstats
path: root/spec/c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-05-18 09:31:59 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-05-18 17:57:25 +0200
commite1c9210d2aad786de70da814d9e92498b6d20ed6 (patch)
treea43edaef6f022b69d425f672ba517df84be5616f /spec/c
parentspec: Fix attribute reference (diff)
downloadrtems-central-e1c9210d2aad786de70da814d9e92498b6d20ed6.tar.bz2
spec: Specify clock_nanosleep()
Diffstat (limited to 'spec/c')
-rw-r--r--spec/c/if/clock-monotonic.yml13
-rw-r--r--spec/c/if/clock-nanosleep.yml13
-rw-r--r--spec/c/if/clock-realtime.yml13
-rw-r--r--spec/c/if/enotsup.yml12
-rw-r--r--spec/c/if/posix-memalign.yml3
-rw-r--r--spec/c/if/timer-abstime.yml13
-rw-r--r--spec/c/req/clock-nanosleep.yml613
7 files changed, 679 insertions, 1 deletions
diff --git a/spec/c/if/clock-monotonic.yml b/spec/c/if/clock-monotonic.yml
new file mode 100644
index 00000000..bc702af5
--- /dev/null
+++ b/spec/c/if/clock-monotonic.yml
@@ -0,0 +1,13 @@
+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
+index-entries: []
+interface-type: unspecified-define
+links:
+- role: interface-placement
+ uid: time
+name: CLOCK_MONOTONIC
+references:
+ url: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
+type: interface
diff --git a/spec/c/if/clock-nanosleep.yml b/spec/c/if/clock-nanosleep.yml
new file mode 100644
index 00000000..1cf2e374
--- /dev/null
+++ b/spec/c/if/clock-nanosleep.yml
@@ -0,0 +1,13 @@
+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
+index-entries: []
+interface-type: unspecified-function
+links:
+- role: interface-placement
+ uid: time
+name: clock_nanosleep
+references:
+ url: https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html
+type: interface
diff --git a/spec/c/if/clock-realtime.yml b/spec/c/if/clock-realtime.yml
new file mode 100644
index 00000000..042ec386
--- /dev/null
+++ b/spec/c/if/clock-realtime.yml
@@ -0,0 +1,13 @@
+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
+index-entries: []
+interface-type: unspecified-define
+links:
+- role: interface-placement
+ uid: time
+name: CLOCK_REALTIME
+references:
+ url: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
+type: interface
diff --git a/spec/c/if/enotsup.yml b/spec/c/if/enotsup.yml
new file mode 100644
index 00000000..cf3f790c
--- /dev/null
+++ b/spec/c/if/enotsup.yml
@@ -0,0 +1,12 @@
+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
+index-entries: []
+interface-type: unspecified-define
+links:
+- role: interface-placement
+ uid: errno-header
+name: ENOTSUP
+references: {}
+type: interface
diff --git a/spec/c/if/posix-memalign.yml b/spec/c/if/posix-memalign.yml
index 6a45994d..e9de1ab0 100644
--- a/spec/c/if/posix-memalign.yml
+++ b/spec/c/if/posix-memalign.yml
@@ -8,5 +8,6 @@ links:
- role: interface-placement
uid: stdlib
name: posix_memalign
-references: {}
+references:
+ url: https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
type: interface
diff --git a/spec/c/if/timer-abstime.yml b/spec/c/if/timer-abstime.yml
new file mode 100644
index 00000000..91b63f6a
--- /dev/null
+++ b/spec/c/if/timer-abstime.yml
@@ -0,0 +1,13 @@
+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
+index-entries: []
+interface-type: unspecified-define
+links:
+- role: interface-placement
+ uid: time
+name: TIMER_ABSTIME
+references:
+ url: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
+type: interface
diff --git a/spec/c/req/clock-nanosleep.yml b/spec/c/req/clock-nanosleep.yml
new file mode 100644
index 00000000..9da4f21e
--- /dev/null
+++ b/spec/c/req/clock-nanosleep.yml
@@ -0,0 +1,613 @@
+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/clock-nanosleep
+post-conditions:
+- name: Status
+ states:
+ - name: Zero
+ test-code: |
+ T_eq_int( ctx->status, 0 );
+ text: |
+ The return value of ${../if/clock-nanosleep:/name} shall be equal to zero.
+ - name: ENOTSUP
+ test-code: |
+ T_eq_int( ctx->status, ENOTSUP );
+ text: |
+ The return value of ${../if/clock-nanosleep:/name} shall be equal to
+ ${../if/enotsup:/name}.
+ - name: EINVAL
+ test-code: |
+ T_eq_int( ctx->status, EINVAL );
+ text: |
+ The return value of ${../if/clock-nanosleep:/name} shall be equal to
+ ${../if/einval:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Timer
+ states:
+ - name: Inactive
+ test-code: |
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
+ text: |
+ The timer of the calling task shall be inactive.
+ - name: Monotonic
+ test-code: |
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_MONOTONIC );
+ text: |
+ The timer of the calling task shall be active using the
+ ${/glossary/clock-monotonic:/term}.
+ - name: Realtime
+ test-code: |
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
+ text: |
+ The timer of the calling task shall be active using the
+ ${/glossary/clock-realtime:/term}.
+ test-epilogue: null
+ test-prologue: null
+- name: Expire
+ states:
+ - name: Last
+ test-code: |
+ T_eq_u64( ctx->timer_info.expire_ticks, 0xffffffffffffffff );
+ text: |
+ The timer of the calling task shall expire at the last valid time point
+ of the clock specified by the ``clock_id`` parameter.
+ - name: Absolute
+ test-code: |
+ T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, ctx->rqtp_obj.tv_sec );
+ T_eq_long(
+ ctx->timer_info.expire_timespec.tv_nsec,
+ ctx->rqtp_obj.tv_nsec
+ );
+ text: |
+ The timer of the calling task shall expire at the time point specified by
+ the ``rqtp`` parameter.
+ - name: Relative
+ test-code: |
+ if ( ctx->clock_id == CLOCK_REALTIME ) {
+ expire = ctx->now_realtime;
+ } else {
+ expire = ctx->now_monotonic;
+ }
+
+ expire.tv_sec += ctx->rqtp_obj.tv_sec;
+ expire.tv_nsec += ctx->rqtp_obj.tv_nsec;
+
+ if ( expire.tv_nsec >= 1000000000 ) {
+ ++expire.tv_sec;
+ expire.tv_nsec -= 1000000000;
+ }
+
+ T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, expire.tv_sec );
+ T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, expire.tv_nsec );
+ text: |
+ The timer of the calling task shall expire at the time point specified by
+ the sum of the current time of the clock specified by the ``clock_id``
+ parameter and the interval specified by the ``rqtp`` parameter.
+ test-epilogue: null
+ test-prologue: |
+ struct timespec expire;
+- name: Scheduler
+ states:
+ - name: Block
+ test-code: |
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ text: |
+ The calling task shall be blocked by the scheduler exactly once by the
+ ${../if/clock-nanosleep:/name} call.
+ - name: BlockUnblock
+ test-code: |
+ 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
+ );
+ text: |
+ The calling task shall be blocked exactly once by the scheduler and then
+ unblocked in the same thread dispatch critical section by the
+ ${../if/clock-nanosleep:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ text: |
+ The calling task shall not be altered by the scheduler by the
+ ${../if/clock-nanosleep:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: RMTp
+ states:
+ - name: Zero
+ test-code: |
+ T_eq_i64( ctx->rmtp_obj.tv_sec, 0 );
+ T_eq_long( ctx->rmtp_obj.tv_nsec, 0 );
+ text: |
+ The object referenced by the ``rmtp`` parameter shall be cleared to zero
+ after the return of the ${../if/clock-nanosleep:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_i64( ctx->rmtp_obj.tv_sec, -1 );
+ T_eq_long( ctx->rmtp_obj.tv_nsec, -1 );
+ text: |
+ Objects referenced by the ``rmtp`` parameter in past calls to
+ ${../if/clock-nanosleep:/name} shall not be accessed by the
+ ${../if/clock-nanosleep:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: ClockId
+ states:
+ - name: Monotonic
+ test-code: |
+ ctx->clock_id = CLOCK_MONOTONIC;
+ text: |
+ While the ``clock_id`` parameter is equal to ${../if/clock-monotonic:/name}.
+ - name: Realtime
+ test-code: |
+ ctx->clock_id = CLOCK_REALTIME;
+ text: |
+ While the ``clock_id`` parameter is equal to ${../if/clock-realtime:/name}.
+ - name: Invalid
+ test-code: |
+ ctx->clock_id = INT_MAX;
+ text: |
+ While the ``clock_id`` parameter is an invalid clock identifier.
+ test-epilogue: null
+ test-prologue: null
+- name: Abstime
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->flags |= TIMER_ABSTIME;
+ text: |
+ While the ``flags`` parameter indicates an absolute time.
+ - name: 'No'
+ test-code: |
+ /* This is the default */
+ text: |
+ While the ``flags`` parameter does not indicate an absolute time.
+ test-epilogue: null
+ test-prologue: null
+- name: RQTp
+ states:
+ - name: Valid
+ test-code: |
+ ctx->rqtp = &ctx->rqtp_obj;
+ text: |
+ While the ``rqtp`` parameter references an object of type
+ ${../if/timespec:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->rqtp = NULL;
+ text: |
+ While the ``rqtp parameter is equal to ${../if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: RQTpNSec
+ states:
+ - name: Valid
+ test-code: |
+ ctx->rqtp_obj.tv_nsec = 999999999;
+ text: |
+ While the ``tv_nsec`` member of the object referenced by the ``rqtp``
+ parameter is a valid nanoseconds value.
+ - name: Invalid
+ test-code: |
+ ctx->rqtp_obj.tv_nsec = -1;
+ text: |
+ While the ``tv_nsec`` member of the object referenced by the ``rqtp``
+ parameter is an invalid nanoseconds value.
+ test-epilogue: null
+ test-prologue: null
+- name: RQTpSec
+ states:
+ - name: Negative
+ test-code: |
+ ctx->rqtp_obj.tv_sec = -238479;
+ text: |
+ While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ parameter is negative.
+ - name: FarFuture
+ test-code: |
+ ctx->rqtp_obj.tv_sec = INT64_MAX;
+ text: |
+ While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ parameter specifies a time point which is past the implementation limit.
+ - name: Future
+ test-code: |
+ ctx->rqtp_obj.tv_sec = 1621322302;
+ text: |
+ While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ parameter specifies a time point which is after the current time of the
+ clock specified by the ``clock_id`` parameter and is within the
+ implementation limits.
+ - name: PastOrNow
+ test-code: |
+ ctx->rqtp_obj.tv_sec = 0;
+
+ if ( ctx->rqtp_obj.tv_nsec == 999999999 ) {
+ ctx->rqtp_obj.tv_nsec = 0;
+ }
+ text: |
+ While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ parameter is non-negative and specifies a time point which is before or
+ at the current time of the clock specified by the ``clock_id`` parameter.
+ test-epilogue: null
+ test-prologue: null
+- name: RMTp
+ states:
+ - name: Valid
+ test-code: |
+ ctx->rmtp = &ctx->rmtp_obj;
+ text: |
+ While the ``rmtp`` parameter references an object of type
+ ${../if/timespec:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->rmtp = NULL;
+ text: |
+ While the ``rmtp parameter is equal to ${../if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+ NeedClock: |
+ The terms past and future need a clock for reference.
+test-action: |
+ ResumeTask( ctx->worker_id );
+ (void) T_scheduler_record( NULL );
+ GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
+ ClockTick();
+ FinalClockTick();
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member provides the scheduler operation records.
+ description: null
+ member: |
+ T_scheduler_log_4 scheduler_log;
+- brief: |
+ This member contains the CLOCK_REALTIME value before the
+ ${../if/clock-nanosleep:/name} call.
+ description: null
+ member: |
+ struct timespec now_realtime;
+- brief: |
+ This member contains the CLOCK_MONOTONIC value before the
+ ${../if/clock-nanosleep:/name} call.
+ description: null
+ member: |
+ struct timespec now_monotonic;
+- brief: |
+ This member contains the worker task identifier.
+ description: null
+ member: |
+ rtems_id worker_id;
+- brief: |
+ This member contains the timer information of the worker task.
+ description: null
+ member: |
+ TaskTimerInfo timer_info;
+- brief: |
+ This member provides the object referenced by the ``rqtp`` parameter.
+ description: null
+ member: |
+ struct timespec rqtp_obj
+- brief: |
+ This member provides the object referenced by the ``rmtp`` parameter.
+ description: null
+ member: |
+ struct timespec rmtp_obj
+- brief: |
+ This member contains the return value of the ${../if/clock-nanosleep:/name}
+ call.
+ description: null
+ member: |
+ int status
+- brief: |
+ This member specifies the ``clock_id`` parameter value.
+ description: null
+ member: |
+ clockid_t clock_id
+- brief: |
+ This member specifies the ``flags`` parameter value.
+ description: null
+ member: |
+ int flags
+- brief: |
+ This member specifies the ``rqtp`` parameter value.
+ description: null
+ member: |
+ const struct timespec *rqtp
+- brief: |
+ This member specifies the ``rmtp`` parameter value.
+ description: null
+ member: |
+ struct timespec *rmtp
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- errno.h
+- limits.h
+- rtems.h
+- time.h
+- rtems/test-scheduler.h
+- rtems/score/timecounter.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ ctx->status = -1;
+ ctx->flags = 0;
+ ctx->rmtp_obj.tv_sec = -1;
+ ctx->rmtp_obj.tv_nsec = -1;
+test-setup:
+ brief: null
+ code: |
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-stop: null
+test-support:
+ typedef CReqClockNanosleep_Context Context;
+
+ static void Worker( rtems_task_argument arg )
+ {
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ T_scheduler_log *log;
+
+ SuspendSelf();
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ _Timecounter_Getnanotime( &ctx->now_realtime );
+ _Timecounter_Getnanouptime( &ctx->now_monotonic );
+
+ ctx->status = clock_nanosleep(
+ ctx->clock_id,
+ ctx->flags,
+ ctx->rqtp,
+ ctx->rmtp
+ );
+
+ (void) T_scheduler_record( NULL );
+ }
+ }
+test-target: testsuites/validation/tc-clock-nanosleep.c
+test-teardown:
+ brief: null
+ code: |
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Zero
+ Timer:
+ - if:
+ pre-conditions:
+ RQTpSec:
+ - Negative
+ - PastOrNow
+ then: Inactive
+ - specified-by: ClockId
+ Expire:
+ - if:
+ pre-conditions:
+ RQTpSec:
+ - Negative
+ - PastOrNow
+ then: N/A
+ - if:
+ pre-conditions:
+ RQTpSec: FarFuture
+ then: Last
+ - else: Absolute
+ Scheduler:
+ - if:
+ pre-conditions:
+ RQTpSec:
+ - Negative
+ - PastOrNow
+ then: BlockUnblock
+ - else: Block
+ RMTp: Nop
+ pre-conditions:
+ ClockId:
+ - Monotonic
+ - Realtime
+ Abstime:
+ - 'Yes'
+ RQTp:
+ - Valid
+ RQTpSec: all
+ RQTpNSec:
+ - Valid
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: Zero
+ Timer:
+ - if:
+ pre-conditions:
+ RQTpSec: PastOrNow
+ then: Inactive
+ - specified-by: ClockId
+ Expire:
+ - if:
+ pre-conditions:
+ RQTpSec: PastOrNow
+ then: N/A
+ - if:
+ pre-conditions:
+ RQTpSec: FarFuture
+ then: Last
+ - else: Relative
+ Scheduler:
+ - if:
+ pre-conditions:
+ RQTpSec: PastOrNow
+ then: BlockUnblock
+ - else: Block
+ RMTp:
+ - if:
+ pre-conditions:
+ RMTp: Valid
+ then: Zero
+ - else: Nop
+ pre-conditions:
+ ClockId:
+ - Monotonic
+ - Realtime
+ Abstime:
+ - 'No'
+ RQTp:
+ - Valid
+ RQTpSec:
+ - FarFuture
+ - Future
+ - PastOrNow
+ RQTpNSec:
+ - Valid
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: ENOTSUP
+ Timer: Inactive
+ Expire: N/A
+ Scheduler: Nop
+ RMTp: Nop
+ pre-conditions:
+ ClockId:
+ - Invalid
+ Abstime: all
+ RQTp:
+ - Valid
+ RQTpSec: all
+ RQTpNSec: all
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: ENOTSUP
+ Timer: Inactive
+ Expire: N/A
+ Scheduler: Nop
+ RMTp: Nop
+ pre-conditions:
+ ClockId:
+ - Invalid
+ Abstime: all
+ RQTp:
+ - 'Null'
+ RQTpSec: N/A
+ RQTpNSec: N/A
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: EINVAL
+ Timer: Inactive
+ Expire: N/A
+ Scheduler: BlockUnblock
+ RMTp:
+ - if:
+ pre-conditions:
+ Abstime: 'No'
+ RMTp: Valid
+ then: Zero
+ - else: Nop
+ pre-conditions:
+ ClockId:
+ - Monotonic
+ - Realtime
+ Abstime: all
+ RQTp:
+ - 'Null'
+ RQTpSec: N/A
+ RQTpNSec: N/A
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: EINVAL
+ Timer: Inactive
+ Expire: N/A
+ Scheduler: BlockUnblock
+ RMTp:
+ - if:
+ pre-conditions:
+ Abstime: 'No'
+ RMTp: Valid
+ then: Zero
+ - else: Nop
+ pre-conditions:
+ ClockId:
+ - Monotonic
+ - Realtime
+ Abstime: all
+ RQTp:
+ - Valid
+ RQTpSec: all
+ RQTpNSec:
+ - Invalid
+ RMTp: all
+- enabled-by: true
+ post-conditions:
+ Status: EINVAL
+ Timer: Inactive
+ Expire: N/A
+ Scheduler: BlockUnblock
+ RMTp:
+ - if:
+ pre-conditions:
+ RMTp: Valid
+ then: Zero
+ - else: Nop
+ pre-conditions:
+ ClockId:
+ - Monotonic
+ - Realtime
+ Abstime:
+ - 'No'
+ RQTp:
+ - Valid
+ RQTpSec:
+ - Negative
+ RQTpNSec:
+ - Valid
+ RMTp: all
+- enabled-by: true
+ post-conditions: NeedClock
+ pre-conditions:
+ ClockId:
+ - Invalid
+ Abstime: all
+ RQTp:
+ - Valid
+ RQTpSec:
+ - Future
+ - PastOrNow
+ RQTpNSec: all
+ RMTp: all
+type: requirement