From b6aefaf100cfaaf15297a8921cca51a575c5e78e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 24 Sep 2018 17:34:25 -0400 Subject: initial hacks towards a truly thread-safe SafeTime object, using boost::atomic --- libs/ardour/ardour/transport_master.h | 34 ++++++++++++++++++++++++++++++---- libs/ardour/mtc_slave.cc | 32 ++++++-------------------------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/libs/ardour/ardour/transport_master.h b/libs/ardour/ardour/transport_master.h index b41d107015..da30abfae9 100644 --- a/libs/ardour/ardour/transport_master.h +++ b/libs/ardour/ardour/transport_master.h @@ -23,6 +23,7 @@ #include #include +#include #include @@ -282,18 +283,43 @@ class LIBARDOUR_API TransportMaster : public PBD::Stateful { }; struct LIBARDOUR_API SafeTime { - volatile int guard1; + boost::atomic guard1; samplepos_t position; samplepos_t timestamp; double speed; - volatile int guard2; + boost::atomic guard2; SafeTime() { - guard1 = 0; + guard1.store (0); position = 0; timestamp = 0; speed = 0; - guard2 = 0; + guard2.store (0); + } + + SafeTime (SafeTime const & other) + : guard1 (other.guard1.load (boost::memory_order_acquire)) + , position (other.position) + , timestamp (other.timestamp) + , speed (other.speed) + , guard2 (other.guard2.load (boost::memory_order_acquire)) + {} + + SafeTime& operator= (SafeTime const & other) { + guard1 = other.guard1.load (boost::memory_order_acquire); + position = other.position; + timestamp = other.timestamp; + speed = other.speed; + guard2 = other.guard2.load (boost::memory_order_acquire); + return *this; + } + + void update (samplepos_t p, samplepos_t t, double s) { + guard1.fetch_add (1, boost::memory_order_acquire); + position = p; + timestamp = t; + speed = s; + guard2.fetch_add (1, boost::memory_order_acquire); } }; diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index a2b73ba2f4..7a6d6a6ed6 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -273,7 +273,7 @@ MTC_TransportMaster::read_current (SafeTime *st) const *st = current; tries++; - } while (st->guard1 != st->guard2); + } while (st->guard1.load (boost::memory_order_acquire) != st->guard2.load (boost::memory_order_acquire)); } void @@ -312,11 +312,7 @@ MTC_TransportMaster::update_mtc_qtr (Parser& p, int which_qtr, samplepos_t now) mtc_speed = (t1 - t0) / qtr_d; DEBUG_TRACE (DEBUG::MTC, string_compose ("qtr sample DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", t0, t1, e, mtc_speed, e2 - qtr_d)); - current.guard1++; - current.position = mtc_frame; - current.timestamp = now; - current.speed = mtc_speed; - current.guard2++; + current.update (mtc_frame, now, mtc_speed); last_inbound_frame = now; } @@ -499,10 +495,7 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp init_mtc_dll(mtc_frame, qtr); mtc_frame_dll = mtc_frame; } - current.guard1++; - current.position = mtc_frame; - current.timestamp = now; - current.guard2++; + current.update (mtc_frame, now, current.speed); reset_window (mtc_frame); } } @@ -525,28 +518,15 @@ MTC_TransportMaster::update_mtc_status (MIDI::MTC_Status status) switch (status) { case MTC_Stopped: - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.speed = 0; - current.guard2++; - + current.update (mtc_frame, 0, 0); break; case MTC_Forward: - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.speed = 0; - current.guard2++; + current.update (mtc_frame, 0, 0); break; case MTC_Backward: - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.speed = 0; - current.guard2++; + current.update (mtc_frame, 0, 0); break; } busy_guard2++; -- cgit v1.2.3