From b075c67e514be77381509464cc44b0ec2406cf71 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 20 Sep 2019 09:33:24 -0600 Subject: [PATCH] use boost::intrusive to manage FSM events (this is all RT code) --- libs/ardour/ardour/transport_fsm.h | 28 ++++++++++------ libs/ardour/transport_fsm.cc | 54 +++++++++++++++--------------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/libs/ardour/ardour/transport_fsm.h b/libs/ardour/ardour/transport_fsm.h index efc5bb161a..4c282e6297 100644 --- a/libs/ardour/ardour/transport_fsm.h +++ b/libs/ardour/ardour/transport_fsm.h @@ -4,6 +4,11 @@ #include #include +#include +#include +#include +#include + #include "pbd/demangle.h" #include "pbd/stacktrace.h" @@ -30,7 +35,7 @@ struct TransportFSM LocateDone }; - struct FSMEvent { + struct FSMEvent : public boost::intrusive::list_base_hook<> { EventType type; union { bool abort; /* for stop */ @@ -122,10 +127,10 @@ struct TransportFSM void stop_playback (); void start_saved_locate (); void roll_after_locate (); - void start_locate (FSMEvent const *); - void interrupt_locate (FSMEvent const *); - void save_locate_and_start_declick (FSMEvent const *); - void start_declick (FSMEvent const *); + void start_locate (FSMEvent const &); + void interrupt_locate (FSMEvent const &); + void save_locate_and_start_declick (FSMEvent const &); + void start_declick (FSMEvent const &); /* guards */ @@ -140,7 +145,7 @@ struct TransportFSM bool declick_in_progress() { return _motion_state == DeclickToLocate || _motion_state == DeclickToStop; } void enqueue (FSMEvent* ev) { - queued_events.push (ev); + queued_events.push_back (*ev); if (!processing) { process_events (); } @@ -152,18 +157,19 @@ struct TransportFSM void transition (ButlerState bs); void process_events (); - bool process_event (FSMEvent *); + bool process_event (FSMEvent&); FSMEvent _last_locate; FSMEvent _last_stop; TransportAPI* api; - std::queue queued_events; - std::list deferred_events; + typedef boost::intrusive::list EventList; + EventList queued_events; + EventList deferred_events; int processing; - void defer (FSMEvent* ev); - void bad_transition (FSMEvent const *); + void defer (FSMEvent& ev); + void bad_transition (FSMEvent const &); }; } /* end namespace ARDOUR */ diff --git a/libs/ardour/transport_fsm.cc b/libs/ardour/transport_fsm.cc index 4c7251328f..2b02346852 100644 --- a/libs/ardour/transport_fsm.cc +++ b/libs/ardour/transport_fsm.cc @@ -41,7 +41,7 @@ void* TransportFSM::FSMEvent::operator new (size_t) { return pool->alloc(); -} + } void TransportFSM::FSMEvent::operator delete (void *ptr, size_t /*size*/) @@ -71,13 +71,11 @@ TransportFSM::process_events () processing++; while (!queued_events.empty()) { - FSMEvent* ev = queued_events.front(); - queued_events.pop (); MotionState oms = _motion_state; ButlerState obs = _butler_state; - if (process_event (ev)) { /* event processed successfully */ + if (process_event (queued_events.front())) { /* event processed successfully */ if (oms != _motion_state || obs != _butler_state) { @@ -88,9 +86,9 @@ TransportFSM::process_events () if (!deferred_events.empty() ){ DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("processing %1 deferred events\n", deferred_events.size())); - for (std::list::iterator e = deferred_events.begin(); e != deferred_events.end(); ) { - FSMEvent* deferred_ev = *e; - if (process_event (deferred_ev)) { /* event processed, remove from deferred */ + for (EventList::iterator e = deferred_events.begin(); e != deferred_events.end(); ) { + FSMEvent* deferred_ev = &(*e); + if (process_event (*e)) { /* event processed, remove from deferred */ e = deferred_events.erase (e); delete deferred_ev; } else { @@ -101,6 +99,8 @@ TransportFSM::process_events () } } + FSMEvent* ev = &queued_events.front(); + queued_events.pop_front (); delete ev; } @@ -166,18 +166,18 @@ TransportFSM::current_state () const } void -TransportFSM::bad_transition (FSMEvent const * ev) +TransportFSM::bad_transition (FSMEvent const & ev) { - error << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev->type) << endmsg; - std::cerr << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev->type) << std::endl; + error << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev.type) << endmsg; + std::cerr << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev.type) << std::endl; } bool -TransportFSM::process_event (FSMEvent* ev) +TransportFSM::process_event (FSMEvent& ev) { - DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("process %1\n", enum_2_string (ev->type))); + DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("process %1\n", enum_2_string (ev.type))); - switch (ev->type) { + switch (ev.type) { case StartTransport: switch (_motion_state) { @@ -305,11 +305,11 @@ TransportFSM::start_playback () } void -TransportFSM::start_declick (FSMEvent const * s) +TransportFSM::start_declick (FSMEvent const & s) { - assert (s->type == StopTransport); + assert (s.type == StopTransport); DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_declick\n"); - _last_stop = *s; + _last_stop = s; } void @@ -320,20 +320,20 @@ TransportFSM::stop_playback () } void -TransportFSM::save_locate_and_start_declick (FSMEvent const * l) +TransportFSM::save_locate_and_start_declick (FSMEvent const & l) { - assert (l->type == Locate); + assert (l.type == Locate); DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::save_locate_and_stop\n"); - _last_locate = *l; + _last_locate = l; _last_stop = FSMEvent (StopTransport, false, false); } void -TransportFSM::start_locate (FSMEvent const * l) +TransportFSM::start_locate (FSMEvent const & l) { - assert (l->type == Locate); + assert (l.type == Locate); DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_locate\n"); - api->locate (l->target, l->with_roll, l->with_flush, l->with_loop, l->force); + api->locate (l.target, l.with_roll, l.with_flush, l.with_loop, l.force); } void @@ -344,14 +344,14 @@ TransportFSM::start_saved_locate () } void -TransportFSM::interrupt_locate (FSMEvent const * l) +TransportFSM::interrupt_locate (FSMEvent const & l) { - assert (l->type == Locate); + assert (l.type == Locate); DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::interrupt\n"); /* maintain original "with-roll" choice of initial locate, even though * we are interrupting the locate to start a new one. */ - api->locate (l->target, _last_locate.with_roll, l->with_flush, l->with_loop, l->force); + api->locate (l.target, _last_locate.with_roll, l.with_flush, l.with_loop, l.force); } void @@ -376,9 +376,9 @@ TransportFSM::roll_after_locate () } void -TransportFSM::defer (FSMEvent* ev) +TransportFSM::defer (FSMEvent& ev) { - DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("Defer %1 during %2\n", enum_2_string (ev->type), current_state())); + DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("Defer %1 during %2\n", enum_2_string (ev.type), current_state())); deferred_events.push_back (ev); }