Skip to content

Commit 0197d82

Browse files
committed
Rework am_hsm_dispatch() by factoring out hsm_transition()
1 parent 36edf89 commit 0197d82

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

libs/hsm/hsm.c

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -165,40 +165,16 @@ static void hsm_enter_and_init(struct am_hsm *hsm, struct am_hsm_path *path) {
165165
hsm_set_state(hsm, &path->state[0]);
166166
}
167167

168-
static enum am_hsm_rc hsm_dispatch(
169-
struct am_hsm *hsm, const struct am_event *event
168+
/**
169+
* Transition from source to destination state.
170+
*
171+
* @param hsm transition the state of this HSM
172+
* @param src the source state
173+
* @param dst the destination state
174+
*/
175+
static void hsm_transition(
176+
struct am_hsm *hsm, struct am_hsm_state src, struct am_hsm_state dst
170177
) {
171-
struct am_hsm_state src = {.fn = NULL, .ifn = 0};
172-
struct am_hsm_state state = hsm->state;
173-
enum am_hsm_rc rc = AM_HSM_RC_HANDLED;
174-
/*
175-
* propagate event up the ancestor chain till it is either
176-
* handled or ignored or triggers transition
177-
*/
178-
int cnt = HSM_HIERARCHY_DEPTH_MAX;
179-
do {
180-
src = hsm->state;
181-
hsm->state = state;
182-
/* preserve hsm->ifn as the instance of src.fn */
183-
rc = src.fn(hsm, event);
184-
--cnt;
185-
AM_ASSERT(cnt); /* HSM hierarchy depth exceeds HSM_HIERARCHY_DEPTH_MAX*/
186-
} while (AM_HSM_RC_SUPER == rc);
187-
188-
{
189-
bool tran = (AM_HSM_RC_TRAN == rc) || (AM_HSM_RC_TRAN_REDISPATCH == rc);
190-
if (!tran) { /* event was handled or ignored */
191-
hsm_set_state(hsm, &state);
192-
return rc;
193-
}
194-
}
195-
196-
/* the event triggered state transition */
197-
198-
struct am_hsm_state dst = hsm->state;
199-
AM_ASSERT(dst.fn != am_hsm_top); /* transition to am_hsm_top() is invalid */
200-
hsm_set_state(hsm, &state);
201-
202178
if (!am_hsm_state_is_eq(hsm, &src)) {
203179
hsm_exit(hsm, /*until=*/&src);
204180
hsm_set_state(hsm, &src);
@@ -212,7 +188,7 @@ static enum am_hsm_rc hsm_dispatch(
212188
path.len = 1;
213189
hsm_exit_state(hsm);
214190
hsm_enter_and_init(hsm, &path);
215-
return rc;
191+
return;
216192
}
217193

218194
struct am_hsm_state until = AM_HSM_STATE_CTOR(am_hsm_top);
@@ -222,7 +198,7 @@ static enum am_hsm_rc hsm_dispatch(
222198
/* src is LCA */
223199
--path.len;
224200
hsm_enter_and_init(hsm, &path);
225-
return rc;
201+
return;
226202
}
227203

228204
/*
@@ -241,13 +217,48 @@ static enum am_hsm_rc hsm_dispatch(
241217
/* LCA is found and it is not am_hsm_top() */
242218
path.len = i;
243219
hsm_enter_and_init(hsm, &path);
244-
return rc;
220+
return;
245221
}
246222
}
247223
hsm_exit_state(hsm);
248224
}
249225
/* LCA is am_hsm_top() */
250226
hsm_enter_and_init(hsm, &path);
227+
}
228+
229+
static enum am_hsm_rc hsm_dispatch(
230+
struct am_hsm *hsm, const struct am_event *event
231+
) {
232+
struct am_hsm_state src = {.fn = NULL, .ifn = 0};
233+
struct am_hsm_state state = hsm->state;
234+
enum am_hsm_rc rc = AM_HSM_RC_HANDLED;
235+
/*
236+
* propagate event up the ancestor chain till it is either
237+
* handled or ignored or triggers transition
238+
*/
239+
int cnt = HSM_HIERARCHY_DEPTH_MAX;
240+
do {
241+
src = hsm->state;
242+
hsm->state = state;
243+
/* preserve hsm->ifn as the instance of src.fn */
244+
rc = src.fn(hsm, event);
245+
--cnt;
246+
AM_ASSERT(cnt); /* HSM hierarchy depth exceeds HSM_HIERARCHY_DEPTH_MAX*/
247+
} while (AM_HSM_RC_SUPER == rc);
248+
249+
bool tran = (AM_HSM_RC_TRAN == rc) || (AM_HSM_RC_TRAN_REDISPATCH == rc);
250+
if (!tran) { /* event was handled or ignored */
251+
hsm_set_state(hsm, &state);
252+
return rc;
253+
}
254+
255+
/* the event triggered state transition */
256+
257+
struct am_hsm_state dst = hsm->state;
258+
AM_ASSERT(dst.fn != am_hsm_top); /* transition to am_hsm_top() is invalid */
259+
hsm_set_state(hsm, &state);
260+
261+
hsm_transition(hsm, src, dst);
251262

252263
return rc;
253264
}

0 commit comments

Comments
 (0)