[msm] Message queue and copy constructed events

Hi Michael,
in case we use message queueing in our state machines (which we actually have to because otherwise the pseudo exit state behaviour will not work correctly) our events have to implement a copy constructor because there is a possibility that some of them are queued.
Actually for the pseudo exit states it's also so that the event from the outgoing transition can be convertible from the event coming from the inner transition.
We do not want that events get copied because they are very big and it certainly decreases our performance. Could you not just store pointers to events so that the events do not get copy constructed again? Our understanding of the queuing implementation is that the event instance is valid as long as the outer most process_event() is not returned to the caller. In that case it is not a problem to just store those pointers.
I suppose you are still talking about the pseudo exit states. It's not that simple because queuing can happen surprisingly fast. One could decide to defer inside the action method of the transition exiting the pseudo exit. It's a corner case, but I can imagine someone will one day find a use of it, like for about every single feature I put inside msm.
We also could use shared pointers as events and so only the shared pointers get copy constructed. But this would mean that we have to put all our events into shared pointers which also decreases performance and it would look like strange passing shared pointer as reference to the process_event() method.
Do you have another idea in order to overcome this?
Why not simply pimpl the big data from the event inside a shared_ptr as event's attribute? Or more efficiently, as I understand your data is useful only until the end of a process_event, keep a pointer to it, for example something like: { Data data; fsm.process_event(my_event(&data)); } // data is gone here
At the moment, we can not think of a proper solution for deferred events. In that case there would be no other solution than copy deferred events.
I'd prefer to avoid confusing users by using different behaviors, especially as the above solution seems pretty simple to implement.
Anyway, we would like to have a mechanism in order to influence the queue implentation and change it to a user definied implementation. Would it be possible to pass the queue type as an optional template argument to the state machine? This would the make state machine even more flexible and one does not have to use std::queue.
I'm thinking about this because someone requested the possibility of using no heap at all and providing a fixed-size array instead. It seems a reasonable request. Regards, Christophe

Hi Christophe I have that request as well to use the MSM without heap actually I have managed to compile MSM in an embedded target without stdlib, rtti, exception and no heap but only if queues are disabled. Second the memory allocation for the events in our application is very important. We have to make sure that events are allocated next to each other in a specific memory area. For data cash hit rate and because DMA transfers from/to peripherals in the processor bus. Therefore we use our own memory management for events via factory. The real time scheduler implements reference counting of events when ever an RTC step is triggered we increment the reference count of the event and if an object stores an event in the system it uses a queue from the RT scheduler where the insert of the queue will increment the reference count and removal from the queue is decrementing the reference count. we have different consecutive memories for different event types grouped carefully to task and to task priority and size. In our system we never copy events and for us the best would be if you could just able to provide us a backend to use our own event queue implementation where we make sure that we use a queue form the RT scheduler where no copy operation is required. We implementing OSI L2/L3 layer protocol stack where we have to deal with 100Kbit of data in every 1ms in worst case where we have 10 ~ 20 state machines interacting with each in each 1ms. Because of this we simply can not allow copy of the data. We can come up with some container type which can be used to pass around instead of the event and implement copy constructor as you suggest but it brings overhead compare to using non copying queues which are user defined. thanks Richie On 15 June 2010 15:55, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
Hi Michael,
in case we use message queueing in our state machines (which we actually have to because otherwise the pseudo exit state behaviour will not work correctly) our events have to implement a copy constructor because there is a possibility that some of them are queued.
Actually for the pseudo exit states it's also so that the event from the outgoing transition can be convertible from the event coming from the inner transition.
We do not want that events get copied because they are very big and it certainly decreases our performance. Could you not just store pointers to events so that the events do not get copy constructed again? Our understanding of the queuing implementation is that the event instance is valid as long as the outer most process_event() is not returned to the caller. In that case it is not a problem to just store those pointers.
I suppose you are still talking about the pseudo exit states. It's not that simple because queuing can happen surprisingly fast. One could decide to defer inside the action method of the transition exiting the pseudo exit. It's a corner case, but I can imagine someone will one day find a use of it, like for about every single feature I put inside msm.
We also could use shared pointers as events and so only the shared pointers get copy constructed. But this would mean that we have to put all our events into shared pointers which also decreases performance and it would look like strange passing shared pointer as reference to the process_event() method.
Do you have another idea in order to overcome this?
Why not simply pimpl the big data from the event inside a shared_ptr as event's attribute? Or more efficiently, as I understand your data is useful only until the end of a process_event, keep a pointer to it, for example something like:
{ Data data; fsm.process_event(my_event(&data)); } // data is gone here
At the moment, we can not think of a proper solution for deferred events. In that case there would be no other solution than copy deferred events.
I'd prefer to avoid confusing users by using different behaviors, especially as the above solution seems pretty simple to implement.
Anyway, we would like to have a mechanism in order to influence the queue implentation and change it to a user definied implementation. Would it be possible to pass the queue type as an optional template argument to the state machine? This would the make state machine even more flexible and one does not have to use std::queue.
I'm thinking about this because someone requested the possibility of using no heap at all and providing a fixed-size array instead. It seems a reasonable request.
Regards, Christophe _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Christophe Henry
-
Richard Szabo