summaryrefslogtreecommitdiffstats
path: root/spec/rtems
diff options
context:
space:
mode:
Diffstat (limited to 'spec/rtems')
-rw-r--r--spec/rtems/userext/req/thread-begin-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-begin-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-create-allocator-owner.yml17
-rw-r--r--spec/rtems/userext/req/thread-create-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-create-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-delete-allocator-owner.yml17
-rw-r--r--spec/rtems/userext/req/thread-delete-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-delete-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-exitted-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-exitted-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-restart-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-restart-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-start-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-start-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-switch-order.yml15
-rw-r--r--spec/rtems/userext/req/thread-terminate-iterate-remove.yml17
-rw-r--r--spec/rtems/userext/req/thread-terminate-order.yml15
-rw-r--r--spec/rtems/userext/val/userext.yml716
18 files changed, 989 insertions, 0 deletions
diff --git a/spec/rtems/userext/req/thread-begin-iterate-remove.yml b/spec/rtems/userext/req/thread-begin-iterate-remove.yml
new file mode 100644
index 00000000..bd96175f
--- /dev/null
+++ b/spec/rtems/userext/req/thread-begin-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ begin extensions, when an extension set is removed, the removed extension set
+ shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-begin-order.yml b/spec/rtems/userext/req/thread-begin-order.yml
new file mode 100644
index 00000000..5314defb
--- /dev/null
+++ b/spec/rtems/userext/req/thread-begin-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread begin ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-create-allocator-owner.yml b/spec/rtems/userext/req/thread-create-allocator-owner.yml
new file mode 100644
index 00000000..a8525006
--- /dev/null
+++ b/spec/rtems/userext/req/thread-create-allocator-owner.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+- role: requirement-refinement
+ uid: /score/object/req/allocator-mutex
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread invoking the thread create ${/glossary/userextensions:/term} shall
+ be the owner of the allocator mutex.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-create-iterate-remove.yml b/spec/rtems/userext/req/thread-create-iterate-remove.yml
new file mode 100644
index 00000000..4fa9e331
--- /dev/null
+++ b/spec/rtems/userext/req/thread-create-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ create extensions, when an extension set is removed, the removed extension
+ set shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-create-order.yml b/spec/rtems/userext/req/thread-create-order.yml
new file mode 100644
index 00000000..418d3c11
--- /dev/null
+++ b/spec/rtems/userext/req/thread-create-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread create ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-delete-allocator-owner.yml b/spec/rtems/userext/req/thread-delete-allocator-owner.yml
new file mode 100644
index 00000000..13216996
--- /dev/null
+++ b/spec/rtems/userext/req/thread-delete-allocator-owner.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+- role: requirement-refinement
+ uid: /score/object/req/allocator-mutex
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread invoking the thread delete ${/glossary/userextensions:/term} shall
+ be the owner of the allocator mutex.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-delete-iterate-remove.yml b/spec/rtems/userext/req/thread-delete-iterate-remove.yml
new file mode 100644
index 00000000..59a17bd3
--- /dev/null
+++ b/spec/rtems/userext/req/thread-delete-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ delete extensions, when an extension set is removed, the removed extension
+ set shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-delete-order.yml b/spec/rtems/userext/req/thread-delete-order.yml
new file mode 100644
index 00000000..d3fc1710
--- /dev/null
+++ b/spec/rtems/userext/req/thread-delete-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread delete ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-reverse-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-exitted-iterate-remove.yml b/spec/rtems/userext/req/thread-exitted-iterate-remove.yml
new file mode 100644
index 00000000..aa53e3b2
--- /dev/null
+++ b/spec/rtems/userext/req/thread-exitted-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ exitted extensions, when an extension set is removed, the removed extension
+ set shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-exitted-order.yml b/spec/rtems/userext/req/thread-exitted-order.yml
new file mode 100644
index 00000000..64c3f3ff
--- /dev/null
+++ b/spec/rtems/userext/req/thread-exitted-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread exitted ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-restart-iterate-remove.yml b/spec/rtems/userext/req/thread-restart-iterate-remove.yml
new file mode 100644
index 00000000..7b75e5d5
--- /dev/null
+++ b/spec/rtems/userext/req/thread-restart-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ restart extensions, when an extension set is removed, the removed extension
+ set shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-restart-order.yml b/spec/rtems/userext/req/thread-restart-order.yml
new file mode 100644
index 00000000..6d1546a5
--- /dev/null
+++ b/spec/rtems/userext/req/thread-restart-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread restart ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-start-iterate-remove.yml b/spec/rtems/userext/req/thread-start-iterate-remove.yml
new file mode 100644
index 00000000..6059efea
--- /dev/null
+++ b/spec/rtems/userext/req/thread-start-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ start extensions, when an extension set is removed, the removed extension set
+ shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-start-order.yml b/spec/rtems/userext/req/thread-start-order.yml
new file mode 100644
index 00000000..98ff2bd4
--- /dev/null
+++ b/spec/rtems/userext/req/thread-start-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread start ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-switch-order.yml b/spec/rtems/userext/req/thread-switch-order.yml
new file mode 100644
index 00000000..754633f9
--- /dev/null
+++ b/spec/rtems/userext/req/thread-switch-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread switch ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-forward-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-terminate-iterate-remove.yml b/spec/rtems/userext/req/thread-terminate-iterate-remove.yml
new file mode 100644
index 00000000..f5522854
--- /dev/null
+++ b/spec/rtems/userext/req/thread-terminate-iterate-remove.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While the ${/glossary/userextensions:/term} are iterated to invoke the thread
+ terminate extensions, when an extension set is removed, the removed extension
+ set shall not be a next extension set for any iteration in progress after the
+ removal.
+type: requirement
diff --git a/spec/rtems/userext/req/thread-terminate-order.yml b/spec/rtems/userext/req/thread-terminate-order.yml
new file mode 100644
index 00000000..6ceb4ad7
--- /dev/null
+++ b/spec/rtems/userext/req/thread-terminate-order.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The thread terminate ${/glossary/userextensions:/term} shall be invoked in
+ ${/glossary/extension-reverse-order:/term}.
+type: requirement
diff --git a/spec/rtems/userext/val/userext.yml b/spec/rtems/userext/val/userext.yml
new file mode 100644
index 00000000..e85f6197
--- /dev/null
+++ b/spec/rtems/userext/val/userext.yml
@@ -0,0 +1,716 @@
+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
+links: []
+test-actions:
+- action-brief: |
+ Create five dynamic extensions. Switch to a started thread. Delete three
+ dynamic extension during the thread begin invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_LOW );
+ thread = GetThread( id );
+ StartTask( id, BeginWorker, NULL );
+ executing = StartTestCase( THREAD_BEGIN );
+ SetPriority( id, PRIO_HIGH );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread switch extensions were invoked in the right order
+ before the thread begin extensions.
+ code: |
+ CheckForward( THREAD_SWITCH, 1, 1, executing, thread );
+ links:
+ - role: validation
+ uid: ../req/thread-switch-order
+ - brief: |
+ Check that the thread begin extensions were invoked in the right order.
+ code: |
+ CheckForward( THREAD_BEGIN, 8, 1, thread, NULL );
+ links:
+ - role: validation
+ uid: ../req/thread-begin-iterate-remove
+ - role: validation
+ uid: ../req/thread-begin-order
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread begin extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_BEGIN );
+ links:
+ - role: validation
+ uid: ../req/thread-begin-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Create a thread. Delete three dynamic
+ extension during the thread create invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ executing = StartTestCase( THREAD_CREATE );
+ id = CreateTask( "WORK", PRIO_NORMAL );
+ thread = GetThread( id );
+ StopTestCase();
+ DeleteTask( id );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread create extensions were invoked in the right order.
+ code: |
+ CheckForward( THREAD_CREATE, 1, 1, executing, thread );
+ links:
+ - role: validation
+ uid: ../req/thread-create-iterate-remove
+ - role: validation
+ uid: ../req/thread-create-order
+ - brief: |
+ Check that the thread create extensions were invoked under protection of
+ the allocator mutex.
+ code: |
+ T_eq_u32( thread_create_allocator_owner_count, 6 );
+ links:
+ - role: validation
+ uid: ../req/thread-create-allocator-owner
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread create extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_CREATE );
+ links:
+ - role: validation
+ uid: ../req/thread-create-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Delete a thread. Delete three dynamic
+ extension during the thread delete invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_NORMAL );
+ thread = GetThread( id );
+ DeleteTask( id );
+ executing = StartTestCase( THREAD_DELETE );
+ KillZombies();
+ StopTestCase();
+ checks:
+ - brief: |
+ Check that the thread delete extensions were invoked in the right order.
+ code: |
+ CheckReverse( THREAD_DELETE, 1, 1, executing, thread );
+ links:
+ - role: validation
+ uid: ../req/thread-delete-iterate-remove
+ - role: validation
+ uid: ../req/thread-delete-order
+ - brief: |
+ Check that the thread delete extensions were invoked under protection of
+ the allocator mutex.
+ code: |
+ T_eq_u32( thread_delete_allocator_owner_count, 6 );
+ links:
+ - role: validation
+ uid: ../req/thread-delete-allocator-owner
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread delete extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_DELETE );
+ links:
+ - role: validation
+ uid: ../req/thread-delete-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Return from a thread entry. Delete three
+ dynamic extension during the thread exitted invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, ExittedWorker, NULL );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread exitted extensions were invoked in the right order.
+ code: |
+ CheckForward( THREAD_EXITTED, 1, 1, thread, NULL );
+ links:
+ - role: validation
+ uid: ../req/thread-exitted-iterate-remove
+ - role: validation
+ uid: ../req/thread-exitted-order
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread exitted extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_EXITTED );
+ links:
+ - role: validation
+ uid: ../req/thread-exitted-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Restart a thread. Delete three
+ dynamic extension during the thread restart invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, RestartWorker, NULL );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread restart extensions were invoked in the right order.
+ code: |
+ CheckForward( THREAD_RESTART, 1, 1, thread, thread );
+ links:
+ - role: validation
+ uid: ../req/thread-restart-iterate-remove
+ - role: validation
+ uid: ../req/thread-restart-order
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckForward( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread restart extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_RESTART );
+ links:
+ - role: validation
+ uid: ../req/thread-restart-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Start a thread. Delete three dynamic
+ extension during the thread start invocation. Clean up the used resources.
+ action-code: |
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_LOW );
+ thread = GetThread( id );
+ executing = StartTestCase( THREAD_START );
+ StartTask( id, StartWorker, NULL );
+ StopTestCase();
+ DeleteTask( id );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread start extensions were invoked in the right order.
+ code: |
+ CheckForward( THREAD_START, 1, 1, executing, thread );
+ links:
+ - role: validation
+ uid: ../req/thread-start-iterate-remove
+ - role: validation
+ uid: ../req/thread-start-order
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckForward( THREAD_TERMINATE, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread start extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_START );
+ links:
+ - role: validation
+ uid: ../req/thread-start-iterate-remove
+ links: []
+- action-brief: |
+ Create five dynamic extensions. Terminate a thread. Delete three dynamic
+ extension during the thread terminate invocation. Clean up the used
+ resources.
+ action-code: |
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, TerminateWorker, NULL );
+ KillZombies();
+ checks:
+ - brief: |
+ Check that the thread terminate extensions were invoked in the right
+ order.
+ code: |
+ CheckReverse( THREAD_TERMINATE, 1, 1, thread, NULL );
+ links:
+ - role: validation
+ uid: ../req/thread-terminate-iterate-remove
+ - role: validation
+ uid: ../req/thread-terminate-order
+ - brief: |
+ Check that the other extensions were not invoked.
+ code: |
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ links: []
+ - brief: |
+ Check that the thread terminate extension of the extension set deleted
+ before its turn in the invocation was not invoked.
+ code: |
+ CheckDeletedNotInvoked( THREAD_TERMINATE );
+ links:
+ - role: validation
+ uid: ../req/thread-terminate-iterate-remove
+ links: []
+test-brief: |
+ Tests the thread user extensions.
+test-context: []
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems/score/atomic.h
+- rtems/score/apimutex.h
+- string.h
+test-local-includes:
+- tc-userext.h
+- tx-support.h
+test-setup:
+ brief: null
+ code: |
+ SetSelfPriority( PRIO_NORMAL );
+ description: null
+test-stop: null
+test-support: |
+ typedef struct {
+ unsigned int counter;
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ } ExtensionEvent;
+
+ typedef enum {
+ THREAD_BEGIN,
+ THREAD_CREATE,
+ THREAD_DELETE,
+ THREAD_EXITTED,
+ THREAD_RESTART,
+ THREAD_START,
+ THREAD_SWITCH,
+ THREAD_TERMINATE,
+ EXTENSION_KIND_COUNT
+ } ExtensionKind;
+
+ static rtems_id extension_ids[ 7 ];
+
+ static Atomic_Uint extension_counter[ RTEMS_ARRAY_SIZE( extension_ids ) ]
+ [ EXTENSION_KIND_COUNT ];
+
+ static ExtensionEvent extension_events[ RTEMS_ARRAY_SIZE( extension_ids ) ]
+ [ EXTENSION_KIND_COUNT ][ 3 ];
+
+ static Atomic_Uint global_counter;
+
+ static ExtensionKind extension_under_test = EXTENSION_KIND_COUNT;
+
+ static uint32_t thread_create_allocator_owner_count;
+
+ static uint32_t thread_delete_allocator_owner_count;
+
+ static void StopTestCase( void )
+ {
+ ExtensionKind kind;
+ rtems_status_code sc;
+
+ kind = extension_under_test;
+ extension_under_test = EXTENSION_KIND_COUNT;
+
+ sc = rtems_extension_delete( extension_ids[ 2 ] );
+ T_rsc_success( sc );
+
+ if ( kind == THREAD_SWITCH ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ }
+
+ sc = rtems_extension_delete( extension_ids[ 6 ] );
+ T_rsc_success( sc );
+ }
+
+ static void Extension(
+ size_t index,
+ ExtensionKind kind,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+ )
+ {
+ unsigned int gc;
+ unsigned int c;
+ rtems_status_code sc;
+
+ if ( extension_under_test == EXTENSION_KIND_COUNT ) {
+ return;
+ }
+
+ if ( kind == THREAD_CREATE && _RTEMS_Allocator_is_owner() ) {
+ ++thread_create_allocator_owner_count;
+ }
+
+ if ( kind == THREAD_DELETE && _RTEMS_Allocator_is_owner() ) {
+ ++thread_delete_allocator_owner_count;
+ }
+
+ gc = _Atomic_Fetch_add_uint( &global_counter, 1, ATOMIC_ORDER_RELAXED ) + 1;
+ c = _Atomic_Fetch_add_uint(
+ &extension_counter[ index ][ kind ],
+ 1,
+ ATOMIC_ORDER_RELAXED
+ );
+
+ if ( c < RTEMS_ARRAY_SIZE( extension_events[ index ][ kind ] ) ) {
+ extension_events[ index ][ kind ][ c ].counter = gc;
+ extension_events[ index ][ kind ][ c ].executing = executing;
+ extension_events[ index ][ kind ][ c ].thread = thread;
+ }
+
+ if ( kind == THREAD_SWITCH ) {
+ /* Extension set deletion is not allowed in thread switch extensions */
+ return;
+ }
+
+ if ( kind != extension_under_test ) {
+ return;
+ }
+
+ if ( kind == THREAD_DELETE || kind == THREAD_TERMINATE ) {
+ if ( index == 6 ) {
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ } else if ( index == 3 ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+ } else if ( index == 2 ) {
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+ }
+ } else {
+ if ( index == 2 ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+ } else if ( index == 5 ) {
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ } else if ( index == 6 ) {
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+ }
+ }
+
+ if ( index == 6 && ( kind == THREAD_EXITTED || kind == THREAD_RESTART ) ) {
+ StopTestCase();
+ rtems_task_exit();
+ }
+
+ if ( index == 0 && kind == THREAD_TERMINATE ) {
+ StopTestCase();
+ }
+ }
+
+ #define DEFINE_EXTENSIONS( index, linkage ) \
+ linkage void ThreadBeginExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_BEGIN, executing, NULL ); \
+ } \
+ linkage bool ThreadCreateExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *created \
+ ) \
+ { \
+ Extension( index, THREAD_CREATE, executing, created ); \
+ return true; \
+ } \
+ linkage void ThreadDeleteExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *deleted \
+ ) \
+ { \
+ Extension( index, THREAD_DELETE, executing, deleted ); \
+ } \
+ linkage void ThreadExittedExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_EXITTED, executing, NULL ); \
+ } \
+ linkage void ThreadRestartExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *restarted \
+ ) \
+ { \
+ Extension( index, THREAD_RESTART, executing, restarted ); \
+ } \
+ linkage void ThreadStartExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *started \
+ ) \
+ { \
+ Extension( index, THREAD_START, executing, started ); \
+ } \
+ linkage void ThreadSwitchExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *heir \
+ ) \
+ { \
+ Extension( index, THREAD_SWITCH, executing, heir ); \
+ } \
+ linkage void ThreadTerminateExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_TERMINATE, executing, NULL ); \
+ }
+
+ DEFINE_EXTENSIONS( 0, )
+ DEFINE_EXTENSIONS( 1, )
+
+ #define DEFINE_EXTENSIONS_AND_TABLE( index ) \
+ DEFINE_EXTENSIONS( index, static ) \
+ static const rtems_extensions_table table_##index = { \
+ .thread_begin = ThreadBeginExtension##index, \
+ .thread_create = ThreadCreateExtension##index, \
+ .thread_delete = ThreadDeleteExtension##index, \
+ .thread_exitted = ThreadExittedExtension##index, \
+ .thread_restart = ThreadRestartExtension##index, \
+ .thread_start = ThreadStartExtension##index, \
+ .thread_switch = ThreadSwitchExtension##index, \
+ .thread_terminate = ThreadTerminateExtension##index \
+ }
+
+ DEFINE_EXTENSIONS_AND_TABLE( 2 );
+ DEFINE_EXTENSIONS_AND_TABLE( 3 );
+ DEFINE_EXTENSIONS_AND_TABLE( 4 );
+ DEFINE_EXTENSIONS_AND_TABLE( 5 );
+ DEFINE_EXTENSIONS_AND_TABLE( 6 );
+
+ static const rtems_extensions_table * const tables[] = {
+ NULL,
+ NULL,
+ &table_2,
+ &table_3,
+ &table_4,
+ &table_5,
+ &table_6
+ };
+
+ static rtems_tcb *StartTestCase( ExtensionKind kind )
+ {
+ size_t i;
+
+ thread_create_allocator_owner_count = 0;
+ thread_delete_allocator_owner_count = 0;
+ _Atomic_Store_uint( &global_counter, 0, ATOMIC_ORDER_RELAXED );
+ memset( extension_counter, 0, sizeof( extension_counter ) );
+ memset( extension_events, 0, sizeof( extension_events ) );
+
+ extension_under_test = kind;
+
+ for ( i = 2; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '2' + i ),
+ tables[ i ],
+ &extension_ids[ i ]
+ );
+ T_rsc_success( sc );
+ }
+
+ return GetExecuting();
+ }
+
+ static void CheckForward(
+ ExtensionKind kind,
+ unsigned int counter,
+ unsigned int increment,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+ )
+ {
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ if ( i == 3 && kind != THREAD_SWITCH ) {
+ continue;
+ }
+
+ if ( counter == 0 ) {
+ T_eq_uint( extension_counter[ i ][ kind ], 0 );
+ } else {
+ T_eq_uint( extension_counter[ i ][ kind ], 1 );
+ T_eq_uint( extension_events[ i ][ kind ][ 0 ].counter, counter );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].executing, executing );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].thread, thread );
+
+ counter += increment;
+ }
+ }
+ }
+
+ static void CheckReverse(
+ ExtensionKind kind,
+ unsigned int counter,
+ unsigned int increment,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+ )
+ {
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ if ( i == 5 && kind != THREAD_SWITCH ) {
+ continue;
+ }
+
+ if ( counter == 0 ) {
+ T_eq_uint( extension_counter[ i ][ kind ], 0 );
+ } else {
+ T_eq_uint( extension_counter[ i ][ kind ], 1 );
+ T_eq_uint(
+ extension_events[ i ][ kind ][ 0 ].counter,
+ 7 - counter
+ );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].executing, executing );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].thread, thread );
+
+ counter += increment;
+ }
+ }
+ }
+
+ static void CheckDeletedNotInvoked( ExtensionKind kind )
+ {
+ size_t index;
+
+ if ( kind == THREAD_DELETE || kind == THREAD_TERMINATE ) {
+ index = 5;
+ } else {
+ index = 3;
+ }
+
+ T_eq_uint( extension_events[ index ][ kind ][ 0 ].counter, 0 );
+ T_null( extension_events[ index ][ kind ][ 0 ].executing );
+ T_null( extension_events[ index ][ kind ][ 0 ].thread );
+ }
+
+ static void BeginWorker( rtems_task_argument arg )
+ {
+ T_eq_u32( arg, 0 );
+ StopTestCase();
+ rtems_task_exit();
+ }
+
+ static void ExittedWorker( rtems_task_argument arg )
+ {
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_EXITTED );
+ }
+
+ static void RestartWorker( rtems_task_argument arg )
+ {
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_RESTART );
+ (void) rtems_task_restart( RTEMS_SELF, 1 );
+ }
+
+ static void StartWorker( rtems_task_argument arg )
+ {
+ (void) arg;
+ T_unreachable();
+ }
+
+ static void TerminateWorker( rtems_task_argument arg )
+ {
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_TERMINATE );
+ rtems_task_exit();
+ }
+test-target: testsuites/validation/tc-userext.c
+test-teardown:
+ brief: null
+ code: |
+ RestoreRunnerPriority();
+ description: null
+type: test-case