[rtems-central commit] validation: Move map index/entry to context

Sebastian Huber sebh at rtems.org
Tue Aug 17 07:36:33 UTC 2021


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Aug 13 22:26:16 2021 +0200

validation: Move map index/entry to context

---

 rtemsspec/tests/test_validation.py | 204 ++++++++++++++++++++-----------------
 rtemsspec/transitionmap.py         |  25 +++--
 rtemsspec/validation.py            |  67 +++++++-----
 3 files changed, 166 insertions(+), 130 deletions(-)

diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index 1fef4bf..287ee3a 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -258,6 +258,15 @@ typedef enum {
   Directive_Post_Id_NA
 } Directive_Post_Id;
 
+typedef struct {
+  uint16_t Skip : 1;
+  uint16_t Pre_Name_NA : 1;
+  uint16_t Pre_Node_NA : 1;
+  uint16_t Pre_Id_NA : 1;
+  uint16_t Post_Status : 3;
+  uint16_t Post_Id : 3;
+} Directive_Entry;
+
 /**
  * @brief Test context for spec:/directive test case.
  */
@@ -281,16 +290,27 @@ typedef struct {
 
   rtems_id id_remote_task;
 
-  /**
-   * @brief This member defines the pre-condition states for the next action.
-   */
-  size_t pcs[ 3 ];
-
-  /**
-   * @brief This member indicates if the test action loop is currently
-   *   executed.
-   */
-  bool in_action_loop;
+  struct {
+    /**
+     * @brief This member defines the pre-condition states for the next action.
+     */
+    size_t pcs[ 3 ];
+
+    /**
+     * @brief If this member is true, then the test action loop is executed.
+     */
+    bool in_action_loop;
+
+    /**
+     * @brief This member contains the next transition map index.
+     */
+    size_t index;
+
+    /**
+     * @brief This member contains the current transition map entry.
+     */
+    Directive_Entry entry;
+  } Map;
 } Directive_Context;
 
 static Directive_Context
@@ -599,7 +619,7 @@ static void Directive_Setup_Wrap( void *arg )
   Directive_Context *ctx;
 
   ctx = arg;
-  ctx->in_action_loop = false;
+  ctx->Map.in_action_loop = false;
   Directive_Setup( ctx );
 }
 
@@ -618,7 +638,7 @@ static void Directive_Teardown_Wrap( void *arg )
   Directive_Context *ctx;
 
   ctx = arg;
-  ctx->in_action_loop = false;
+  ctx->Map.in_action_loop = false;
   Directive_Teardown( ctx );
 }
 
@@ -627,15 +647,6 @@ static void Directive_Action( Directive_Context *ctx )
   ctx->status = rtems_task_ident( ctx->name, ctx->node, ctx->id );
 }
 
