diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-01-17 11:30:17 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-01-17 11:30:44 +0100 |
commit | 7ca7edbc5a80b3869fb0772946c00c76c264da8d (patch) | |
tree | f9b8fabd56fe422d637475b882e50982027d524d | |
parent | 4f7636694a752fa8c652c684a3c9ebf1488ceaa4 (diff) | |
download | dabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.tar.gz dabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.tar.bz2 dabmod-7ca7edbc5a80b3869fb0772946c00c76c264da8d.zip |
Don't use CLOCK_GETTIME in SDR
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | src/Utils.cpp | 16 | ||||
-rw-r--r-- | src/Utils.h | 22 | ||||
-rw-r--r-- | src/output/SDR.cpp | 43 | ||||
-rw-r--r-- | src/output/SDR.h | 8 | ||||
-rw-r--r-- | src/output/USRPTime.cpp | 2 |
6 files changed, 30 insertions, 65 deletions
@@ -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 |