summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac27
-rw-r--r--src/OutputUHD.cpp133
-rw-r--r--src/OutputUHD.h6
-rw-r--r--src/Utils.cpp72
4 files changed, 124 insertions, 114 deletions
diff --git a/configure.ac b/configure.ac
index cd6f0ed..acefa90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -161,31 +161,22 @@ AC_COMPILE_IFELSE(
AC_LANG_POP([C++])
-# Check for SSE
-AC_MSG_CHECKING(for SSE in current arch/CFLAGS)
+# Check for march
+AC_MSG_CHECKING(if we can add -march=native to CFLAGS)
save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS -msse"
-AC_MSG_CHECKING([whether we need to add -msse])
+CXXFLAGS="$CXXFLAGS -march=native"
AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[
-#include <xmmintrin.h>
-__m128 testfunc(float *a, float *b) {
- return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b));
-}
+void testfunc(void) {}
]])],
-[has_sse=yes],
-[has_sse=no]
+[supports_march_native=yes],
+[supports_march_native=no]
)
-AC_MSG_RESULT($has_sse)
-if test x"$has_sse" = xno; then
+AC_MSG_RESULT($supports_march_native)
+if test x"$supports_march_native" = xno; then
CXXFLAGS="$save_CXXFLAGS"
fi
-
-AM_CONDITIONAL([HAVE_SSE], [test "x$has_sse" = "xyes"])
-
-# TODO: Check for NEON
-
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([bzero floor ftime gettimeofday memset sqrt strchr strerror strtol])
@@ -211,7 +202,7 @@ echo
echo
enabled=""
disabled=""
-for feat in with_debug_malloc has_sse enable_fast_math
+for feat in with_debug_malloc supports_march_native enable_fast_math
do
eval var=\$$feat
AS_IF([test "x$var" != "xno"],
diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp
index e4b57bc..d78c4bf 100644
--- a/src/OutputUHD.cpp
+++ b/src/OutputUHD.cpp
@@ -56,8 +56,12 @@ typedef std::complex<float> complexf;
std::string stringtrim(const std::string &s)
{
- auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c){return std::isspace(c);} );
- return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), [](int c){return std::isspace(c);} ).base());
+ auto wsfront = std::find_if_not(s.begin(), s.end(),
+ [](int c){ return std::isspace(c);} );
+ return std::string(wsfront,
+ std::find_if_not(s.rbegin(),
+ std::string::const_reverse_iterator(wsfront),
+ [](int c){ return std::isspace(c);} ).base());
}
void uhd_msg_handler(uhd::msg::type_t type, const std::string &msg)
@@ -639,16 +643,29 @@ void UHDWorker::process()
num_underflows = 0;
num_late_packets = 0;
+ int last_num_underflows = 0;
+ size_t pop_prebuffering = FRAMES_MAX_SIZE;
+
while (uwd->running) {
md.has_time_spec = false;
md.time_spec = uhd::time_spec_t(0.0);
struct UHDWorkerFrameData frame;
etiLog.log(trace, "UHD,wait");
- uwd->frames.wait_and_pop(frame);
+ uwd->frames.wait_and_pop(frame, pop_prebuffering);
etiLog.log(trace, "UHD,pop");
handle_frame(&frame);
+
+ /* Ensure we fill uwd->frames after every underrun and
+ * at startup to reduce underrun likelihood. */
+ if (last_num_underflows < num_underflows) {
+ pop_prebuffering = FRAMES_MAX_SIZE;
+ }
+ else {
+ pop_prebuffering = 1;
+ }
+ last_num_underflows = num_underflows;
}
}
@@ -780,21 +797,6 @@ void UHDWorker::handle_frame(const struct UHDWorkerFrameData *frame)
}
tx_frame(frame, timestamp_discontinuity);
-
- auto time_now = std::chrono::steady_clock::now();
- if (last_print_time + std::chrono::seconds(1) < time_now) {
- if (num_underflows or num_late_packets) {
- etiLog.log(info,
- "OutputUHD status (usrp time: %f): "
- "%d underruns and %d late packets since last status.\n",
- usrp_time,
- num_underflows, num_late_packets);
- }
- num_underflows = 0;
- num_late_packets = 0;
-
- last_print_time = time_now;
- }
}
void UHDWorker::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update)
@@ -834,51 +836,70 @@ void UHDWorker::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update)
"UHDWorker::process() unable to write to device, skipping frame!\n");
break;
}
-
- print_async_metadata(frame);
}
}
-void UHDWorker::print_async_metadata(const struct UHDWorkerFrameData *frame)
+void UHDWorker::print_async_metadata()
{
- uhd::async_metadata_t async_md;
- if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 0)) {
- const char* uhd_async_message = "";
- bool failure = false;
- switch (async_md.event_code) {
- case uhd::async_metadata_t::EVENT_CODE_BURST_ACK:
- break;
- case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
- uhd_async_message = "Underflow";
- num_underflows++;
- break;
- case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR:
- uhd_async_message = "Packet loss between host and device.";
- failure = true;
- break;
- case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR:
- uhd_async_message = "Packet had time that was late.";
- num_late_packets++;
- break;
- case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET:
- uhd_async_message = "Underflow occurred inside a packet.";
- failure = true;
- break;
- case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST:
- uhd_async_message = "Packet loss within a burst.";
- failure = true;
- break;
- default:
- uhd_async_message = "unknown event code";
- failure = true;
- break;
+ while (uwd->running) {
+ uhd::async_metadata_t async_md;
+ if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 1)) {
+ const char* uhd_async_message = "";
+ bool failure = false;
+ switch (async_md.event_code) {
+ case uhd::async_metadata_t::EVENT_CODE_BURST_ACK:
+ break;
+ case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
+ uhd_async_message = "Underflow";
+ num_underflows++;
+ break;
+ case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR:
+ uhd_async_message = "Packet loss between host and device.";
+ failure = true;
+ break;
+ case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR:
+ uhd_async_message = "Packet had time that was late.";
+ num_late_packets++;
+ break;
+ case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET:
+ uhd_async_message = "Underflow occurred inside a packet.";
+ failure = true;
+ break;
+ case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST:
+ uhd_async_message = "Packet loss within a burst.";
+ failure = true;
+ break;
+ default:
+ uhd_async_message = "unknown event code";
+ failure = true;
+ break;
+ }
+
+ if (failure) {
+ etiLog.level(alert) <<
+ "Received Async UHD Message '" <<
+ uhd_async_message << "' at time " <<
+ md.time_spec.get_real_secs();
+
+ }
}
- if (failure) {
- etiLog.level(alert) << "Near frame " <<
- frame->ts.fct << ": Received Async UHD Message '" <<
- uhd_async_message << "'";
+ auto time_now = std::chrono::steady_clock::now();
+ if (last_print_time + std::chrono::seconds(1) < time_now) {
+ const double usrp_time =
+ uwd->myUsrp->get_time_now().get_real_secs();
+
+ if (num_underflows or num_late_packets) {
+ etiLog.log(info,
+ "OutputUHD status (usrp time: %f): "
+ "%d underruns and %d late packets since last status.\n",
+ usrp_time,
+ num_underflows, num_late_packets);
+ }
+ num_underflows = 0;
+ num_late_packets = 0;
+ last_print_time = time_now;
}
}
}
diff --git a/src/OutputUHD.h b/src/OutputUHD.h
index cbf159f..d42245f 100644
--- a/src/OutputUHD.h
+++ b/src/OutputUHD.h
@@ -125,6 +125,8 @@ class UHDWorker {
void start(struct UHDWorkerData *uhdworkerdata) {
uwd->running = true;
uhd_thread = boost::thread(&UHDWorker::process_errhandler, this);
+ async_rx_thread = boost::thread(
+ &UHDWorker::print_async_metadata, this);
}
void stop() {
@@ -133,6 +135,7 @@ class UHDWorker {
}
uhd_thread.interrupt();
uhd_thread.join();
+ async_rx_thread.join();
}
~UHDWorker() {
@@ -155,13 +158,14 @@ class UHDWorker {
// Used to print statistics once a second
std::chrono::steady_clock::time_point last_print_time;
- void print_async_metadata(const struct UHDWorkerFrameData *frame);
+ void print_async_metadata(void);
void handle_frame(const struct UHDWorkerFrameData *frame);
void tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update);
struct UHDWorkerData *uwd;
boost::thread uhd_thread;
+ boost::thread async_rx_thread;
uhd::tx_streamer::sptr myTxStream;
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 5bd93d9..cd116c7 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -30,18 +30,40 @@
#include <sys/prctl.h>
#include <pthread.h>
-void printUsage(const char* progName)
+static void printHeader()
{
- FILE* out = stderr;
-
- fprintf(out, "Welcome to %s %s, compiled at %s, %s\n\n",
- PACKAGE,
+ std::cerr << "ODR-DabMod version " <<
#if defined(GITVERSION)
- GITVERSION,
+ GITVERSION
#else
- VERSION,
+ VERSION
+#endif
+ ", compiled at " << __DATE__ << ", " << __TIME__ << std::endl;
+
+ std::cerr << "Compiled with features: " <<
+#if defined(HAVE_ZEROMQ)
+ "zeromq " <<
+#endif
+#if defined(HAVE_OUTPUT_UHD)
+ "output_uhd " <<
#endif
- __DATE__, __TIME__);
+#if defined(HAVE_SOAPYSDR)
+ "output_soapysdr " <<
+#endif
+#if defined(__FAST_MATH__)
+ "fast-math " <<
+#endif
+#if defined(__SSE__)
+ "SSE " <<
+#endif
+ "\n";
+}
+
+void printUsage(const char* progName)
+{
+ printHeader();
+
+ FILE* out = stderr;
fprintf(out, "Usage with configuration file:\n");
fprintf(out, "\t%s [-C] config_file.ini\n\n", progName);
@@ -87,16 +109,9 @@ void printUsage(const char* progName)
void printVersion(void)
{
- FILE *out = stderr;
+ printHeader();
- fprintf(out, "%s %s, compiled at %s, %s\n\n",
- PACKAGE,
-#if defined(GITVERSION)
- GITVERSION
-#else
- VERSION
-#endif
- ,__DATE__, __TIME__);
+ FILE *out = stderr;
fprintf(out,
" ODR-DabMod is copyright (C) Her Majesty the Queen in Right of Canada,\n"
" 2005 -- 2012 Communications Research Centre (CRC),\n"
@@ -123,28 +138,7 @@ void printVersion(void)
void printStartupInfo()
{
- std::cerr << "ODR-DabMod version " <<
-#if defined(GITVERSION)
- GITVERSION
-#else
- VERSION
-#endif
- << std::endl;
-
- std::cerr << "Compiled with features: " <<
-#if defined(HAVE_ZEROMQ)
- "zeromq " <<
-#endif
-#if defined(HAVE_OUTPUT_UHD)
- "output_uhd " <<
-#endif
-#if defined(HAVE_SOAPYSDR)
- "output_soapysdr " <<
-#endif
-#if defined(__FAST_MATH__)
- "fast-math" <<
-#endif
- "\n";
+ printHeader();
etiLog.level(info) << "Starting up version " <<
#if defined(GITVERSION)