-typedef struct {
-  uint16_t Skip : 1;
-  uint16_t Pre_Name_NA : 1;
-  uint16_t Pre_Node_NA : 1;
-  uint16_t Pre_Id_NA : 1;
-  uint16_t Post_Status : 3;
-  uint16_t Post_Id : 3;
-} Directive_Entry;
-
 static const Directive_Entry
 Directive_Entries[] = {
   { 0, 0, 0, 0, Directive_Post_Status_InvAddr, Directive_Post_Id_NullPtr },
@@ -661,8 +672,8 @@ static size_t Directive_Scope( void *arg, char *buf, size_t n )
 
   ctx = arg;
 
-  if ( ctx->in_action_loop ) {
-    return T_get_scope( Directive_PreDesc, buf, n, ctx->pcs );
+  if ( ctx->Map.in_action_loop ) {
+    return T_get_scope( Directive_PreDesc, buf, n, ctx->Map.pcs );
   }
 
   return 0;
@@ -676,8 +687,12 @@ static T_fixture Directive_Fixture = {
   .initial_context = &Directive_Instance
 };
 
-static inline Directive_Entry Directive_GetEntry( size_t index )
+static inline Directive_Entry Directive_PopEntry( Directive_Context *ctx )
 {
+  size_t index;
+
+  index = ctx->Map.index;
+  ctx->Map.index = index + 1;
   return Directive_Entries[
     Directive_Map[ index ]
   ];
@@ -689,38 +704,34 @@ static inline Directive_Entry Directive_GetEntry( size_t index )
 T_TEST_CASE_FIXTURE( Directive, &Directive_Fixture )
 {
   Directive_Context *ctx;
-  size_t index;
 
   ctx = T_fixture_context();
-  ctx->in_action_loop = true;
-  index = 0;
+  ctx->Map.in_action_loop = true;
+  ctx->Map.index = 0;
 
   for (
-    ctx->pcs[ 0 ] = Directive_Pre_Name_Invalid;
-    ctx->pcs[ 0 ] < Directive_Pre_Name_NA;
-    ++ctx->pcs[ 0 ]
+    ctx->Map.pcs[ 0 ] = Directive_Pre_Name_Invalid;
+    ctx->Map.pcs[ 0 ] < Directive_Pre_Name_NA;
+    ++ctx->Map.pcs[ 0 ]
   ) {
     for (
-      ctx->pcs[ 1 ] = Directive_Pre_Node_Local;
-      ctx->pcs[ 1 ] < Directive_Pre_Node_NA;
-      ++ctx->pcs[ 1 ]
+      ctx->Map.pcs[ 1 ] = Directive_Pre_Node_Local;
+      ctx->Map.pcs[ 1 ] < Directive_Pre_Node_NA;
+      ++ctx->Map.pcs[ 1 ]
     ) {
       for (
-        ctx->pcs[ 2 ] = Directive_Pre_Id_NullPtr;
-        ctx->pcs[ 2 ] < Directive_Pre_Id_NA;
-        ++ctx->pcs[ 2 ]
+        ctx->Map.pcs[ 2 ] = Directive_Pre_Id_NullPtr;
+        ctx->Map.pcs[ 2 ] < Directive_Pre_Id_NA;
+        ++ctx->Map.pcs[ 2 ]
       ) {
-        Directive_Entry entry;
-
-        entry = Directive_GetEntry( index );
-        ++index;
+        ctx->Map.entry = Directive_PopEntry( ctx );
 
-        Directive_Pre_Name_Prepare( ctx, ctx->pcs[ 0 ] );
-        Directive_Pre_Node_Prepare( ctx, ctx->pcs[ 1 ] );
-        Directive_Pre_Id_Prepare( ctx, ctx->pcs[ 2 ] );
+        Directive_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+        Directive_Pre_Node_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+        Directive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
         Directive_Action( ctx );
-        Directive_Post_Status_Check( ctx, entry.Post_Status );
-        Directive_Post_Id_Check( ctx, entry.Post_Id );
+        Directive_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+        Directive_Post_Id_Check( ctx, ctx->Map.entry.Post_Id );
       }
     }
   }
@@ -1824,6 +1835,15 @@ void Action2_Run( int *a, int b, int *c );
  * @{
  */
 
+typedef struct {
+  uint16_t Skip : 1;
+  uint16_t Pre_A_NA : 1;
+  uint16_t Pre_B_NA : 1;
+  uint16_t Pre_C_NA : 1;
+  uint16_t Post_A : 3;
+  uint16_t Post_B : 2;
+} Action2_Entry;
+
 /* Context support code */
 
 /**
@@ -1855,16 +1875,27 @@ typedef struct {
    */
   int *c;
 
-  /**
-   * @brief This member defines the pre-condition states for the next action.
-   */
-  size_t pcs[ 3 ];
-
-  /**
-   * @brief This member indicates if the test action loop is currently
-   *   executed.
-   */
-  bool in_action_loop;
+  struct {
+    /**
+     * @brief This member defines the pre-condition states for the next action.
+     */
+    size_t pcs[ 3 ];
+
+    /**
+     * @brief If this member is true, then the test action loop is executed.
+     */
+    bool in_action_loop;
+
+    /**
+     * @brief This member contains the next transition map index.
+     */
+    size_t index;
+
+    /**
+     * @brief This member contains the current transition map entry.
+     */
+    Action2_Entry entry;
+  } Map;
 } Action2_Context;
 
 static Action2_Context
@@ -2094,7 +2125,7 @@ static void Action2_Setup_Wrap( void *arg )
   Action2_Context *ctx;
 
   ctx = arg;
-  ctx->in_action_loop = false;
+  ctx->Map.in_action_loop = false;
   Action2_Setup( ctx );
 }
 
@@ -2113,7 +2144,7 @@ static void Action2_Teardown_Wrap( void *arg )
   Action2_Context *ctx;
 
   ctx = arg;
-  ctx->in_action_loop = false;
+  ctx->Map.in_action_loop = false;
   Action2_Teardown( ctx );
 }
 
@@ -2132,15 +2163,6 @@ static void Action2_Cleanup( Action2_Context *ctx )
   /* Cleanup */
 }
 
-typedef struct {
-  uint16_t Skip : 1;
-  uint16_t Pre_A_NA : 1;
-  uint16_t Pre_B_NA : 1;
-  uint16_t Pre_C_NA : 1;
-  uint16_t Post_A : 3;
-  uint16_t Post_B : 2;
-} Action2_Entry;
-
 static const Action2_Entry
 Action2_Entries[] = {
   { 0, 1, 0, 0, Action2_Post_A_A1, Action2_Post_B_NA },
@@ -2171,8 +2193,8 @@ static size_t Action2_Scope( void *arg, char *buf, size_t n )
 
   ctx = arg;
 
-  if ( ctx->in_action_loop ) {
-    return T_get_scope( Action2_PreDesc, buf, n, ctx->pcs );
+  if ( ctx->Map.in_action_loop ) {
+    return T_get_scope( Action2_PreDesc, buf, n, ctx->Map.pcs );
   }
 
   return 0;
@@ -2186,8 +2208,12 @@ static T_fixture Action2_Fixture = {
   .initial_context = &Action2_Instance
 };
 
-static inline Action2_Entry Action2_GetEntry( size_t index )
+static inline Action2_Entry Action2_PopEntry( Action2_Context *ctx )
 {
+  size_t index;
+
+  index = ctx->Map.index;
+  ctx->Map.index = index + 1;
   return Action2_Entries[
     Action2_Map[ index ]
   ];
@@ -2198,7 +2224,6 @@ static T_fixture_node Action2_Node;
 void Action2_Run( int *a, int b, int *c )
 {
   Action2_Context *ctx;
-  size_t index;
 
   ctx = &Action2_Instance;
   ctx->a = a;
@@ -2206,43 +2231,40 @@ void Action2_Run( int *a, int b, int *c )
   ctx->c = c;
 
   ctx = T_push_fixture( &Action2_Node, &Action2_Fixture );
-  ctx->in_action_loop = true;
-  index = 0;
+  ctx->Map.in_action_loop = true;
+  ctx->Map.index = 0;
 
   for (
-    ctx->pcs[ 0 ] = Action2_Pre_A_A0;
-    ctx->pcs[ 0 ] < Action2_Pre_A_NA;
-    ++ctx->pcs[ 0 ]
+    ctx->Map.pcs[ 0 ] = Action2_Pre_A_A0;
+    ctx->Map.pcs[ 0 ] < Action2_Pre_A_NA;
+    ++ctx->Map.pcs[ 0 ]
   ) {
     for (
-      ctx->pcs[ 1 ] = Action2_Pre_B_B0;
-      ctx->pcs[ 1 ] < Action2_Pre_B_NA;
-      ++ctx->pcs[ 1 ]
+      ctx->Map.pcs[ 1 ] = Action2_Pre_B_B0;
+      ctx->Map.pcs[ 1 ] < Action2_Pre_B_NA;
+      ++ctx->Map.pcs[ 1 ]
     ) {
       for (
-        ctx->pcs[ 2 ] = Action2_Pre_C_C0;
-        ctx->pcs[ 2 ] < Action2_Pre_C_NA;
-        ++ctx->pcs[ 2 ]
+        ctx->Map.pcs[ 2 ] = Action2_Pre_C_C0;
+        ctx->Map.pcs[ 2 ] < Action2_Pre_C_NA;
+        ++ctx->Map.pcs[ 2 ]
       ) {
-        Action2_Entry entry;
-
-        entry = Action2_GetEntry( index );
-        ++index;
+        ctx->Map.entry = Action2_PopEntry( ctx );
 
-        if ( entry.Skip ) {
+        if ( ctx->Map.entry.Skip ) {
           continue;
         }
 
         Action2_Prepare( ctx );
         Action2_Pre_A_Prepare(
           ctx,
-          entry.Pre_A_NA ? Action2_Pre_A_NA : ctx->pcs[ 0 ]
+          ctx->Map.entry.Pre_A_NA ? Action2_Pre_A_NA : ctx->Map.pcs[ 0 ]
         );
-        Action2_Pre_B_Prepare( ctx, ctx->pcs[ 1 ] );
-        Action2_Pre_C_Prepare( ctx, ctx->pcs[ 2 ] );
+        Action2_Pre_B_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+        Action2_Pre_C_Prepare( ctx, ctx->Map.pcs[ 2 ] );
         Action2_Action( ctx );
-        Action2_Post_A_Check( ctx, entry.Post_A );
-        Action2_Post_B_Check( ctx, entry.Post_B );
+        Action2_Post_A_Check( ctx, ctx->Map.entry.Post_A );
+        Action2_Post_B_Check( ctx, ctx->Map.entry.Post_B );
         Action2_Cleanup( ctx );
       }
     }
diff --git a/rtemsspec/transitionmap.py b/rtemsspec/transitionmap.py
index c7f2193..703395c 100644
--- a/rtemsspec/transitionmap.py
+++ b/rtemsspec/transitionmap.py
@@ -616,6 +616,20 @@ class TransitionMap:
             bits += math.ceil(math.log2(len(st_idx_to_st_name)))
         return 2**max(math.ceil(math.log2(bits)), 3)
 
+    def add_map_entry_type(self, content: CContent, ident: str) -> None:
+        """ Adds the transition map entry type definition to the content. """
+        bits = self._get_entry_bits()
+        content.add("typedef struct {")
+        with content.indent():
+            content.append(f"uint{bits}_t Skip : 1;")
+            for condition in self["pre-conditions"]:
+                content.append(f"uint{bits}_t Pre_{condition['name']}_NA : 1;")
+            for condition in self["post-conditions"]:
+                state_bits = math.ceil(math.log2(len(condition["states"]) + 1))
+                content.append(
+                    f"uint{bits}_t Post_{condition['name']} : {state_bits};")
+        content.add(f"}} {ident}_Entry;")
+
     def add_map(self, content: CContent, ident: str) -> None:
         """ Adds the transition map definitions to the content. """
         entries = []
@@ -636,17 +650,6 @@ class TransitionMap:
                 enumerators.append(self._get_entry(ident, transitions[0]))
                 enumerators.append("#endif")
                 entries.append("\n".join(enumerators))
-        bits = self._get_entry_bits()
-        content.add("typedef struct {")
-        with content.indent():
-            content.append(f"uint{bits}_t Skip : 1;")
-            for condition in self["pre-conditions"]:
-                content.append(f"uint{bits}_t Pre_{condition['name']}_NA : 1;")
-            for condition in self["post-conditions"]:
-                state_bits = math.ceil(math.log2(len(condition["states"]) + 1))
-                content.append(
-                    f"uint{bits}_t Post_{condition['name']} : {state_bits};")
-        content.add(f"}} {ident}_Entry;")
         content.add([f"static const {ident}_Entry", f"{ident}_Entries[] = {{"])
         entries[-1] = entries[-1].replace("},", "}")
         content.append(entries)
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index 8b76fe9..48c6507 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -528,23 +528,32 @@ class _ActionRequirementTestItem(_TestItem):
 
     def add_default_context_members(self, content: CContent) -> None:
         super().add_default_context_members(content)
-        content.add_description_block(
-            "This member defines the pre-condition states "
-            "for the next action.", None)
-        content.add(f"size_t pcs[ {self._pre_co_count} ];")
-        content.add_description_block(
-            "This member indicates if the test action loop "
-            "is currently executed.", None)
-        content.add("bool in_action_loop;")
+        content.add("struct {")
+        with content.indent():
+            content.add_description_block(
+                "This member defines the pre-condition states "
+                "for the next action.", None)
+            content.add(f"size_t pcs[ {self._pre_co_count} ];")
+            content.add_description_block(
+                "If this member is true, then the test action "
+                "loop is executed.", None)
+            content.add("bool in_action_loop;")
+            content.add_description_block(
+                "This member contains the next transition map index.", None)
+            content.add("size_t index;")
+            content.add_description_block(
+                "This member contains the current transition map entry.", None)
+            content.add(f"{self.ident}_Entry entry;")
+        content.append("} Map;")
 
     def _add_fixture_scope(self, content: CContent) -> None:
         params = ["void *arg", "char *buf", "size_t n"]
         with content.function("static size_t", f"{self.ident}_Scope", params):
             content.add([f"{self.context} *ctx;", "", "ctx = arg;"])
-            with content.condition("ctx->in_action_loop"):
+            with content.condition("ctx->Map.in_action_loop"):
                 content.call_function(
                     "return", "T_get_scope",
-                    [f"{self.ident}_PreDesc", "buf", "n", "ctx->pcs"])
+                    [f"{self.ident}_PreDesc", "buf", "n", "ctx->Map.pcs"])
             content.add("return 0;")
 
     def _add_call(self, content: CContent, key: str, name: str) -> None:
@@ -554,34 +563,34 @@ class _ActionRequirementTestItem(_TestItem):
 
     def _add_loop_body(self, content: CContent,
                        transition_map: TransitionMap) -> None:
-        content.add(f"{self.ident}_Entry entry;")
-        content.call_function("entry =", f"{self.ident}_GetEntry", ["index"])
-        content.append("++index;")
+        entry = "ctx->Map.entry"
+        content.call_function(f"{entry} =", f"{self.ident}_PopEntry", ["ctx"])
         if transition_map.pre_co_summary[0]:
-            with content.condition("entry.Skip"):
+            with content.condition(f"{entry}.Skip"):
                 content.append("continue;")
         content.add_blank_line()
         self._add_call(content, "test-prepare", "Prepare")
         for index, pre_co in enumerate(self._item["pre-conditions"]):
             content.gap = False
-            state = f"ctx->pcs[ {index} ]"
+            state = f"ctx->Map.pcs[ {index} ]"
             if transition_map.pre_co_summary[index + 1]:
                 enum_na = self._pre_co_idx_to_enum[index][-1]
-                state = f"entry.Pre_{pre_co['name']}_NA ? {enum_na} : {state}"
+                name = pre_co["name"]
+                state = f"{entry}.Pre_{name}_NA ? {enum_na} : {state}"
             prepare = f"{self._pre_co_idx_to_enum[index][0]}_Prepare"
             content.call_function(None, prepare, ["ctx", state])
         self._add_call(content, "test-action", "Action")
         for index, enum in enumerate(self._post_co_idx_to_enum):
             content.gap = False
             content.call_function(None, f"{enum[0]}_Check", [
-                "ctx", f"entry.{transition_map.get_post_entry_member(index)}"
+                "ctx", f"{entry}.{transition_map.get_post_entry_member(index)}"
             ])
         self._add_call(content, "test-cleanup", "Cleanup")
 
     def _add_for_loops(self, content: CContent, transition_map: TransitionMap,
                        index: int) -> None:
         if index < self._pre_co_count:
-            var = f"ctx->pcs[ {index} ]"
+            var = f"ctx->Map.pcs[ {index} ]"
             begin = self._pre_co_idx_to_enum[index][1]
             end = self._pre_co_idx_to_enum[index][-1]
             with content.for_loop(f"{var} = {begin}", f"{var} < {end}",
@@ -593,11 +602,12 @@ class _ActionRequirementTestItem(_TestItem):
     def _add_test_case(self, content: CContent, transition_map: TransitionMap,
                        header: Dict[str, Any]) -> None:
         ret = f"static inline {self.ident}_Entry"
-        name = f"{self.ident}_GetEntry"
-        params = ["size_t index"]
+        name = f"{self.ident}_PopEntry"
+        params = [f"{self.context} *ctx"]
         with content.function(ret, name, params, align=True):
             content.add([
-                f"return {self.ident}_Entries[",
+                "size_t index;", "", "index = ctx->Map.index;",
+                "ctx->Map.index = index + 1;", f"return {self.ident}_Entries[",
                 f"  {self.ident}_Map[ index ]", "];"
             ])
         fixture = f"{self.ident}_Fixture"
@@ -608,11 +618,12 @@ class _ActionRequirementTestItem(_TestItem):
             ret = "void"
             name = f"{self.ident}_Run"
             params = self._get_run_params(header)
-            prologue.add([f"{self.context} *ctx;", "size_t index;"])
+            prologue.add([f"{self.context} *ctx;"])
             self.assign_run_params(prologue, header)
             prologue.call_function("ctx =", "T_push_fixture",
                                    [f"&{self.ident}_Node", f"&{fixture}"])
-            prologue.append(["ctx->in_action_loop = true;", "index = 0;"])
+            prologue.append(
+                ["ctx->Map.in_action_loop = true;", "ctx->Map.index = 0;"])
             epilogue.add("T_pop_fixture();")
             align = True
         else:
@@ -624,9 +635,8 @@ class _ActionRequirementTestItem(_TestItem):
             name = "T_TEST_CASE_FIXTURE"
             params = [f"{self.ident}", f"&{fixture}"]
             prologue.add([
-                f"{self.context} *ctx;", "size_t index;", "",
-                "ctx = T_fixture_context();", "ctx->in_action_loop = true;",
-                "index = 0;"
+                f"{self.context} *ctx;", "", "ctx = T_fixture_context();",
+                "ctx->Map.in_action_loop = true;", "ctx->Map.index = 0;"
             ])
             align = False
         with content.function(ret, name, params, align=align):
@@ -678,6 +688,8 @@ class _ActionRequirementTestItem(_TestItem):
         else:
             _add_condition_enum(content, self._pre_co_idx_to_enum)
             _add_condition_enum(content, self._post_co_idx_to_enum)
+        transition_map = TransitionMap(self.item)
+        transition_map.add_map_entry_type(content, self.ident)
         instance = self.add_context(content)
         self._add_pre_condition_descriptions(content)
         content.add(self.substitute_code(self["test-support"]))
@@ -685,7 +697,7 @@ class _ActionRequirementTestItem(_TestItem):
                           self._pre_co_idx_to_enum, "Prepare")
         self._add_handler(content, self["post-conditions"],
                           self._post_co_idx_to_enum, "Check")
-        optional_code = "ctx->in_action_loop = false;"
+        optional_code = "ctx->Map.in_action_loop = false;"
         setup = self.add_support_method(content,
                                         "test-setup",
                                         "Setup",
@@ -701,7 +713,6 @@ class _ActionRequirementTestItem(_TestItem):
         self.add_function(content, "test-prepare", "Prepare")
         self.add_function(content, "test-action", "Action")
         self.add_function(content, "test-cleanup", "Cleanup")
-        transition_map = TransitionMap(self.item)
         transition_map.add_map(content, self.ident)
         self._add_fixture_scope(content)
         content.add([



More information about the vc mailing list