Boost logo

Boost Users :

From: David Greene (greened_at_[hidden])
Date: 2006-02-21 20:03:11


Andreas Huber wrote:
> Hi Dave,

Hi Andreas, thanks for your help.

> David Greene wrote:
>
>>David Greene wrote:
>>
>>>If I have an asynchronous state machine running in another thread and
>>>I send it an event, is there any way to have the sending thread block
>>>until the event is processed?
>
>
> Yes: Add a boost::function member to the event. Have the member point to
> a function which calls notify_one() on a boost::condition. Have the
> sending thread call wait() on the condition. When processing the event
> inside the state_machine, call the boost::function member.

Hmm...that's rather complex, but it makes sense.

>>Quick follow-up: when the documentation says that
>>FifoWorker::operator() "must only be called from exactly one thread,"
>>does that mean it must be called only from one thread at any given
>>time (i.e. it must be protected with mutexes or other concurrency
>>protection) or that literally only one thread may ever call it and it
>>must always be the same thread that calls it?
>
>
> The latter. fifo_worker::operator() calls terminated(), which in turn
> returns the bool member terminated_. This call chain is not protected by
> mutexes. Picture the following scenario with one fifo_worker object:
> 1. Thread A, which is executed on CPU 1, calls operator(). Inside
> operator(), terminated_ is modified and operator() returns.
> 2. Thread B, which is executed on CPU 2, calls operator(), after thread
> A has returned from operator().
>
> Nowadays both CPUs tend to have caches. Whether or not the cache
> contents is guaranteed to be written back to the main memory when thread
> A returns depends on the architecture of your hardware. IIRC, on X86
> architectures there is such a guarantee. On other architectures you
> might need to use mutexes or a similar concept to guarantee that thread
> B sees the updates of thread A.

Mutexes don't effect cache coherence. Likely there will have to be
calls to special intrinsics depending on the architecture.

>>If it's the latter then that changes things quite dramatically and I
>>probably want a blocking scheduler and will need to create another
>>thread just to wait on empty and call operator() when full.
>
> I'm not sure I understand that. You only need to create a blocking
> scheduler and call operator() on it, that's it. operator() will return
> when you call terminate() from any other thread.

Yes, what I said doesn't make sense given your solution outlined
above.

Hmm...I was going to use a synchronous machine due to the state
access problems I outlined in another message, but now I see that
won't work if terminated_ is in cacheable memory and there is no
hardware coherence. For my purposes that's probably ok because
we'll only run on machines with hardware coherence. Therefore
if I understand you correctly, it's ok if different threads
calls process_event() as long as the call (and any call to
statechart routines) are guarded by mutexes to avoid the
non-reentrancy problems.

                              -Dave


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net