Boost logo

Boost :

From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2004-05-26 04:42:17

"Andreas Huber" <ah2003_at_[hidden]> wrote in message
> Rob Stewart wrote:
> > From: Andreas Huber <ah2003_at_[hidden]>
> >>
> >>> Could the fsm manage a container of (pointers to) state objects
> >>> that it populates as it first creates each state object and from
> >>> which it retrieves a state object when transitioning? IOW, the
> >>> first time the fsm encounters the need to transition to a given
> >>> state (from A to B, say), it creates B and tracks it in the
> >>> container. Upon transition back to A, the fsm locates state A in
> >>> the container and reuses it.
> >>
> >> This is certainly possible. I just have my doubts whether this
> >> approach is so much better speed-wise. If you customize state memory
> >> management, construction and destruction doesn't take an awful
> >> amount of cycles. Searching that state container might well take
> >> longer for large FSMs.
> >
> > That's certainly an important consideration, but I was thinking
> > in terms of something built into the fsm framework, thus
> > providing the benefit for all clients versus requiring clients to
> > do work if they want the speed improvement. If your concern
> > proves correct, then using the container approach isn't helpful.
> > However, the states' base class, which I presume is part of your
> > library, could provide a pool allocator for state objects. That
> > would put the onus on the library, rather than the clients, and
> > would still reduce the (perceived, not proven) overhead caused by
> > creating and destroying state objects on each transition.
> <rationale quote>
> simple_state<> and state<> subclass objects are constructed and destructed
> only by the state machine. It would therefore be possible to use the
> state_machine<> allocator instead of forcing the user to overload operator
> new() and operator delete(). However, a lot of systems employ at most one
> instance of a particular state machine, which means that a) there is at
> one object of a particular state and b) this object is always constructed,
> accessed and destructed by one and the same thread. We can exploit these
> facts in a much simpler (and faster) new/delete implementation (for
> see UniqueObject.hpp in the BitMachine example). However, this is only
> possible as long as we have the freedom to customize memory management for
> state classes separately.
> </rationale quote>
> Building a pool allocator into state_machine<> or even using the one that
> the user can pass would mean to needlessly throw away some opportunities
> optimization. The user has to make that decision.
> > Don't forget, though, that part of my proposal was that state
> > objects would have enter() and exit() mfs rather than relying on
> > the ctor and dtor for entry and exit, respectively. That can
> > simplify matters when dealing with exceptions.
> The longer I think about it the more am I convinced that separate entry()
> and exit() functions don't buy you anything w.r.t to exception handling
> my discussion with Dave).

He's definitely the expert on the subject in question. Exception handling
aside for a moment, I still would strongly prefer to have separate
entry/exit methods in the state object interface; it more clearly relates to
the conceptual view of FSMs. And, while we're at it: perhaps the
entry()/exit() points should be user configurable (per-state-type) to
correspond to the UML notation e.g. "entry() / init()", "exit() /
cleanup()" IIRC.

As I haven't been following your discussion with Dave; is this also a
performance concern (function call overhead)?

// Johan

Boost list run by bdawes at, gregod at, cpdaniel at, john at