From 168ab7279cec925e3db3e943e35d0d2bd220d8b3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 16 Jun 2010 18:40:44 -0700 Subject: uhd: work on thread priority scheduling --- host/lib/thread_priority.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 host/lib/thread_priority.cpp (limited to 'host/lib/thread_priority.cpp') diff --git a/host/lib/thread_priority.cpp b/host/lib/thread_priority.cpp new file mode 100644 index 000000000..ff3c1528b --- /dev/null +++ b/host/lib/thread_priority.cpp @@ -0,0 +1,93 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include +#include + +bool uhd::set_thread_priority_safe(float priority, bool realtime){ + try{ + set_thread_priority(priority, realtime); + return true; + }catch(const std::exception &e){ + std::cerr << "set_thread_priority: " << e.what() << std::endl; + return false; + } +} + +static void check_priority_range(float priority){ + if (priority > +1.0 or priority < -1.0) + throw std::range_error("priority out of range [-1.0, +1.0]"); +} + +/*********************************************************************** + * Pthread API to set priority + **********************************************************************/ +#if defined(HAVE_PTHREAD_SETSCHEDPARAM) + #include + + void uhd::set_thread_priority(float priority, bool realtime){ + check_priority_range(priority); + + //when realtime is not enabled, use sched other + int policy = (realtime)? SCHED_RR : SCHED_OTHER; + + //we cannot have below normal priority, set to zero and use other policy + if (priority < 0){ + priority = 0; + policy = SCHED_OTHER; + } + + //get the priority bounds for the selected policy + int min_pri = sched_get_priority_min(policy); + int max_pri = sched_get_priority_max(policy); + if (min_pri == -1 or max_pri == -1) throw std::runtime_error("error in sched_get_priority_min/max"); + + //set the new priority and policy + sched_param sp; + sp.sched_priority = int(priority*(max_pri - min_pri)) + min_pri; + int ret = pthread_setschedparam(pthread_self(), policy, &sp); + if (ret == -1) throw std::runtime_error("error in pthread_setschedparam"); + } + +/*********************************************************************** + * Windows API to set priority + **********************************************************************/ +#elif defined(HAVE_WIN_SETTHREADPRIORITY) + #include + + void uhd::set_thread_priority(float priority, bool realtime){ + //set the priority class on the process + int pri_class = (realtime)? REALTIME_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; + if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0) + throw std::runtime_error("error in SetPriorityClass"); + + //set the thread priority on the thread + int pri_int = int(pri*(THREAD_PRIORITY_TIME_CRITICAL - THREAD_PRIORITY_IDLE)) + THREAD_PRIORITY_IDLE; + if (SetThreadPriority(GetCurrentThread(), pri_int) == 0) + throw std::runtime_error("error in SetThreadPriority"); + } + +/*********************************************************************** + * Unimplemented API to set priority + **********************************************************************/ +#else + void uhd::set_thread_priority(float, bool){ + throw std::runtime_error("set thread priority not implemented"); + } + +#endif /* HAVE_PTHREAD_SETSCHEDPARAM */ -- cgit v1.2.3 From 339aa3ccd4a50de5e259078635ddbcd552fff22f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 16 Jun 2010 19:18:06 -0700 Subject: uhd: working windows implementation of thread priority setting, added called to example apps --- host/examples/rx_timed_samples.cpp | 3 +++ host/examples/tx_timed_samples.cpp | 3 +++ host/lib/thread_priority.cpp | 10 ++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'host/lib/thread_priority.cpp') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 64da260d5..6920b34d1 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -25,6 +26,8 @@ namespace po = boost::program_options; int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + //variables to be set by po std::string args; int seconds_in_future; diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index e9e0c785e..28fd2ee67 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -25,6 +26,8 @@ namespace po = boost::program_options; int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + //variables to be set by po std::string args; int seconds_in_future; diff --git a/host/lib/thread_priority.cpp b/host/lib/thread_priority.cpp index ff3c1528b..afaa5e36e 100644 --- a/host/lib/thread_priority.cpp +++ b/host/lib/thread_priority.cpp @@ -76,9 +76,15 @@ static void check_priority_range(float priority){ if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0) throw std::runtime_error("error in SetPriorityClass"); + //scale the priority value to the constants + int priorities[] = { + THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, + THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL + }; + size_t pri_index = size_t((priority+1.0)*6/2.0); // -1 -> 0, +1 -> 6 + //set the thread priority on the thread - int pri_int = int(pri*(THREAD_PRIORITY_TIME_CRITICAL - THREAD_PRIORITY_IDLE)) + THREAD_PRIORITY_IDLE; - if (SetThreadPriority(GetCurrentThread(), pri_int) == 0) + if (SetThreadPriority(GetCurrentThread(), priorities[pri_index]) == 0) throw std::runtime_error("error in SetThreadPriority"); } -- cgit v1.2.3 From 1db016bc6503cdca76025f131773e550bd895d48 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 17 Jun 2010 11:32:46 -0700 Subject: uhd: check priority range --- host/lib/thread_priority.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'host/lib/thread_priority.cpp') diff --git a/host/lib/thread_priority.cpp b/host/lib/thread_priority.cpp index afaa5e36e..30b184123 100644 --- a/host/lib/thread_priority.cpp +++ b/host/lib/thread_priority.cpp @@ -46,11 +46,8 @@ static void check_priority_range(float priority){ //when realtime is not enabled, use sched other int policy = (realtime)? SCHED_RR : SCHED_OTHER; - //we cannot have below normal priority, set to zero and use other policy - if (priority < 0){ - priority = 0; - policy = SCHED_OTHER; - } + //we cannot have below normal priority, set to zero + if (priority < 0) priority = 0; //get the priority bounds for the selected policy int min_pri = sched_get_priority_min(policy); @@ -71,6 +68,8 @@ static void check_priority_range(float priority){ #include void uhd::set_thread_priority(float priority, bool realtime){ + check_priority_range(priority); + //set the priority class on the process int pri_class = (realtime)? REALTIME_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0) -- cgit v1.2.3 From 1c1d967ec73906d50ee6e7257a4153db4ab9c507 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 18 Jun 2010 17:59:57 -0700 Subject: usrp2: init clock rate shadows for dboard iface, uhd: pthread sched fix error condition check --- host/lib/thread_priority.cpp | 2 +- host/lib/usrp/usrp2/clock_ctrl.cpp | 2 -- host/lib/usrp/usrp2/dboard_iface.cpp | 5 +++++ 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'host/lib/thread_priority.cpp') diff --git a/host/lib/thread_priority.cpp b/host/lib/thread_priority.cpp index 30b184123..c35e5fcb1 100644 --- a/host/lib/thread_priority.cpp +++ b/host/lib/thread_priority.cpp @@ -58,7 +58,7 @@ static void check_priority_range(float priority){ sched_param sp; sp.sched_priority = int(priority*(max_pri - min_pri)) + min_pri; int ret = pthread_setschedparam(pthread_self(), policy, &sp); - if (ret == -1) throw std::runtime_error("error in pthread_setschedparam"); + if (ret != 0) throw std::runtime_error("error in pthread_setschedparam"); } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 59fac6fcf..b9be037c0 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -61,9 +61,7 @@ public: this->enable_external_ref(false); this->enable_rx_dboard_clock(false); - this->set_rate_rx_dboard_clock(get_rates_rx_dboard_clock().at(0)); this->enable_tx_dboard_clock(false); - this->set_rate_tx_dboard_clock(get_rates_tx_dboard_clock().at(0)); /* private clock enables, must be set here */ this->enable_dac_clock(true); diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index ec6c98186..6f2fb9396 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include //htonl and ntohl #include @@ -109,6 +110,10 @@ usrp2_dboard_iface::usrp2_dboard_iface( _dac_regs[unit].cmd = ad5623_regs_t::CMD_RESET; this->_write_aux_dac(unit); } + + //init the clock rate shadows with max rate clock + this->set_clock_rate(UNIT_RX, sorted(this->get_clock_rates(UNIT_RX)).back()); + this->set_clock_rate(UNIT_TX, sorted(this->get_clock_rates(UNIT_TX)).back()); } usrp2_dboard_iface::~usrp2_dboard_iface(void){ -- cgit v1.2.3