1515
1616using namespace srsran ;
1717
18- class ue_event_manager ::ue_dl_buffer_occupancy_manager
18+ // / \brief More than one DL buffer occupancy update may be received per slot for the same UE and bearer. This class
19+ // / ensures that the UE DL buffer occupancy is updated only once per bearer per slot for efficiency reasons.
20+ class ue_event_manager ::ue_dl_buffer_occupancy_manager final : public scheduler_dl_buffer_state_indication_handler
1921{
22+ using bearer_key = uint32_t ;
23+ static constexpr size_t NOF_BEARER_KEYS = MAX_NOF_DU_UES * MAX_NOF_RB_LCIDS;
24+
25+ static bearer_key get_bearer_key (du_ue_index_t ue_index, lcid_t lcid) { return lcid * MAX_NOF_DU_UES + ue_index; }
26+ static du_ue_index_t get_ue_index (bearer_key key) { return to_du_ue_index (key % MAX_NOF_DU_UES); }
27+ static lcid_t get_lcid (bearer_key key) { return uint_to_lcid (key / MAX_NOF_DU_UES); }
28+
2029public:
2130 ue_dl_buffer_occupancy_manager (ue_event_manager& parent_) : parent(parent_)
2231 {
23- std::fill (ue_rlc_bo_list .begin (), ue_rlc_bo_list .end (), -1 );
32+ std::fill (ue_dl_bo_table .begin (), ue_dl_bo_table .end (), -1 );
2433 }
2534
26- void enqueue_rlc_buffer_occupancy_update (const dl_buffer_state_indication_message& rlc_dl_bo)
35+ void handle_dl_buffer_state_indication (const dl_buffer_state_indication_message& rlc_dl_bo) override
2736 {
28- unsigned idx = rlc_dl_bo.ue_index * MAX_NOF_RB_LCIDS + rlc_dl_bo.lcid ;
29- bool first_rlc_bo = ue_rlc_bo_list[idx].exchange (rlc_dl_bo.bs , std::memory_order_acquire) < 0 ;
37+ // Update DL Buffer Occupancy for the given UE and bearer.
38+ unsigned key = get_bearer_key (rlc_dl_bo.ue_index , rlc_dl_bo.lcid );
39+ bool first_rlc_bo = ue_dl_bo_table[key].exchange (rlc_dl_bo.bs , std::memory_order_acquire) < 0 ;
3040
3141 if (not first_rlc_bo) {
42+ // If another DL BO update has been received before for this same bearer, we do not need to enqueue a new event.
3243 return ;
3344 }
3445
35- pending_evs.push (rlc_dl_bo);
46+ // Signal that this bearer needs its BO state updated.
47+ pending_evs.push (key);
3648 }
3749
3850 void slot_indication ()
3951 {
4052 // Retrieve pending UEs.
4153 pending_evs.slot_indication ();
42- span<dl_buffer_state_indication_message > ues_to_process = pending_evs.get_events ();
54+ span<bearer_key > ues_to_process = pending_evs.get_events ();
4355
4456 // Process RLC buffer updates of pending UEs.
45- for (dl_buffer_state_indication_message& dl_bo : ues_to_process) {
57+ for (bearer_key key : ues_to_process) {
58+ // Recreate latest DL BO update.
59+ dl_buffer_state_indication_message dl_bo;
60+ // > Extract UE index and LCID.
61+ dl_bo.ue_index = get_ue_index (key);
62+ dl_bo.lcid = get_lcid (key);
63+ // > Extract last DL BO value for the respective bearer and reset BO table position.
64+ dl_bo.bs = ue_dl_bo_table[key].exchange (-1 , std::memory_order_acq_rel);
65+ if (dl_bo.bs < 0 ) {
66+ parent.logger .warning (
67+ " ue={} lcid={}: Invalid DL buffer occupancy value: {}" , dl_bo.ue_index , dl_bo.lcid , dl_bo.bs );
68+ continue ;
69+ }
70+
71+ // Retrieve UE.
4672 if (not parent.ue_db .contains (dl_bo.ue_index )) {
4773 parent.log_invalid_ue_index (dl_bo.ue_index );
4874 continue ;
4975 }
5076 ue& u = parent.ue_db [dl_bo.ue_index ];
5177
52- // Update DL buffer state with latest RLC buffer occupancy update for this UE.
53- unsigned idx = dl_bo.ue_index * MAX_NOF_RB_LCIDS + dl_bo.lcid ;
54- dl_bo.bs = ue_rlc_bo_list[idx].exchange (-1 , std::memory_order_acq_rel);
55-
56- // Forward DL buffer state to UE.
78+ // Forward DL BO update to UE.
5779 u.handle_dl_buffer_state_indication (dl_bo);
5880 if (dl_bo.lcid == LCID_SRB0) {
5981 // Signal SRB0 scheduler with the new SRB0 buffer state.
@@ -71,9 +93,10 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager
7193private:
7294 ue_event_manager& parent;
7395
74- std::array<std::atomic<int >, MAX_NOF_DU_UES * MAX_NOF_RB_LCIDS> ue_rlc_bo_list;
96+ // Table of pending DL Buffer Occupancy values. -1 means that no DL Buffer Occupancy is set.
97+ std::array<std::atomic<int >, NOF_BEARER_KEYS> ue_dl_bo_table;
7598
76- slot_event_list<dl_buffer_state_indication_message > pending_evs;
99+ slot_event_list<bearer_key > pending_evs;
77100};
78101
79102ue_event_manager::ue_event_manager (ue_repository& ue_db_,
@@ -390,7 +413,7 @@ void ue_event_manager::handle_dl_mac_ce_indication(const dl_mac_ce_indication& c
390413
391414void ue_event_manager::handle_dl_buffer_state_indication (const dl_buffer_state_indication_message& bs)
392415{
393- dl_bo_mng->enqueue_rlc_buffer_occupancy_update (bs);
416+ dl_bo_mng->handle_dl_buffer_state_indication (bs);
394417}
395418
396419void ue_event_manager::process_common (slot_point sl, du_cell_index_t cell_index)
0 commit comments