From 453a7760b3aaaa69eb741403fa03c671d3eeffe8 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 12 Nov 2021 15:11:09 +0100 Subject: [PATCH] Port misc SSN changes to dev. --- lib/include/srsran/adt/circular_buffer.h | 4 +- lib/include/srsran/common/block_queue.h | 12 ++++- lib/src/common/threads.c | 4 +- srsenb/hdr/phy/phy_metrics.h | 16 +++++- srsenb/hdr/stack/mac/common/mac_metrics.h | 19 ++++--- srsenb/hdr/stack/mac/sched.h | 1 + srsenb/hdr/stack/mac/sched_ue.h | 2 + .../stack/mac/sched_ue_ctrl/sched_ue_cell.h | 2 + srsenb/src/metrics_json.cc | 42 ++++++++++++--- srsenb/src/metrics_stdout.cc | 9 ++-- srsenb/src/stack/mac/mac.cc | 29 +++++++--- srsenb/src/stack/mac/sched.cc | 6 +++ srsenb/src/stack/mac/sched_grid.cc | 53 ++++++++++--------- srsenb/src/stack/mac/sched_ue.cc | 7 +++ srsenb/src/stack/upper/rlc.cc | 7 ++- 15 files changed, 154 insertions(+), 59 deletions(-) diff --git a/lib/include/srsran/adt/circular_buffer.h b/lib/include/srsran/adt/circular_buffer.h index 72f636dff..156abc99c 100644 --- a/lib/include/srsran/adt/circular_buffer.h +++ b/lib/include/srsran/adt/circular_buffer.h @@ -291,7 +291,7 @@ public: } return obj; } - bool pop_wait_until(T& obj, const std::chrono::system_clock::time_point& until) { return pop_(obj, true, &until); } + bool pop_wait_until(T& obj, const std::chrono::steady_clock::time_point& until) { return pop_(obj, true, &until); } void clear() { T obj; @@ -405,7 +405,7 @@ protected: return {}; } - bool pop_(T& obj, bool block, const std::chrono::system_clock::time_point* until = nullptr) + bool pop_(T& obj, bool block, const std::chrono::steady_clock::time_point* until = nullptr) { std::unique_lock lock(mutex); if (not active) { diff --git a/lib/include/srsran/common/block_queue.h b/lib/include/srsran/common/block_queue.h index 7442c9a0b..a53bd67c0 100644 --- a/lib/include/srsran/common/block_queue.h +++ b/lib/include/srsran/common/block_queue.h @@ -95,6 +95,8 @@ public: return value; } + bool timedwait_pop(myobj* value, const struct timespec* abstime) { return pop_(value, true, abstime); } + bool empty() { // queue is empty? pthread_mutex_lock(&mutex); @@ -130,7 +132,7 @@ public: } private: - bool pop_(myobj* value, bool block) + bool pop_(myobj* value, bool block, const struct timespec* abstime = nullptr) { if (!enable) { return false; @@ -142,7 +144,13 @@ private: goto exit; } while (q.empty() && enable) { - pthread_cond_wait(&cv_empty, &mutex); + if (abstime == nullptr) { + pthread_cond_wait(&cv_empty, &mutex); + } else { + if (pthread_cond_timedwait(&cv_empty, &mutex, abstime)) { + goto exit; + } + } } if (!enable) { goto exit; diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index bad3d05d7..8ae786848 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -80,7 +80,9 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* #else // All threads have normal priority except prio_offset=0,1,2,3,4 if (prio_offset >= 0 && prio_offset < 5) { - param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset; + // Subtract one to the priority offset to avoid scheduling threads with the highest priority that could contend with + // OS critical tasks. + param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset - 1; if (pthread_attr_init(&attr)) { perror("pthread_attr_init"); } else { diff --git a/srsenb/hdr/phy/phy_metrics.h b/srsenb/hdr/phy/phy_metrics.h index 2207de864..0b27a5417 100644 --- a/srsenb/hdr/phy/phy_metrics.h +++ b/srsenb/hdr/phy/phy_metrics.h @@ -13,6 +13,8 @@ #ifndef SRSENB_PHY_METRICS_H #define SRSENB_PHY_METRICS_H +#include + namespace srsenb { // PHY metrics per user @@ -20,7 +22,15 @@ namespace srsenb { struct ul_metrics_t { float n; float pusch_sinr; - float pucch_sinr; + // Initialize this member with an invalid value as this field is optional. + float pusch_rssi = std::numeric_limits::quiet_NaN(); + // Initialize this member with an invalid value as this field is optional. + int64_t pusch_tpc = 0; + float pucch_sinr; + // Initialize this member with an invalid value as this field is optional. + float pucch_rssi = std::numeric_limits::quiet_NaN(); + // Initialize this member with an invalid value as this field is optional. + float pucch_ni = std::numeric_limits::quiet_NaN(); float rssi; float turbo_iters; float mcs; @@ -30,7 +40,9 @@ struct ul_metrics_t { struct dl_metrics_t { float mcs; - int n_samples; + // Initialize this member with an invalid value as this field is optional. + int64_t pucch_tpc = 0; + int n_samples; }; struct phy_metrics_t { diff --git a/srsenb/hdr/stack/mac/common/mac_metrics.h b/srsenb/hdr/stack/mac/common/mac_metrics.h index 78165ed1b..4fb47770d 100644 --- a/srsenb/hdr/stack/mac/common/mac_metrics.h +++ b/srsenb/hdr/stack/mac/common/mac_metrics.h @@ -21,6 +21,7 @@ namespace srsenb { /// MAC metrics per user struct mac_ue_metrics_t { uint16_t rnti; + uint32_t pci; uint32_t nof_tti; uint32_t cc_idx; int tx_pkts; @@ -35,16 +36,18 @@ struct mac_ue_metrics_t { float dl_ri; float dl_pmi; float phr; + float dl_cqi_offset; + float ul_snr_offset; // NR-only UL PHY metrics - float pusch_sinr; - float pucch_sinr; - float ul_rssi; - float fec_iters; - float dl_mcs; - int dl_mcs_samples; - float ul_mcs; - int ul_mcs_samples; + float pusch_sinr; + float pucch_sinr; + float ul_rssi; + float fec_iters; + float dl_mcs; + int dl_mcs_samples; + float ul_mcs; + int ul_mcs_samples; }; /// MAC misc information for each cc. struct mac_cc_info_t { diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index 4e0ab9c68..31c076d1c 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -77,6 +77,7 @@ public: std::array get_enb_ue_cc_map(uint16_t rnti) final; std::array get_enb_ue_activ_cc_map(uint16_t rnti) final; int ul_buffer_add(uint16_t rnti, uint32_t lcid, uint32_t bytes) final; + int metrics_read(uint16_t rnti, mac_ue_metrics_t& metrics); class carrier_sched; diff --git a/srsenb/hdr/stack/mac/sched_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index fc68c70c8..312fcc3c9 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -18,6 +18,7 @@ #include "sched_ue_ctrl/sched_ue_cell.h" #include "sched_ue_ctrl/tpc.h" #include "srsenb/hdr/common/common_enb.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" #include "srsran/srslog/srslog.h" #include #include @@ -73,6 +74,7 @@ public: const ue_cfg_t& get_ue_cfg() const { return cfg; } uint32_t get_aggr_level(uint32_t enb_cc_idx, uint32_t nof_bits); void ul_buffer_add(uint8_t lcid, uint32_t bytes); + void metrics_read(mac_ue_metrics_t& metrics); /******************************************************* * Functions used by scheduler metric objects diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index b0f34d5c4..830ae628c 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -43,6 +43,8 @@ struct sched_ue_cell { const ue_cc_cfg* get_ue_cc_cfg() const { return configured() ? &ue_cfg->supported_cc_list[ue_cc_idx] : nullptr; } const sched_interface::ue_cfg_t* get_ue_cfg() const { return configured() ? ue_cfg : nullptr; } cc_st cc_state() const { return cc_state_; } + float get_ul_snr_offset() const { return ul_snr_coeff; } + float get_dl_cqi_offset() const { return dl_cqi_coeff; } int get_dl_cqi() const; int get_dl_cqi(const rbgmask_t& rbgs) const; diff --git a/srsenb/src/metrics_json.cc b/srsenb/src/metrics_json.cc index 2e2505a48..0e129f712 100644 --- a/srsenb/src/metrics_json.cc +++ b/srsenb/src/metrics_json.cc @@ -45,6 +45,13 @@ DECLARE_METRIC("dl_bitrate", metric_dl_bitrate, float, ""); DECLARE_METRIC("dl_bler", metric_dl_bler, float, ""); DECLARE_METRIC("ul_snr", metric_ul_snr, float, ""); DECLARE_METRIC("ul_mcs", metric_ul_mcs, float, ""); +DECLARE_METRIC("ul_pusch_rssi", metric_ul_pusch_rssi, float, ""); +DECLARE_METRIC("ul_pucch_rssi", metric_ul_pucch_rssi, float, ""); +DECLARE_METRIC("ul_pucch_ni", metric_ul_pucch_ni, float, ""); +DECLARE_METRIC("ul_pusch_tpc", metric_ul_pusch_tpc, int64_t, ""); +DECLARE_METRIC("ul_pucch_tpc", metric_ul_pucch_tpc, int64_t, ""); +DECLARE_METRIC("dl_cqi_offset", metric_dl_cqi_offset, float, ""); +DECLARE_METRIC("ul_snr_offset", metric_ul_snr_offset, float, ""); DECLARE_METRIC("ul_bitrate", metric_ul_bitrate, float, ""); DECLARE_METRIC("ul_bler", metric_ul_bler, float, ""); DECLARE_METRIC("ul_phr", metric_ul_phr, float, ""); @@ -55,6 +62,13 @@ DECLARE_METRIC_SET("ue_container", metric_ue_rnti, metric_dl_cqi, metric_dl_mcs, + metric_ul_pusch_rssi, + metric_ul_pucch_rssi, + metric_ul_pucch_ni, + metric_ul_pusch_tpc, + metric_ul_pucch_tpc, + metric_dl_cqi_offset, + metric_ul_snr_offset, metric_dl_bitrate, metric_dl_bler, metric_ul_snr, @@ -88,24 +102,40 @@ static void fill_ue_metrics(mset_ue_container& ue, const enb_metrics_t& m, unsig ue.write(m.stack.mac.ues[i].rnti); ue.write(std::max(0.1f, m.stack.mac.ues[i].dl_cqi)); if (!std::isnan(m.phy[i].dl.mcs)) { - ue.write(std::max(0.1f, m.phy[i].dl.mcs)); + ue.write(m.phy[i].dl.mcs); } if (m.stack.mac.ues[i].tx_brate > 0 && m.stack.mac.ues[i].nof_tti > 0) { ue.write( std::max(0.1f, (float)m.stack.mac.ues[i].tx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f))); } if (m.stack.mac.ues[i].tx_pkts > 0 && m.stack.mac.ues[i].tx_errors > 0) { - ue.write(std::max(0.1f, (float)100 * m.stack.mac.ues[i].tx_errors / m.stack.mac.ues[i].tx_pkts)); + ue.write((float)100 * m.stack.mac.ues[i].tx_errors / m.stack.mac.ues[i].tx_pkts); } if (!std::isnan(m.phy[i].ul.pusch_sinr)) { - ue.write(std::max(0.1f, m.phy[i].ul.pusch_sinr)); + ue.write(m.phy[i].ul.pusch_sinr); + } + if (!std::isnan(m.phy[i].ul.pusch_rssi)) { + ue.write(m.phy[i].ul.pusch_rssi); + } + if (!std::isnan(m.phy[i].ul.pucch_rssi)) { + ue.write(m.phy[i].ul.pucch_rssi); + } + if (!std::isnan(m.phy[i].ul.pucch_ni)) { + ue.write(m.phy[i].ul.pucch_ni); + } + ue.write(m.phy[i].ul.pusch_tpc); + ue.write(m.phy[i].dl.pucch_tpc); + if (!std::isnan(m.stack.mac.ues[i].dl_cqi_offset)) { + ue.write(m.stack.mac.ues[i].dl_cqi_offset); + } + if (!std::isnan(m.stack.mac.ues[i].ul_snr_offset)) { + ue.write(m.stack.mac.ues[i].ul_snr_offset); } if (!std::isnan(m.phy[i].ul.mcs)) { - ue.write(std::max(0.1f, m.phy[i].ul.mcs)); + ue.write(m.phy[i].ul.mcs); } if (m.stack.mac.ues[i].rx_brate > 0 && m.stack.mac.ues[i].nof_tti > 0) { - ue.write( - std::max(0.1f, (float)m.stack.mac.ues[i].rx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f))); + ue.write((float)m.stack.mac.ues[i].rx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f)); } if (m.stack.mac.ues[i].rx_pkts > 0 && m.stack.mac.ues[i].rx_errors > 0) { ue.write(std::max(0.1f, (float)100 * m.stack.mac.ues[i].rx_errors / m.stack.mac.ues[i].rx_pkts)); diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 2a1a213f2..29fcc70a0 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -88,7 +88,8 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue fmt::print("rx caution errors {} > {}\n", mac.ues[i].rx_errors, mac.ues[i].rx_pkts); } - fmt::print("{:>3.5}", (is_nr) ? "nr" : "lte"); + fmt::print("{:>4}", mac.ues[i].pci); + fmt::print(" {:>3.5}", (is_nr) ? "nr" : "lte"); fmt::print("{:>5x}", mac.ues[i].rnti); if (not iszero(mac.ues[i].dl_cqi)) { fmt::print(" {:>3}", int(mac.ues[i].dl_cqi)); @@ -185,8 +186,10 @@ void metrics_stdout::set_metrics(const enb_metrics_t& metrics, const uint32_t pe if (++n_reports > 10) { n_reports = 0; fmt::print("\n"); - fmt::print(" -----------------DL----------------|-------------------------UL-------------------------\n"); - fmt::print("rat rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); + fmt::print( + " -----------------DL----------------|-------------------------UL-------------------------\n"); + fmt::print( + " pci rat rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); } set_metrics_helper(metrics.stack.rrc.ues.size(), metrics.stack.mac, metrics.phy, false); diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index b451f77ec..34f37373f 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -241,7 +241,11 @@ void mac::get_metrics(mac_metrics_t& metrics) continue; } metrics.ues.emplace_back(); - u.second->metrics_read(&metrics.ues.back()); + auto& ue_metrics = metrics.ues.back(); + + u.second->metrics_read(&ue_metrics); + scheduler.metrics_read(u.first, ue_metrics); + ue_metrics.pci = (ue_metrics.cc_idx < cell_config.size()) ? cell_config[ue_metrics.cc_idx].cell.id : 0; } metrics.cc_info.resize(detected_rachs.size()); for (unsigned cc = 0, e = detected_rachs.size(); cc != e; ++cc) { @@ -570,11 +574,22 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx // Trigger scheduler RACH scheduler.dl_rach_info(enb_cc_idx, rar_info); - logger.info( - "RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", tti, enb_cc_idx, preamble_idx, time_adv, rnti); - srsran::console("RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", + auto get_pci = [this, enb_cc_idx]() { + srsran::rwlock_read_guard lock(rwlock); + return (enb_cc_idx < cell_config.size()) ? cell_config[enb_cc_idx].cell.id : 0; + }; + uint32_t pci = get_pci(); + logger.info("RACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x", + tti, + enb_cc_idx, + pci, + preamble_idx, + time_adv, + rnti); + srsran::console("RACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", tti, enb_cc_idx, + pci, preamble_idx, time_adv, rnti); @@ -831,9 +846,9 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res int requested_bytes = (mcs_data.tbs / 8 > (int)mch.mtch_sched[mtch_index].lcid_buffer_size) ? (mch.mtch_sched[mtch_index].lcid_buffer_size) : ((mcs_data.tbs / 8) - 2); - int bytes_received = ue_db[SRSRAN_MRNTI]->read_pdu(current_lcid, mtch_payload_buffer, requested_bytes); - mch.pdu[0].lcid = current_lcid; - mch.pdu[0].nbytes = bytes_received; + int bytes_received = ue_db[SRSRAN_MRNTI]->read_pdu(current_lcid, mtch_payload_buffer, requested_bytes); + mch.pdu[0].lcid = current_lcid; + mch.pdu[0].nbytes = bytes_received; mch.mtch_sched[0].mtch_payload = mtch_payload_buffer; dl_sched_res->pdsch[0].dci.rnti = SRSRAN_MRNTI; if (bytes_received) { diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index d836fdbd2..bfa4aa278 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -361,6 +361,12 @@ bool sched::is_generated(srsran::tti_point tti_rx, uint32_t enb_cc_idx) const return sched_results.has_sf(tti_rx) and sched_results.get_sf(tti_rx)->is_generated(enb_cc_idx); } +int sched::metrics_read(uint16_t rnti, mac_ue_metrics_t& metrics) +{ + return ue_db_access_locked( + rnti, [&metrics](sched_ue& ue) { ue.metrics_read(metrics); }, "metrics_read"); +} + // Common way to access ue_db elements in a read locking way template int sched::ue_db_access_locked(uint16_t rnti, Func&& f, const char* func_name, bool log_fail) diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index fba1acf28..ff0178fb9 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -78,8 +78,8 @@ void sf_grid_t::init(const sched_cell_params_t& cell_params_) // Compute reserved PRBs for CQI, SR and HARQ-ACK, and store it in a bitmask pucch_mask.resize(cc_cfg->nof_prb()); - pucch_nrb = (cc_cfg->cfg.nrb_pucch > 0) ? (uint32_t)cc_cfg->cfg.nrb_pucch : 0; - srsran_pucch_cfg_t pucch_cfg = cell_params_.pucch_cfg_common; + pucch_nrb = (cc_cfg->cfg.nrb_pucch > 0) ? (uint32_t)cc_cfg->cfg.nrb_pucch : 0; + srsran_pucch_cfg_t pucch_cfg = cell_params_.pucch_cfg_common; uint32_t harq_pucch = 0; if (cc_cfg->sched_cfg->pucch_harq_max_rb > 0) { harq_pucch = cc_cfg->sched_cfg->pucch_harq_max_rb; @@ -822,13 +822,13 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r sched_interface::ul_sched_data_t& pusch = ul_result->pusch.back(); uint32_t total_data_before = user->get_pending_ul_data_total(get_tti_tx_ul(), cc_cfg->enb_cc_idx); int tbs = user->generate_format0(&pusch, - get_tti_tx_ul(), - cc_cfg->enb_cc_idx, - ul_alloc.alloc, - ul_alloc.needs_pdcch(), - cce_range, - ul_alloc.msg3_mcs, - uci_type); + get_tti_tx_ul(), + cc_cfg->enb_cc_idx, + ul_alloc.alloc, + ul_alloc.needs_pdcch(), + cce_range, + ul_alloc.msg3_mcs, + uci_type); ul_harq_proc* h = user->get_ul_harq(get_tti_tx_ul(), cc_cfg->enb_cc_idx); uint32_t new_pending_bytes = user->get_pending_ul_new_data(get_tti_tx_ul(), cc_cfg->enb_cc_idx); @@ -854,23 +854,24 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r uint32_t old_pending_bytes = user->get_pending_ul_old_data(); if (logger.info.enabled()) { fmt::memory_buffer str_buffer; - fmt::format_to( - str_buffer, - "SCHED: {} {} rnti=0x{:x}, cc={}, pid={}, dci=({},{}), prb={}, n_rtx={}, cfi={}, tbs={}, bsr={} ({}-{})", - ul_alloc.is_msg3 ? "Msg3" : "UL", - ul_alloc.is_retx() ? "retx" : "tx", - user->get_rnti(), - cc_cfg->enb_cc_idx, - h->get_id(), - pusch.dci.location.L, - pusch.dci.location.ncce, - ul_alloc.alloc, - h->nof_retx(0), - tti_alloc.get_cfi(), - tbs, - new_pending_bytes, - total_data_before, - old_pending_bytes); + fmt::format_to(str_buffer, + "SCHED: {} {} rnti=0x{:x}, cc={}, pid={}, dci=({},{}), prb={}, n_rtx={}, cfi={}, tbs={}, bsr={} " + "({}-{}), tti_tx_ul={}", + ul_alloc.is_msg3 ? "Msg3" : "UL", + ul_alloc.is_retx() ? "retx" : "tx", + user->get_rnti(), + cc_cfg->enb_cc_idx, + h->get_id(), + pusch.dci.location.L, + pusch.dci.location.ncce, + ul_alloc.alloc, + h->nof_retx(0), + tti_alloc.get_cfi(), + tbs, + new_pending_bytes, + total_data_before, + old_pending_bytes, + get_tti_tx_ul().to_uint()); logger.info("%s", srsran::to_c_str(str_buffer)); } diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index fb4d15d3f..d34529c94 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -164,6 +164,13 @@ void sched_ue::unset_sr() sr = false; } +void sched_ue::metrics_read(mac_ue_metrics_t& metrics) +{ + sched_ue_cell& pcell = cells[cfg.supported_cc_list[0].enb_cc_idx]; + metrics.ul_snr_offset = pcell.get_ul_snr_offset(); + metrics.dl_cqi_offset = pcell.get_dl_cqi_offset(); +} + tti_point prev_meas_gap_start(tti_point tti, uint32_t period, uint32_t offset) { return tti_point{static_cast(floor(static_cast((tti - offset).to_uint()) / period)) * period + diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 38ccd6a35..016d59deb 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -75,14 +75,17 @@ void rlc::add_user(uint16_t rnti) void rlc::rem_user(uint16_t rnti) { - pthread_rwlock_wrlock(&rwlock); + pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { users[rnti].rlc->stop(); - users.erase(rnti); } else { logger.error("Removing rnti=0x%x. Already removed", rnti); } pthread_rwlock_unlock(&rwlock); + + pthread_rwlock_wrlock(&rwlock); + users.erase(rnti); + pthread_rwlock_unlock(&rwlock); } void rlc::clear_buffer(uint16_t rnti)