initial hacks towards a truly thread-safe SafeTime object, using boost::atomic
This commit is contained in:
parent
3c11660d2a
commit
b6aefaf100
@ -23,6 +23,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/atomic.hpp>
|
||||||
|
|
||||||
#include <glibmm/threads.h>
|
#include <glibmm/threads.h>
|
||||||
|
|
||||||
@ -282,18 +283,43 @@ class LIBARDOUR_API TransportMaster : public PBD::Stateful {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct LIBARDOUR_API SafeTime {
|
struct LIBARDOUR_API SafeTime {
|
||||||
volatile int guard1;
|
boost::atomic<int> guard1;
|
||||||
samplepos_t position;
|
samplepos_t position;
|
||||||
samplepos_t timestamp;
|
samplepos_t timestamp;
|
||||||
double speed;
|
double speed;
|
||||||
volatile int guard2;
|
boost::atomic<int> guard2;
|
||||||
|
|
||||||
SafeTime() {
|
SafeTime() {
|
||||||
guard1 = 0;
|
guard1.store (0);
|
||||||
position = 0;
|
position = 0;
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
speed = 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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ MTC_TransportMaster::read_current (SafeTime *st) const
|
|||||||
*st = current;
|
*st = current;
|
||||||
tries++;
|
tries++;
|
||||||
|
|
||||||
} while (st->guard1 != st->guard2);
|
} while (st->guard1.load (boost::memory_order_acquire) != st->guard2.load (boost::memory_order_acquire));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -312,11 +312,7 @@ MTC_TransportMaster::update_mtc_qtr (Parser& p, int which_qtr, samplepos_t now)
|
|||||||
mtc_speed = (t1 - t0) / qtr_d;
|
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));
|
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.update (mtc_frame, now, mtc_speed);
|
||||||
current.position = mtc_frame;
|
|
||||||
current.timestamp = now;
|
|
||||||
current.speed = mtc_speed;
|
|
||||||
current.guard2++;
|
|
||||||
|
|
||||||
last_inbound_frame = now;
|
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);
|
init_mtc_dll(mtc_frame, qtr);
|
||||||
mtc_frame_dll = mtc_frame;
|
mtc_frame_dll = mtc_frame;
|
||||||
}
|
}
|
||||||
current.guard1++;
|
current.update (mtc_frame, now, current.speed);
|
||||||
current.position = mtc_frame;
|
|
||||||
current.timestamp = now;
|
|
||||||
current.guard2++;
|
|
||||||
reset_window (mtc_frame);
|
reset_window (mtc_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,28 +518,15 @@ MTC_TransportMaster::update_mtc_status (MIDI::MTC_Status status)
|
|||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case MTC_Stopped:
|
case MTC_Stopped:
|
||||||
current.guard1++;
|
current.update (mtc_frame, 0, 0);
|
||||||
current.position = mtc_frame;
|
|
||||||
current.timestamp = 0;
|
|
||||||
current.speed = 0;
|
|
||||||
current.guard2++;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MTC_Forward:
|
case MTC_Forward:
|
||||||
current.guard1++;
|
current.update (mtc_frame, 0, 0);
|
||||||
current.position = mtc_frame;
|
|
||||||
current.timestamp = 0;
|
|
||||||
current.speed = 0;
|
|
||||||
current.guard2++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MTC_Backward:
|
case MTC_Backward:
|
||||||
current.guard1++;
|
current.update (mtc_frame, 0, 0);
|
||||||
current.position = mtc_frame;
|
|
||||||
current.timestamp = 0;
|
|
||||||
current.speed = 0;
|
|
||||||
current.guard2++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
busy_guard2++;
|
busy_guard2++;
|
||||||
|
Loading…
Reference in New Issue
Block a user