summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorschodet2008-07-30 09:34:41 +0000
committerschodet2008-07-30 09:34:41 +0000
commit424724d99dd2f2a96517b5698e0d1ae44adb5772 (patch)
tree1af40834da460b69ece524a68466c6b39ac7db00 /cesar
parenta6a300f73703dc58ea68c15096273bdff589ad62 (diff)
* cp2/fsm:
- add support for enter/leave. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2690 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar')
-rw-r--r--cesar/cp2/fsm/inc/tables.h8
-rw-r--r--cesar/cp2/fsm/src/fsm.c33
-rw-r--r--cesar/cp2/fsm/src/fsm/template_defs.h3
-rw-r--r--cesar/cp2/fsm/src/fsm/template_tables.h10
-rw-r--r--cesar/cp2/fsm/test/utest/inc/scenario_defs.h8
-rw-r--r--cesar/cp2/fsm/test/utest/override/cp2/fsm/src/fsm/cp.fsm11
-rw-r--r--cesar/cp2/fsm/test/utest/src/fsm_stub.c36
-rw-r--r--cesar/cp2/fsm/test/utest/src/test_fsm.c27
8 files changed, 133 insertions, 3 deletions
diff --git a/cesar/cp2/fsm/inc/tables.h b/cesar/cp2/fsm/inc/tables.h
index b57a2564e6..eea3cdfa60 100644
--- a/cesar/cp2/fsm/inc/tables.h
+++ b/cesar/cp2/fsm/inc/tables.h
@@ -21,6 +21,14 @@ cp_fsm_transition_table[CP_FSM_STATE_NB][CP_FSM_EVENT_TYPE_NB];
extern const cp_fsm_state_t
cp_fsm_only_branch_table[CP_FSM_STATE_NB][CP_FSM_EVENT_TYPE_NB];
+/* Control Plane FSM state enter table. */
+const cp_fsm_enter_leave_t
+cp_fsm_enter_table[CP_FSM_STATE_NB];
+
+/* Control Plane FSM state leave table. */
+const cp_fsm_enter_leave_t
+cp_fsm_leave_table[CP_FSM_STATE_NB];
+
/* Control Plane FSM initial states table. */
extern const cp_fsm_state_t
cp_fsm_initials_table[CP_FSM_INITIAL_NB];
diff --git a/cesar/cp2/fsm/src/fsm.c b/cesar/cp2/fsm/src/fsm.c
index 1605dec6f9..4c673e2bf4 100644
--- a/cesar/cp2/fsm/src/fsm.c
+++ b/cesar/cp2/fsm/src/fsm.c
@@ -24,6 +24,9 @@ cp_fsm_init (cp_t *ctx)
dbg_assert (ctx);
for (i = 0; i < CP_FSM_INITIAL_NB; i++)
ctx->fsm.active_states[i] = cp_fsm_initials_table[i];
+ for (i = 0; i < CP_FSM_INITIAL_NB; i++)
+ if (cp_fsm_enter_table[i])
+ cp_fsm_enter_table[i] (ctx);
ctx->fsm.handled_event = NULL;
ctx->fsm.head = NULL;
ctx->fsm.tail = NULL;
@@ -44,6 +47,27 @@ cp_fsm_uninit (cp_t *ctx)
}
/**
+ * Execute callbacks attached to enter and leave action of states.
+ * \param ctx control plane context
+ * \param i active state index
+ * \param to state entered
+ */
+static void
+cp_fsm_leave_enter (cp_t *ctx, uint i, cp_fsm_state_t to)
+{
+ dbg_assert (ctx);
+ dbg_assert (i < CP_FSM_INITIAL_NB);
+ dbg_assert (to < CP_FSM_STATE_NB);
+ cp_fsm_state_t from = ctx->fsm.active_states[i];
+ dbg_assert (from < CP_FSM_STATE_NB);
+ if (cp_fsm_leave_table[from])
+ cp_fsm_leave_table[from] (ctx);
+ ctx->fsm.active_states[i] = to;
+ if (cp_fsm_enter_table[to])
+ cp_fsm_enter_table[to] (ctx);
+}
+
+/**
* Handle event for one active state.
* \param ctx control plane context
* \param e event to handle
@@ -52,6 +76,9 @@ cp_fsm_uninit (cp_t *ctx)
static void
cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
{
+ dbg_assert (ctx);
+ dbg_assert (e);
+ dbg_assert (i < CP_FSM_INITIAL_NB);
cp_fsm_transition_t t =
cp_fsm_transition_table[ctx->fsm.active_states[i]][e->type];
if (t)
@@ -71,7 +98,7 @@ cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
"no branch selected");
dbg_assert (to < CP_FSM_STATE_NB);
if (to != CP_FSM_STATE_NB) /* Be clement for errors. */
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}
}
@@ -83,7 +110,7 @@ cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
if (to != CP_FSM_STATE_NB)
{
dbg_assert (to < CP_FSM_STATE_NB);
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}
}
@@ -153,7 +180,7 @@ cp_fsm_branch_ (cp_t *ctx, cp_fsm_branch_t branch)
"bad branch");
/* Select this branch. */
cp_fsm_state_t to = ((uint) branch) & 0xff;
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}
diff --git a/cesar/cp2/fsm/src/fsm/template_defs.h b/cesar/cp2/fsm/src/fsm/template_defs.h
index de7f0e9e84..d61762c492 100644
--- a/cesar/cp2/fsm/src/fsm/template_defs.h
+++ b/cesar/cp2/fsm/src/fsm/template_defs.h
@@ -39,6 +39,9 @@ typedef enum %(prefix)s_branch_t %(prefix)s_branch_t;
/* %(name)s transition type. */
typedef void *%(prefix)s_transition_t;
+/* %(name)s enter/leave type. */
+typedef void (*%(prefix)s_enter_leave_t) (cp_t *ctx);
+
/* Value to use to follow a given branch. */
#define %(PREFIX)s_BRANCH(state, event, branch) \
%(PREFIX)s_BRANCH__ ## state ## __ ## event ## __ ## branch
diff --git a/cesar/cp2/fsm/src/fsm/template_tables.h b/cesar/cp2/fsm/src/fsm/template_tables.h
index e0d6dbe4d3..c6fbefb1ac 100644
--- a/cesar/cp2/fsm/src/fsm/template_tables.h
+++ b/cesar/cp2/fsm/src/fsm/template_tables.h
@@ -15,6 +15,16 @@ const %(prefix)s_state_t
%(prefix)s_only_branch_table[%(PREFIX)s_STATE_NB][%(PREFIX)s_EVENT_TYPE_NB] = {
%(only_branch_table)s};
+/* %(name)s state enter table. */
+const %(prefix)s_enter_leave_t
+%(prefix)s_enter_table[%(PREFIX)s_STATE_NB] = {
+%(states,%(@enter|NULL)s)s};
+
+/* %(name)s state leave table. */
+const %(prefix)s_enter_leave_t
+%(prefix)s_leave_table[%(PREFIX)s_STATE_NB] = {
+%(states,%(@leave|NULL)s)s};
+
/* %(name)s initial states table. */
const %(prefix)s_state_t
%(prefix)s_initials_table[%(PREFIX)s_INITIAL_NB] = {
diff --git a/cesar/cp2/fsm/test/utest/inc/scenario_defs.h b/cesar/cp2/fsm/test/utest/inc/scenario_defs.h
index 945924c4b9..65f98da665 100644
--- a/cesar/cp2/fsm/test/utest/inc/scenario_defs.h
+++ b/cesar/cp2/fsm/test/utest/inc/scenario_defs.h
@@ -49,6 +49,10 @@ scenario_action_post_and_process_cb (scenario_globals_t *globals,
cp_fsm__STATE3__event1, \
cp_fsm__STATE3__event2, \
cp_fsm__STATE4__event1, \
+ cp_fsm__STATE5__enter, \
+ cp_fsm__STATE5__leave, \
+ cp_fsm__STATE6__enter, \
+ cp_fsm__STATE6__leave, \
cp_fsm__STATEA__eventb, \
cp_fsm__STATEB__eventa
@@ -77,6 +81,10 @@ scenario_event_cp_fsm__STATE3__event1_t;
typedef scenario_empty_t scenario_event_cp_fsm__STATE3__event2_t;
typedef scenario_event_transition_with_branch_t
scenario_event_cp_fsm__STATE4__event1_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE5__enter_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE5__leave_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE6__enter_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE6__leave_t;
typedef scenario_empty_t scenario_event_cp_fsm__STATEA__eventb_t;
typedef scenario_empty_t scenario_event_cp_fsm__STATEB__eventa_t;
diff --git a/cesar/cp2/fsm/test/utest/override/cp2/fsm/src/fsm/cp.fsm b/cesar/cp2/fsm/test/utest/override/cp2/fsm/src/fsm/cp.fsm
index f3a2fe523b..76ad45a617 100644
--- a/cesar/cp2/fsm/test/utest/override/cp2/fsm/src/fsm/cp.fsm
+++ b/cesar/cp2/fsm/test/utest/override/cp2/fsm/src/fsm/cp.fsm
@@ -6,6 +6,8 @@ States:
STATE2
STATE3
STATE4
+ STATE5 [enter=cp_fsm__STATE5__enter leave=cp_fsm__STATE5__leave]
+ STATE6 [enter=cp_fsm__STATE6__enter leave=cp_fsm__STATE6__leave]
*STATEA
STATEB
@@ -14,6 +16,8 @@ Events:
event2
event3
event4
+ event5
+ event6
error_event_no_branch
test error conditions: no branch selected
error_event_bad_branch
@@ -29,6 +33,7 @@ Events:
STATE1:
event1 -> .
event2 -> STATE2
+ event5 -> STATE5 [NULL]
error_event_no_branch: branch1 -> .
error_event_no_branch: branch2 -> .
error_event_bad_branch: branch1 -> .
@@ -51,6 +56,12 @@ STATE3, STATE4:
event1: branch1 -> STATE1
event1: branch2 -> .
+STATE5:
+ event6 -> STATE6 [NULL]
+
+STATE6:
+ event1 -> STATE1 [NULL]
+
STATEA:
eventb -> STATEB
diff --git a/cesar/cp2/fsm/test/utest/src/fsm_stub.c b/cesar/cp2/fsm/test/utest/src/fsm_stub.c
index 86e595c5a7..3ddd0f60c6 100644
--- a/cesar/cp2/fsm/test/utest/src/fsm_stub.c
+++ b/cesar/cp2/fsm/test/utest/src/fsm_stub.c
@@ -55,6 +55,18 @@ void
cp_fsm__STATE4__event1 (cp_t *ctx);
void
+cp_fsm__STATE5__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE5__leave (cp_t *ctx);
+
+void
+cp_fsm__STATE6__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE6__leave (cp_t *ctx);
+
+void
cp_fsm__STATEA__eventb (cp_t *ctx);
void
@@ -145,6 +157,30 @@ cp_fsm__STATE4__event1 (cp_t *ctx)
}
void
+cp_fsm__STATE5__enter (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE5__enter);
+}
+
+void
+cp_fsm__STATE5__leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE5__leave);
+}
+
+void
+cp_fsm__STATE6__enter (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE6__enter);
+}
+
+void
+cp_fsm__STATE6__leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE6__leave);
+}
+
+void
cp_fsm__STATEA__eventb (cp_t *ctx)
{
scenario_event (cp_fsm__STATEA__eventb);
diff --git a/cesar/cp2/fsm/test/utest/src/test_fsm.c b/cesar/cp2/fsm/test/utest/src/test_fsm.c
index 3f5a88c28e..d6976b4f23 100644
--- a/cesar/cp2/fsm/test/utest/src/test_fsm.c
+++ b/cesar/cp2/fsm/test/utest/src/test_fsm.c
@@ -163,6 +163,33 @@ test_fsm_basic_test_case (test_t t)
test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
cp_fsm_uninit (&cp);
} test_end;
+ test_begin (t, "enter leave")
+ {
+ cp_fsm_init (&cp);
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event5),
+ SCENARIO_EVENT (cp_fsm__STATE5__enter),
+ /* STATE5 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event6),
+ SCENARIO_EVENT (cp_fsm__STATE5__leave),
+ SCENARIO_EVENT (cp_fsm__STATE6__enter),
+ /* STATE6 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE6__leave),
+ /* STATE1 */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
}
void