aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-01-17 11:30:17 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-01-17 11:30:44 +0100
commit7ca7edbc5a80b3869fb0772946c00c76c264da8d (patch)
treef9b8fabd56fe422d637475b882e50982027d524d
parent4f7636694a752fa8c652c684a3c9ebf1488ceaa4 (diff)
downloaddabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.tar.gz
dabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.tar.bz2
dabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.zip
Don't use CLOCK_GETTIME in SDR
-rw-r--r--TODO4
-rw-r--r--src/Utils.cpp16
-rw-r--r--src/Utils.h22
-rw-r--r--src/output/SDR.cpp43
-rw-r--r--src/output/SDR.h8
-rw-r--r--src/output/USRPTime.cpp2
6 files changed, 30 insertions, 65 deletions
diff --git a/TODO b/TODO
index 8f49571..ac0a877 100644
--- a/TODO
+++ b/TODO
@@ -18,7 +18,7 @@ https://discourse.myriadrf.org/t/synchronize-two-limesdr/1714
DPD will be possible too.
-Move dpd port from uhd section to somewhere else.
+Test sleep_through_frame implementation.
Clean up and separate GPS and refclk checks.
* *done* handle UHD GPSDO and time
@@ -31,7 +31,7 @@ Add antenna selection to config.
Test RC entries.
-Portability: replace clock_gettime with std::chrono
+*done* Portability: replace clock_gettime with std::chrono
*done* Make an abstraction for the DPD feedback server, use it for Soapy and UHD.
diff --git a/src/Utils.cpp b/src/Utils.cpp
index f113be3..b4816d3 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2017
+ Copyright (C) 2018
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -215,16 +215,16 @@ double parseChannel(const std::string& chan)
return freq;
}
-int transmission_frame_duration_ms(unsigned int dabMode)
+std::chrono::milliseconds transmission_frame_duration(unsigned int dabmode)
{
- switch (dabMode) {
- case 1: return 96;
- case 2: return 24;
- case 3: return 24;
- case 4: return 48;
+ using namespace std::chrono;
+ switch (dabmode) {
+ case 1: return milliseconds(96);
+ case 2: return milliseconds(24);
+ case 3: return milliseconds(24);
+ case 4: return milliseconds(48);
default:
throw std::runtime_error("invalid DAB mode");
}
}
-
diff --git a/src/Utils.h b/src/Utils.h
index 5d5831b..9e88488 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2017
+ Copyright (C) 2018
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <time.h>
#include <string>
+#include <chrono>
void printUsage(const char* progName);
@@ -43,22 +44,6 @@ void printVersion(void);
void printStartupInfo(void);
-inline long timespecdiff_us(struct timespec& oldTime, struct timespec& time)
-{
- long tv_sec;
- long tv_nsec;
- if (time.tv_nsec < oldTime.tv_nsec) {
- tv_sec = time.tv_sec - 1 - oldTime.tv_sec;
- tv_nsec = 1000000000L + time.tv_nsec - oldTime.tv_nsec;
- }
- else {
- tv_sec = time.tv_sec - oldTime.tv_sec;
- tv_nsec = time.tv_nsec - oldTime.tv_nsec;
- }
-
- return tv_sec * 1000 + tv_nsec / 1000;
-}
-
// Set SCHED_RR with priority prio (0=lowest)
int set_realtime_prio(int prio);
@@ -70,5 +55,4 @@ double parseChannel(const std::string& chan);
// dabMode is either 1, 2, 3, 4, corresponding to TM I, TM II, TM III and TM IV.
// throws a runtime_error if dabMode is not one of these values.
-int transmission_frame_duration_ms(unsigned int dabMode);
-
+std::chrono::milliseconds transmission_frame_duration(unsigned int dabmode);
diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp
index e478de5..8906ef6 100644
--- a/src/output/SDR.cpp
+++ b/src/output/SDR.cpp
@@ -59,15 +59,11 @@ static constexpr double TIMESTAMP_MARGIN_FUTURE = 0.5;
SDR::SDR(SDRDeviceConfig& config, std::shared_ptr<SDRDevice> device) :
ModOutput(), ModMetadata(), RemoteControllable("sdr"),
m_config(config),
- m_running(false),
m_device(device)
{
// muting is remote-controllable
m_config.muting = false;
- time_last_frame.tv_sec = 0;
- time_last_frame.tv_nsec = 0;
-
m_device_thread = std::thread(&SDR::process_thread_entry, this);
m_dpd_feedback_server = make_shared<DPDFeedbackServer>(
@@ -78,15 +74,10 @@ SDR::SDR(SDRDeviceConfig& config, std::shared_ptr<SDRDevice> device) :
SDR::~SDR()
{
- stop();
-}
-
-void SDR::stop()
-{
m_running.store(false);
FrameData end_marker;
- end_marker.buf.resize(0);
+ end_marker.buf.clear();
m_queue.push(end_marker);
if (m_device_thread.joinable()) {
@@ -218,33 +209,23 @@ const char* SDR::name()
void SDR::sleep_through_frame()
{
- struct timespec now;
- if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
- stringstream ss;
- ss << "clock_gettime failure: " << strerror(errno);
- throw runtime_error(ss.str());
- }
+ using namespace std::chrono;
- if (time_last_frame.tv_sec == 0) {
- if (clock_gettime(CLOCK_MONOTONIC, &time_last_frame) != 0) {
- stringstream ss;
- ss << "clock_gettime failure: " << strerror(errno);
- throw runtime_error(ss.str());
- }
+ const auto now = steady_clock::now();
+
+ if (not t_last_frame_initialised) {
+ t_last_frame = now;
+ t_last_frame_initialised = true;
}
- long delta_us = timespecdiff_us(time_last_frame, now);
- long wait_time_us = transmission_frame_duration_ms(m_config.dabMode);
+ const auto delta = now - t_last_frame;
+ const auto wait_time = transmission_frame_duration(m_config.dabMode);
- if (wait_time_us - delta_us > 0) {
- usleep(wait_time_us - delta_us);
+ if (wait_time > delta) {
+ this_thread::sleep_for(wait_time - delta);
}
- time_last_frame.tv_nsec += wait_time_us * 1000;
- while (time_last_frame.tv_nsec >= 1000000000L) {
- time_last_frame.tv_nsec -= 1000000000L;
- time_last_frame.tv_sec++;
- }
+ t_last_frame += wait_time;
}
void SDR::handle_frame(struct FrameData& frame)
diff --git a/src/output/SDR.h b/src/output/SDR.h
index 4c7de5a..a55f7c0 100644
--- a/src/output/SDR.h
+++ b/src/output/SDR.h
@@ -34,6 +34,7 @@ DESCRIPTION:
# include <config.h>
#endif
+#include <chrono>
#include "ModPlugin.h"
#include "EtiReader.h"
#include "output/SDRDevice.h"
@@ -66,14 +67,13 @@ class SDR : public ModOutput, public ModMetadata, public RemoteControllable {
const std::string& parameter) const override;
private:
- void stop(void);
void process_thread_entry(void);
void handle_frame(struct FrameData &frame);
void sleep_through_frame(void);
SDRDeviceConfig& m_config;
- std::atomic<bool> m_running;
+ std::atomic<bool> m_running = ATOMIC_VAR_INIT(false);
std::thread m_device_thread;
std::vector<uint8_t> m_frame;
ThreadsafeQueue<FrameData> m_queue;
@@ -87,8 +87,8 @@ class SDR : public ModOutput, public ModMetadata, public RemoteControllable {
uint32_t last_tx_second = 0;
uint32_t last_tx_pps = 0;
- struct timespec time_last_frame;
-
+ bool t_last_frame_initialised = false;
+ std::chrono::steady_clock::time_point t_last_frame;
};
}
diff --git a/src/output/USRPTime.cpp b/src/output/USRPTime.cpp
index dcedeab..9ed398e 100644
--- a/src/output/USRPTime.cpp
+++ b/src/output/USRPTime.cpp
@@ -2,7 +2,7 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Her Majesty the
Queen in Right of Canada (Communications Research Center Canada)
- Copyright (C) 2017
+ Copyright (C) 2018
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org