Hoernchen has submitted this change. ( https://gerrit.osmocom.org/c/osmo-trx/+/32943 )
Change subject: ms: prettify scheduling + add odroid ......................................................................
ms: prettify scheduling + add odroid
Change-Id: Icaf42fd5f76dc2d53dc526558aa8ceaa9c190f7b --- M Transceiver52M/ms/ms.cpp M Transceiver52M/ms/ms.h M Transceiver52M/ms/ms_rx_lower.cpp M Transceiver52M/ms/ms_upper.cpp 4 files changed, 70 insertions(+), 15 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve Hoernchen: Looks good to me, approved
diff --git a/Transceiver52M/ms/ms.cpp b/Transceiver52M/ms/ms.cpp index d191ed5..1dc2587 100644 --- a/Transceiver52M/ms/ms.cpp +++ b/Transceiver52M/ms/ms.cpp @@ -278,12 +278,13 @@ { auto fn = get_rx_burst_handler_fn(rx_bh()); rx_task = std::thread(fn); - set_name_aff_sched(rx_task.native_handle(), "rxrun", 2, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 2); + set_name_aff_sched(rx_task.native_handle(), sched_params::thread_names::RXRUN);
usleep(1000); auto fn2 = get_tx_burst_handler_fn(tx_bh()); tx_task = std::thread(fn2); - set_name_aff_sched(tx_task.native_handle(), "txrun", 2, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 1); + set_name_aff_sched(tx_task.native_handle(), sched_params::thread_names::TXRUN); + }
void ms_trx::set_upper_ready(bool is_ready) diff --git a/Transceiver52M/ms/ms.h b/Transceiver52M/ms/ms.h index 8ea9932..dbf2e9a 100644 --- a/Transceiver52M/ms/ms.h +++ b/Transceiver52M/ms/ms.h @@ -200,6 +200,40 @@ } };
+static struct sched_params { + enum thread_names { U_CTL = 0, U_RX, U_TX, SCH_SEARCH, MAIN, LEAKCHECK, RXRUN, TXRUN, _THRD_NAME_COUNT }; + enum target { ODROID = 0, PI4 }; + const char *name; + int core; + int schedtype; + int prio; +} schdp[][sched_params::_THRD_NAME_COUNT]{ + { + { "upper_ctrl", 2, SCHED_RR, sched_get_priority_max(SCHED_RR) }, + { "upper_rx", 2, SCHED_RR, sched_get_priority_max(SCHED_RR) - 5 }, + { "upper_tx", 2, SCHED_RR, sched_get_priority_max(SCHED_RR) - 1 }, + + { "sch_search", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5 }, + { "main", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5 }, + { "leakcheck", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 10 }, + + { "rxrun", 4, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 2 }, + { "txrun", 5, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 1 }, + }, + { + { "upper_ctrl", 1, SCHED_RR, sched_get_priority_max(SCHED_RR) }, + { "upper_rx", 1, SCHED_RR, sched_get_priority_max(SCHED_RR) - 5 }, + { "upper_tx", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 1 }, + + { "sch_search", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5 }, + { "main", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5 }, + { "leakcheck", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 10 }, + + { "rxrun", 2, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 2 }, + { "txrun", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 1 }, + }, +}; + using ts_hitter_q_t = spsc_cond<64, GSM::Time, true, false>;
struct ms_trx : public BASET { @@ -230,6 +264,8 @@ int64_t first_sch_ts_start = -1;
time_keeper timekeeper; + int hw_cpus; + sched_params::target hw_target;
void start(); std::atomic<bool> upper_is_ready; @@ -250,8 +286,11 @@
ms_trx() : timing_advance(0), do_auto_gain(false), rxqueue(), first_sch_buf(new blade_sample_type[SCH_LEN_SPS]), - burst_copy_buffer(new blade_sample_type[ONE_TS_BURST_LEN]), rcv_done{ false }, sch_thread_done{ false } + burst_copy_buffer(new blade_sample_type[ONE_TS_BURST_LEN]), rcv_done{ false }, + sch_thread_done{ false }, hw_cpus(std::thread::hardware_concurrency()), + hw_target(hw_cpus > 4 ? sched_params::target::ODROID : sched_params::target::PI4) { + std::cerr << "scheduling for: " << (hw_cpus > 4 ? "odroid" : "pi4") << std::endl; }
virtual ~ms_trx() @@ -269,11 +308,19 @@ timing_advance = val * 4; }
- void set_name_aff_sched(const char *name, int cpunum, int schedtype, int prio) + void set_name_aff_sched(sched_params::thread_names name) { - set_name_aff_sched(pthread_self(), name, cpunum, schedtype, prio); + set_name_aff_sched(pthread_self(), name); }
+ void set_name_aff_sched(std::thread::native_handle_type h, sched_params::thread_names name) + { + auto tgt = schdp[hw_target][name]; + // std::cerr << "scheduling for: " << tgt.name << ":" << tgt.core << std::endl; + set_name_aff_sched(h, tgt.name, tgt.core, tgt.schedtype, tgt.prio); + } + + private: void set_name_aff_sched(std::thread::native_handle_type h, const char *name, int cpunum, int schedtype, int prio) { @@ -284,16 +331,14 @@ CPU_ZERO(&cpuset); CPU_SET(cpunum, &cpuset);
- auto rv = pthread_setaffinity_np(h, sizeof(cpuset), &cpuset); - if (rv < 0) { + if (pthread_setaffinity_np(h, sizeof(cpuset), &cpuset) < 0) { std::cerr << name << " affinity: errreur! " << std::strerror(errno); return exit(0); }
sched_param sch_params; sch_params.sched_priority = prio; - rv = pthread_setschedparam(h, schedtype, &sch_params); - if (rv < 0) { + if (pthread_setschedparam(h, schedtype, &sch_params) < 0) { std::cerr << name << " sched: errreur! " << std::strerror(errno); return exit(0); } diff --git a/Transceiver52M/ms/ms_rx_lower.cpp b/Transceiver52M/ms/ms_rx_lower.cpp index e39d72d..e8d8e0e 100644 --- a/Transceiver52M/ms/ms_rx_lower.cpp +++ b/Transceiver52M/ms/ms_rx_lower.cpp @@ -235,7 +235,7 @@ sch_pos = 0; rcv_done = true; std::thread([this] { - set_name_aff_sched("sch_search", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5); + set_name_aff_sched(sched_params::thread_names::SCH_SEARCH);
auto ptr = reinterpret_cast<const int16_t *>(first_sch_buf); const auto target_val = rxFullScale / 8; diff --git a/Transceiver52M/ms/ms_upper.cpp b/Transceiver52M/ms/ms_upper.cpp index 63f5926..3cb27e3 100644 --- a/Transceiver52M/ms/ms_upper.cpp +++ b/Transceiver52M/ms/ms_upper.cpp @@ -97,14 +97,14 @@ void upper_trx::start_threads() { thr_control = std::thread([this] { - set_name_aff_sched("upper_ctrl", 1, SCHED_RR, sched_get_priority_max(SCHED_RR)); + set_name_aff_sched(sched_params::thread_names::U_CTL); while (!g_exit_flag) { driveControl(); } }); msleep(1); thr_tx = std::thread([this] { - set_name_aff_sched("upper_tx", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 1); + set_name_aff_sched(sched_params::thread_names::U_TX); while (!g_exit_flag) { driveTx(); } @@ -113,7 +113,7 @@ // atomic ensures data is not written to q until loop reads start_lower_ms();
- set_name_aff_sched("upper_rx", 1, SCHED_FIFO, sched_get_priority_max(SCHED_RR) - 5); + set_name_aff_sched(sched_params::thread_names::U_RX); while (!g_exit_flag) { // set_upper_ready(true); driveReceiveFIFO(); @@ -128,7 +128,7 @@
#ifdef LSANDEBUG std::thread([this] { - set_name_aff_sched("leakcheck", 1, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 10); + set_name_aff_sched(sched_params::thread_names::LEAKCHECK);
while (1) { std::this_thread::sleep_for(std::chrono::seconds{ 5 }); @@ -485,7 +485,7 @@ std::cerr << "Error initializing hardware, quitting.." << std::endl; return -1; } - trx->set_name_aff_sched("main", 3, SCHED_FIFO, sched_get_priority_max(SCHED_FIFO) - 5); + trx->set_name_aff_sched(sched_params::thread_names::MAIN);
if (!trxcon::trxc_l1ctl_init(tall_trxcon_ctx)) { std::cerr << "Error initializing l1ctl, quitting.." << std::endl;