done. Two issues remain, nevertheless:
A) What happens if any future plugin for some reason does something more
complex, let's say O(n^k) per event, would it still be possible to do
this on the rt thread? Propably not. But anyway, how could one possibly
guaranty rt processing of such a problem? Propably not at all?
ardour has evolved a lot in this area in the last month. the transport
state is a classic non-RT mechanism (it often requires disk seeks, for
example). all changes to transport state with a non-RT element are
divided into two functions, the RT part and the non-RT part. the
non-RT part is queued with another thread (which not uncoincidentally
is the thread that would handle disk i/o anyway), and until its
finished its work, nothing much happens in the audio thread (we just
do silence or some equivalent). once its finished, we run the RT
component of the state change, and then the audio thread can run
"normally".
what is critical about this design is that it delegates "classes of
activity" to the correct thread, but (and this is the key part) the
audio thread is the initiator of all such delegation. as a result, the
audio thread is never "suprised" by anything happening behind its
back: if the disk thread is doing something, the audio thread already
knows about it.
B) How to implement a lock-free fifo? Or rather: is
there some ready to
use implementation of it?
i just use RingBuffer<Event*> (assuming you know C++ syntax). pseudo
code:
delivery:
Event* event;
event = new Event (arg1, arg2, ...);
pending_events.write (&event, 1);
receipt:
Event* event;
if (pending_events.read (&event, 1) == 1) {
process_event (event);
}
this does have one problem in that it limits the number of queued
events, but i set it to a large number (size is N * sizeof(Event*)),
and don't worry about it.
--p