SRSUE: created initial PHY LTE worker pool

master
Xavier Arteaga 4 years ago committed by Andre Puschmann
parent c9c8a1db5c
commit c6798653be

@ -481,7 +481,7 @@ typedef struct {
float prach_gain = -1;
uint32_t pdsch_max_its = 8;
bool meas_evm = false;
int nof_phy_threads = 3;
uint32_t nof_phy_threads = 3;
int worker_cpu_mask = -1;
int sync_cpu_affinity = -1;

@ -10,14 +10,15 @@
*
*/
#ifndef SRSLTE_CC_WORKER_H
#define SRSLTE_CC_WORKER_H
#ifndef SRSUE_LTE_CC_WORKER_H
#define SRSUE_LTE_CC_WORKER_H
#include "phy_common.h"
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/phy_common.h"
namespace srsue {
namespace lte {
class cc_worker
{
@ -113,6 +114,7 @@ private:
srslte_ue_ul_cfg_t ue_ul_cfg = {};
};
} // namespace lte
} // namespace srsue
#endif // SRSLTE_CC_WORKER_H
#endif // SRSUE_LTE_CC_WORKER_H

@ -10,16 +10,17 @@
*
*/
#ifndef SRSUE_PHCH_WORKER_H
#define SRSUE_PHCH_WORKER_H
#ifndef SRSUE_LTE_SF_WORKER_H
#define SRSUE_LTE_SF_WORKER_H
#include "cc_worker.h"
#include "phy_common.h"
#include "srslte/common/thread_pool.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/phy_common.h"
#include <string.h>
namespace srsue {
namespace lte {
/**
* The sf_worker class handles the PHY processing, UL and DL procedures associated with 1 subframe.
@ -32,7 +33,7 @@ namespace srsue {
class sf_worker : public srslte::thread_pool::worker
{
public:
sf_worker(uint32_t max_prb, phy_common* phy, srslte::log* log, srslte::log* log_phy_lib_h);
sf_worker(uint32_t max_prb, phy_common* phy, srslte::log* log);
virtual ~sf_worker();
void reset_cell_unlocked(uint32_t cc_idx);
@ -80,8 +81,6 @@ private:
srslte::log* log_h = nullptr;
srslte::log* log_phy_lib_h = nullptr;
srslte_cell_t cell = {};
std::mutex cell_mutex;
srslte_tdd_config_t tdd_config = {};
@ -94,9 +93,9 @@ private:
uint32_t tti = 0;
srslte::rf_timestamp_t tx_time = {};
};
} // namespace lte
} // namespace srsue
#endif // SRSUE_PHCH_WORKER_H
#endif // SRSUE_LTE_SF_WORKER_H

@ -0,0 +1,54 @@
/*
* Copyright 2013-2020 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_WORKER_POOL_H
#define SRSLTE_WORKER_POOL_H
#include "sf_worker.h"
#include "srslte/common/thread_pool.h"
namespace srsue {
namespace lte {
class worker_pool
{
private:
std::vector<std::unique_ptr<srslte::log_filter> > log_vec;
srslte::thread_pool pool;
std::vector<std::unique_ptr<sf_worker> > workers;
public:
sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); }
worker_pool(uint32_t max_workers);
bool init(phy_common* common, srslte::logger* logger, int prio);
sf_worker* wait_worker(uint32_t tti);
sf_worker* wait_worker_id(uint32_t id);
void start_worker(sf_worker* w);
void stop();
};
} // namespace lte
} // namespace srsue
#endif // SRSLTE_WORKER_POOL_H

@ -16,7 +16,6 @@
#include "phy_common.h"
#include "phy_metrics.h"
#include "prach.h"
#include "sf_worker.h"
#include "srslte/common/log_filter.h"
#include "srslte/common/threads.h"
#include "srslte/common/trace.h"
@ -25,6 +24,7 @@
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/radio/radio.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/lte/worker_pool.h"
#include "srsue/hdr/phy/ue_lte_phy_base.h"
#include "sync.h"
@ -66,7 +66,7 @@ private:
class phy final : public ue_lte_phy_base, public srslte::thread
{
public:
explicit phy(srslte::logger* logger_) : logger(logger_), workers_pool(MAX_WORKERS), common(), thread("PHY"){};
explicit phy(srslte::logger* logger_) : logger(logger_), lte_workers(MAX_WORKERS), common(), thread("PHY"){};
~phy() final { stop(); }
// Init defined in base class
@ -165,24 +165,21 @@ private:
std::mutex config_mutex;
std::condition_variable config_cond;
bool is_configured = false;
uint32_t nof_workers = 0;
const static int SF_RECV_THREAD_PRIO = 0;
const static int WORKERS_THREAD_PRIO = 2;
srslte::radio_interface_phy* radio = nullptr;
std::vector<std::unique_ptr<srslte::log_filter> > log_vec;
srslte::logger* logger = nullptr;
srslte::radio_interface_phy* radio = nullptr;
srslte::logger* logger = nullptr;
srslte::log* log_h = nullptr;
srslte::log* log_phy_lib_h = nullptr;
srsue::stack_interface_phy_lte* stack = nullptr;
std::unique_ptr<srslte::log_filter> log_h = nullptr;
std::unique_ptr<srslte::log_filter> log_phy_lib_h = nullptr;
srsue::stack_interface_phy_lte* stack = nullptr;
srslte::thread_pool workers_pool;
std::vector<std::unique_ptr<sf_worker> > workers;
phy_common common;
sync sfsync;
prach prach_buffer;
lte::worker_pool lte_workers;
phy_common common;
sync sfsync;
prach prach_buffer;
srslte_prach_cfg_t prach_cfg = {};
srslte_tdd_config_t tdd_config = {};

@ -126,7 +126,6 @@ public:
void worker_end(void* h, bool tx_enable, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time);
void set_cell(const srslte_cell_t& c);
void set_nof_workers(uint32_t nof_workers);
bool sr_enabled = false;
int sr_last_tx_tti = -1;
@ -246,8 +245,6 @@ private:
std::mutex mtch_mutex;
std::condition_variable mtch_cvar;
uint32_t nof_workers = 0;
bool is_pending_tx_end = false;
srslte::radio_interface_phy* radio_h = nullptr;

@ -23,7 +23,6 @@
#include "scell/intra_measure.h"
#include "scell/scell_sync.h"
#include "search.h"
#include "sf_worker.h"
#include "sfn_sync.h"
#include "srslte/common/log.h"
#include "srslte/common/thread_pool.h"
@ -33,6 +32,7 @@
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/phy/channel/channel.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/lte/worker_pool.h"
#include "sync_state.h"
namespace srsue {
@ -52,7 +52,7 @@ public:
void init(srslte::radio_interface_phy* radio_,
stack_interface_phy_lte* _stack,
prach* prach_buffer,
srslte::thread_pool* _workers_pool,
lte::worker_pool* _workers_pool,
phy_common* _worker_com,
srslte::log* _log_h,
srslte::log* _log_phy_lib_h,
@ -164,7 +164,7 @@ private:
* @param worker Selected worker for the current TTI
* @param sync_buffer Sub-frame buffer for the current TTI
*/
void run_camping_in_sync_state(sf_worker* worker, srslte::rf_buffer_t& sync_buffer);
void run_camping_in_sync_state(lte::sf_worker* worker, srslte::rf_buffer_t& sync_buffer);
/**
* Helper method, executed in a TTI basis for signaling to the stack a new TTI execution
@ -197,7 +197,7 @@ private:
stack_interface_phy_lte* stack = nullptr;
srslte::log* log_h = nullptr;
srslte::log* log_phy_lib_h = nullptr;
srslte::thread_pool* workers_pool = nullptr;
lte::worker_pool* workers_pool = nullptr;
srslte::radio_interface_phy* radio_h = nullptr;
phy_common* worker_com = nullptr;
prach* prach_buffer = nullptr;
@ -252,7 +252,6 @@ private:
srslte_timestamp_t stack_tti_ts = {};
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN> mib = {};
uint32_t nof_workers = 0;
uint32_t nof_rf_channels = 0;
float ul_dl_factor = NAN;
int current_earfcn = 0;

@ -270,7 +270,7 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
"Measure PDSCH EVM, increases CPU load (default false)")
("phy.nof_phy_threads",
bpo::value<int>(&args->phy.nof_phy_threads)->default_value(3),
bpo::value<uint32_t>(&args->phy.nof_phy_threads)->default_value(3),
"Number of PHY threads")
("phy.equalizer_mode",

@ -12,7 +12,7 @@
#include "srslte/srslte.h"
#include "srsue/hdr/phy/cc_worker.h"
#include "srsue/hdr/phy/lte/cc_worker.h"
#define Error(fmt, ...) \
if (SRSLTE_DEBUG_ENABLED) \
@ -32,6 +32,7 @@
#define CURRENT_TTI_TX (sf_cfg_ul.tti)
namespace srsue {
namespace lte {
/************
*
@ -903,4 +904,5 @@ int cc_worker::read_pdsch_d(cf_t* pdsch_d)
return ue_dl_cfg.cfg.pdsch.grant.nof_re;
}
} // namespace lte
} // namespace srsue

@ -13,7 +13,7 @@
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/sf_worker.h"
#include "srsue/hdr/phy/lte/sf_worker.h"
#include <string.h>
#include <unistd.h>
@ -45,12 +45,12 @@ static int plot_worker_id = -1;
/*********************************************/
namespace srsue {
namespace lte {
sf_worker::sf_worker(uint32_t max_prb, phy_common* phy_, srslte::log* log_h_, srslte::log* log_phy_lib_h_)
sf_worker::sf_worker(uint32_t max_prb, phy_common* phy_, srslte::log* log_h_)
{
phy = phy_;
log_h = log_h_;
log_phy_lib_h = log_phy_lib_h_;
phy = phy_;
log_h = log_h_;
// ue_sync in phy.cc requires a buffer for 3 subframes
for (uint32_t r = 0; r < phy->args->nof_carriers; r++) {
@ -113,10 +113,6 @@ void sf_worker::set_tti(uint32_t tti_)
}
log_h->step(tti);
if (log_phy_lib_h) {
log_phy_lib_h->step(tti);
}
}
void sf_worker::set_tx_time(const srslte::rf_timestamp_t& tx_time_)
@ -324,6 +320,7 @@ float sf_worker::get_cfo()
phy->get_sync_metrics(sync_metrics);
return sync_metrics[0].cfo;
}
} // namespace lte
} // namespace srsue
/***********************************************************

@ -0,0 +1,74 @@
/*
* Copyright 2013-2020 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srsue/hdr/phy/lte/worker_pool.h"
namespace srsue {
namespace lte {
worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {}
bool worker_pool::init(phy_common* common, srslte::logger* logger, int prio)
{
// Create logs
// Create array of pointers to phy_logs
for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) {
auto* mylog = new srslte::log_filter;
char tmp[16];
sprintf(tmp, "PHY%d", i);
mylog->init(tmp, logger, true);
mylog->set_level(common->args->log.phy_level);
mylog->set_hex_limit(common->args->log.phy_hex_limit);
log_vec.push_back(std::unique_ptr<srslte::log_filter>(mylog));
}
// Add workers to workers pool and start threads
for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) {
auto w =
std::unique_ptr<lte::sf_worker>(new lte::sf_worker(SRSLTE_MAX_PRB, common, (srslte::log*)log_vec[i].get()));
pool.init_worker(i, w.get(), prio, common->args->worker_cpu_mask);
workers.push_back(std::move(w));
}
return true;
}
void worker_pool::start_worker(sf_worker* w)
{
pool.start_worker(w);
}
sf_worker* worker_pool::wait_worker(uint32_t tti)
{
return (sf_worker*)pool.wait_worker(tti);
}
sf_worker* worker_pool::wait_worker_id(uint32_t id)
{
return (sf_worker*)pool.wait_worker_id(id);
}
void worker_pool::stop()
{
pool.stop();
}
}; // namespace lte
}; // namespace srsue

@ -122,43 +122,32 @@ int phy::init(const phy_args_t& args_)
sfsync.force_freq(args.dl_freq, args.ul_freq);
}
// Create array of pointers to phy_logs
for (int i = 0; i < args.nof_phy_threads; i++) {
auto* mylog = new srslte::log_filter;
char tmp[16];
sprintf(tmp, "PHY%d", i);
mylog->init(tmp, logger, true);
mylog->set_level(args.log.phy_level);
mylog->set_hex_limit(args.log.phy_hex_limit);
log_vec.push_back(std::unique_ptr<srslte::log_filter>(mylog));
}
// Add PHY lib log
if (log_vec.at(0)->get_level_from_string(args.log.phy_lib_level) != srslte::LOG_LEVEL_NONE) {
auto* lib_log = new srslte::log_filter;
char tmp[16];
if (srslte::log::get_level_from_string(args.log.phy_lib_level) != srslte::LOG_LEVEL_NONE) {
log_phy_lib_h = std::unique_ptr<srslte::log_filter>(new srslte::log_filter);
char tmp[16];
sprintf(tmp, "PHY_LIB");
lib_log->init(tmp, logger, true);
lib_log->set_level(args.log.phy_lib_level);
lib_log->set_hex_limit(args.log.phy_hex_limit);
log_vec.push_back(std::unique_ptr<srslte::log_filter>(lib_log));
} else {
log_vec.push_back(nullptr);
log_phy_lib_h->init(tmp, logger, true);
log_phy_lib_h->set_level(args.log.phy_lib_level);
log_phy_lib_h->set_hex_limit(args.log.phy_hex_limit);
}
// set default logger
log_h = log_vec.at(0).get();
{
log_h = std::unique_ptr<srslte::log_filter>(new srslte::log_filter);
char tmp[16];
sprintf(tmp, "PHY_COM");
log_h->init(tmp, logger, true);
log_h->set_level(args.log.phy_lib_level);
log_h->set_hex_limit(args.log.phy_hex_limit);
}
if (!check_args(args)) {
return false;
}
nof_workers = args.nof_phy_threads;
if (log_vec[nof_workers]) {
this->log_phy_lib_h = (srslte::log*)log_vec[0].get();
if (log_phy_lib_h) {
srslte_phy_log_register_handler(this, srslte_phy_handler);
} else {
this->log_phy_lib_h = nullptr;
}
is_configured = false;
@ -170,25 +159,20 @@ int phy::init(const phy_args_t& args_)
void phy::run_thread()
{
std::unique_lock<std::mutex> lock(config_mutex);
prach_buffer.init(SRSLTE_MAX_PRB, log_h);
common.init(&args, (srslte::log*)log_vec[0].get(), radio, stack, &sfsync);
// Add workers to workers pool and start threads
for (uint32_t i = 0; i < nof_workers; i++) {
auto w = std::unique_ptr<sf_worker>(new sf_worker(
SRSLTE_MAX_PRB, &common, (srslte::log*)log_vec[i].get(), (srslte::log*)log_vec[nof_workers].get()));
workers_pool.init_worker(i, w.get(), WORKERS_THREAD_PRIO, args.worker_cpu_mask);
workers.push_back(std::move(w));
}
prach_buffer.init(SRSLTE_MAX_PRB, log_h.get());
common.init(&args, log_h.get(), radio, stack, &sfsync);
// Initialise workers
lte_workers.init(&common, logger, WORKERS_THREAD_PRIO);
// Warning this must be initialized after all workers have been added to the pool
sfsync.init(radio,
stack,
&prach_buffer,
&workers_pool,
&lte_workers,
&common,
log_h,
log_phy_lib_h,
log_h.get(),
log_phy_lib_h.get(),
SF_RECV_THREAD_PRIO,
args.sync_cpu_affinity);
@ -220,7 +204,7 @@ void phy::stop()
cmd_worker_cell.stop();
if (is_configured) {
sfsync.stop();
workers_pool.stop();
lte_workers.stop();
prach_buffer.stop();
wait_thread_finish();
@ -445,9 +429,9 @@ void phy::set_crnti(uint16_t rnti)
// set_crnti() is an operation that takes time, run in background worker
cmd_worker.add_cmd([this, rnti]() {
log_h->info("Configuring sequences for C-RNTI=0x%x...\n", rnti);
for (uint32_t i = 0; i < nof_workers; i++) {
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
// set_crnti is not protected so run when worker is finished
sf_worker* w = (sf_worker*)workers_pool.wait_worker_id(i);
lte::sf_worker* w = lte_workers.wait_worker_id(i);
if (w) {
w->set_crnti_unlocked(rnti);
w->release();
@ -460,13 +444,13 @@ void phy::set_crnti(uint16_t rnti)
// Start GUI
void phy::start_plot()
{
workers[0]->start_plot();
lte_workers[0]->start_plot();
}
void phy::enable_pregen_signals(bool enable)
{
for (uint32_t i = 0; i < nof_workers; i++) {
workers[i]->enable_pregen_signals_unlocked(enable);
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
lte_workers[i]->enable_pregen_signals_unlocked(enable);
}
}
@ -499,9 +483,9 @@ bool phy::set_config(srslte::phy_cfg_t config_, uint32_t cc_idx)
// Apply configuration after the worker is finished to avoid race conditions
cmd_worker.add_cmd([this, config_, cc_idx, reconfigure_prach]() {
log_h->info("Setting new PHY configuration cc_idx=%d...\n", cc_idx);
for (uint32_t i = 0; i < nof_workers; i++) {
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
// set_cell is not protected so run when worker is finished
sf_worker* w = (sf_worker*)workers_pool.wait_worker_id(i);
lte::sf_worker* w = lte_workers.wait_worker_id(i);
if (w) {
w->set_config_unlocked(cc_idx, config_);
w->release();
@ -554,17 +538,17 @@ bool phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn)
common.cell_state.configure(cc_idx, earfcn, cell_info.id);
// Reset cell configuration
for (uint32_t i = 0; i < nof_workers; i++) {
workers[i]->reset_cell_unlocked(cc_idx);
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
lte_workers[i]->reset_cell_unlocked(cc_idx);
}
// Component carrier index zero should be reserved for PCell
// Send configuration to workers
cmd_worker.add_cmd([this, cell_info, cc_idx, earfcn, earfcn_is_different]() {
log_h->info("Setting new SCell configuration cc_idx=%d, earfcn=%d...\n", cc_idx, earfcn);
for (uint32_t i = 0; i < nof_workers; i++) {
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
// set_cell is not protected so run when worker is finished
sf_worker* w = (sf_worker*)workers_pool.wait_worker_id(i);
lte::sf_worker* w = lte_workers.wait_worker_id(i);
if (w) {
w->set_cell_unlocked(cc_idx, cell_info);
w->release();
@ -600,9 +584,9 @@ void phy::set_config_tdd(srslte_tdd_config_t& tdd_config_)
// Apply config when worker is finished
cmd_worker.add_cmd([this]() {
for (uint32_t i = 0; i < nof_workers; i++) {
for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
// set_tdd_config is not protected so run when worker is finished
sf_worker* w = (sf_worker*)workers_pool.wait_worker_id(i);
lte::sf_worker* w = lte_workers.wait_worker_id(i);
if (w) {
w->set_tdd_config_unlocked(tdd_config);
w->release();

@ -40,11 +40,6 @@ phy_common::phy_common()
phy_common::~phy_common() = default;
void phy_common::set_nof_workers(uint32_t nof_workers_)
{
nof_workers = nof_workers_;
}
void phy_common::init(phy_args_t* _args,
srslte::log* _log,
srslte::radio_interface_phy* _radio,

@ -14,7 +14,7 @@
#include "srslte/common/log.h"
#include "srslte/phy/channel/channel.h"
#include "srslte/srslte.h"
#include "srsue/hdr/phy/sf_worker.h"
#include "srsue/hdr/phy/lte/sf_worker.h"
#include <algorithm>
#include <unistd.h>
@ -48,7 +48,7 @@ static SRSLTE_AGC_CALLBACK(callback_set_rx_gain)
void sync::init(srslte::radio_interface_phy* _radio,
stack_interface_phy_lte* _stack,
prach* _prach_buffer,
srslte::thread_pool* _workers_pool,
lte::worker_pool* _workers_pool,
phy_common* _worker_com,
srslte::log* _log_h,
srslte::log* _log_phy_lib_h,
@ -79,9 +79,6 @@ void sync::init(srslte::radio_interface_phy* _radio,
channel_emulator = srslte::channel_ptr(new srslte::channel(worker_com->args->dl_channel_args, nof_rf_channels));
}
nof_workers = workers_pool->get_nof_workers();
worker_com->set_nof_workers(nof_workers);
// Initialize cell searcher
search_p.init(sf_buffer, log_h, nof_rf_channels, this);
@ -403,8 +400,11 @@ void sync::run_sfn_sync_state()
}
}
void sync::run_camping_in_sync_state(sf_worker* worker, srslte::rf_buffer_t& sync_buffer)
void sync::run_camping_in_sync_state(lte::sf_worker* worker, srslte::rf_buffer_t& sync_buffer)
{
// Update logging TTI
log_h->step(tti);
log_phy_lib_h->step(tti);
// Check tti is synched with ue_sync
if (srslte_ue_sync_get_sfidx(&ue_sync) != tti % 10) {
@ -501,7 +501,7 @@ void sync::run_camping_in_sync_state(sf_worker* worker, srslte::rf_buffer_t& syn
}
void sync::run_camping_state()
{
sf_worker* worker = (sf_worker*)workers_pool->wait_worker(tti);
lte::sf_worker* worker = (lte::sf_worker*)workers_pool->wait_worker(tti);
srslte::rf_buffer_t sync_buffer = {};
if (worker == nullptr) {
@ -771,13 +771,13 @@ bool sync::set_cell(float cfo)
worker_com->set_cell(cell);
// Reset cell configuration
for (uint32_t i = 0; i < nof_workers; i++) {
((sf_worker*)workers_pool->get_worker(i))->reset_cell_unlocked(0);
for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) {
(*workers_pool)[i]->reset_cell_unlocked(0);
}
bool success = true;
for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) {
sf_worker* w = (sf_worker*)workers_pool->wait_worker_id(i);
for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) {
lte::sf_worker* w = (lte::sf_worker*)workers_pool->wait_worker_id(i);
if (w) {
success &= w->set_cell_unlocked(0, cell);
w->release();

Loading…
Cancel
Save