@@ -108,6 +108,11 @@ class frame_buffer_array
108108 };
109109
110110public:
111+ struct used_buffer {
112+ frame_buffer* buffer;
113+ ofh::slot_symbol_point timestamp;
114+ };
115+
111116 // Constructor receives number of buffers stored/read at a time, reserves storage for all eAxCs.
112117 frame_buffer_array (unsigned nof_buffers_to_return, unsigned buffer_size, unsigned nof_antennas) :
113118 increment_quant (nof_buffers_to_return),
@@ -140,14 +145,14 @@ class frame_buffer_array
140145
141146 // Stores actually used buffers in a list of buffers ready for sending.
142147 // Unused buffers state is changed to 'free'.
143- void push_buffers (span<frame_buffer> prepared_buffers)
148+ void push_buffers (span<frame_buffer> prepared_buffers, ofh::slot_symbol_point symbol_point )
144149 {
145150 for (auto & buffer : prepared_buffers) {
146151 if (buffer.empty ()) {
147152 buffer.status = frame_buffer::frame_buffer_status::free;
148153 } else {
149154 buffer.status = frame_buffer::frame_buffer_status::used;
150- used_buffers.push_back (&buffer);
155+ used_buffers.push_back ({ &buffer, symbol_point} );
151156 }
152157 }
153158 }
@@ -176,14 +181,16 @@ class frame_buffer_array
176181 span<const frame_buffer*> find_buffers_ready_for_sending ()
177182 {
178183 aux_array.clear ();
179- for (auto & buffer : used_buffers) {
180- buffer->status = frame_buffer::frame_buffer_status::marked_to_send;
181- aux_array.push_back (buffer);
184+ for (auto & used_buf : used_buffers) {
185+ used_buf. buffer ->status = frame_buffer::frame_buffer_status::marked_to_send;
186+ aux_array.push_back (used_buf. buffer );
182187 }
183188 used_buffers.clear ();
184189 return aux_array;
185190 }
186191
192+ span<const used_buffer> get_prepared_buffers () const { return used_buffers; }
193+
187194private:
188195 // Number of buffers accessed at a time.
189196 unsigned increment_quant;
@@ -192,7 +199,7 @@ class frame_buffer_array
192199 // Data buffers.
193200 storage_array_type buffers_array;
194201 // Used buffers are added to this list.
195- static_vector<frame_buffer* , 128 > used_buffers;
202+ static_vector<used_buffer , 128 > used_buffers;
196203 // Auxiliary array used as a list of ready-to-send buffers returned to a reader.
197204 std::vector<const frame_buffer*> aux_array;
198205 // Keeps track of the current write position.
@@ -202,8 +209,11 @@ class frame_buffer_array
202209// / Pool of Ethernet frames pre-allocated for each slot symbol.
203210class eth_frame_pool
204211{
212+ // / Number of slots the pool can accommodate.
213+ static constexpr size_t NUM_SLOTS = 20L ;
214+
205215 // / Maximum number of entries contained by the pool, one entry per OFDM symbol, sized to accommodate 20 slots.
206- static constexpr size_t NUM_ENTRIES = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP * 20L ;
216+ static constexpr size_t NUM_ENTRIES = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP * NUM_SLOTS ;
207217
208218 // / Number of symbols in an interval for which an auxiliary vector is pre-allocated to store buffer pointers.
209219 static constexpr size_t NUM_INTERVAL_SYMBOL = 14 ;
@@ -259,10 +269,10 @@ class eth_frame_pool
259269 }
260270
261271 // / Push span of ready buffers to the array associated with the given OFH type.
262- void push_buffers (const ofh_pool_message_type & context, span<frame_buffer> prepared_buffers)
272+ void push_buffers (const frame_pool_context & context, span<frame_buffer> prepared_buffers)
263273 {
264- frame_buffer_array& entry_buf = get_ofh_type_buffers (context.type , context.direction );
265- entry_buf.push_buffers (prepared_buffers);
274+ frame_buffer_array& entry_buf = get_ofh_type_buffers (context.type . type , context. type .direction );
275+ entry_buf.push_buffers (prepared_buffers, context. symbol_point );
266276 }
267277
268278 void clear_buffers (const ofh_pool_message_type& context)
@@ -277,6 +287,12 @@ class eth_frame_pool
277287 entry_buf.reset_buffers ();
278288 }
279289
290+ span<const frame_buffer_array::used_buffer> get_prepared_buffers (const ofh_pool_message_type& context) const
291+ {
292+ const frame_buffer_array& entry_buf = get_ofh_type_buffers (context.type , context.direction );
293+ return entry_buf.get_prepared_buffers ();
294+ }
295+
280296 // / Returns a view over a next stored frame buffer for a given OFH type.
281297 span<const frame_buffer*> read_buffers (const ofh_pool_message_type& context)
282298 {
@@ -320,7 +336,7 @@ class eth_frame_pool
320336 pool_entry& p_entry = get_pool_entry (context.symbol_point .get_slot (), context.symbol_point .get_symbol_index ());
321337 // Lock and update the pool entry.
322338 std::lock_guard<std::mutex> lock (mutex);
323- p_entry.push_buffers (context. type , prepared_buffers);
339+ p_entry.push_buffers (context, prepared_buffers);
324340 }
325341
326342 // / Returns data buffers from the pool to a reader thread given a specific symbol context.
@@ -385,29 +401,76 @@ class eth_frame_pool
385401 }
386402 }
387403
388- // / Clear stored buffers associated with the given slot.
389- void clear_slot (slot_point slot_point)
404+ // / Clears stored buffers associated with the given slot and logs the messages that could not be sent .
405+ void clear_downlink_slot (slot_point slot_point, srslog::basic_logger& logger )
390406 {
391407 // Lock before changing the pool entries.
392408 std::lock_guard<std::mutex> lock (mutex);
393409
394410 pool_entry& cp_entry = get_pool_entry (slot_point, 0 );
395411 // Clear buffers with DL Control-Plane messages.
396412 ofh_pool_message_type msg_type{ofh::message_type::control_plane, ofh::data_direction::downlink};
397- cp_entry.reset_buffers (msg_type);
398- // Clear buffers with UL Control-Plane messages.
399- msg_type.direction = ofh::data_direction::uplink;
400- cp_entry.reset_buffers (msg_type);
413+
414+ auto dl_cp_buffers = cp_entry.get_prepared_buffers (msg_type);
415+ for (const auto & used_buf : dl_cp_buffers) {
416+ if (used_buf.timestamp .get_slot () == slot_point) {
417+ continue ;
418+ }
419+ logger.warning (" Detected '{}' late downlink C-Plane messages in the transmitter queue for slot '{}'" ,
420+ dl_cp_buffers.size (),
421+ used_buf.timestamp .get_slot ());
422+ cp_entry.reset_buffers (msg_type);
423+ break ;
424+ }
401425
402426 // Clear buffers with User-Plane messages.
403427 msg_type.type = ofh::message_type::user_plane;
404428 msg_type.direction = ofh::data_direction::downlink;
405- for (unsigned symbol = 0 ; symbol != 14 ; ++symbol) {
429+ for (unsigned symbol = 0 ; symbol != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP ; ++symbol) {
406430 pool_entry& up_entry = get_pool_entry (slot_point, symbol);
407- up_entry.reset_buffers (msg_type);
431+
432+ auto dl_up_buffers = up_entry.get_prepared_buffers (msg_type);
433+ for (const auto & used_buf : dl_up_buffers) {
434+ if (used_buf.timestamp .get_slot () == slot_point) {
435+ continue ;
436+ }
437+ logger.warning (
438+ " Detected '{}' late downlink U-Plane messages in the transmitter queue for slot '{}', symbol '{}'" ,
439+ dl_up_buffers.size (),
440+ used_buf.timestamp .get_slot (),
441+ used_buf.timestamp .get_symbol_index ());
442+ up_entry.reset_buffers (msg_type);
443+ break ;
444+ }
408445 }
409446 }
410447
448+ // / Clears stored uplink C-Plane buffers associated with the given slot and logs the messages that could not be sent.
449+ void clear_uplink_slot (slot_point slot_point, srslog::basic_logger& logger)
450+ {
451+ // Lock before changing the pool entries.
452+ std::lock_guard<std::mutex> lock (mutex);
453+
454+ pool_entry& cp_entry = get_pool_entry (slot_point, 0 );
455+ // Clear buffers with UL Control-Plane messages.
456+ ofh_pool_message_type msg_type{ofh::message_type::control_plane, ofh::data_direction::uplink};
457+
458+ auto ul_cp_buffers = cp_entry.get_prepared_buffers (msg_type);
459+ for (const auto & used_buf : ul_cp_buffers) {
460+ if (used_buf.timestamp .get_slot () == slot_point) {
461+ continue ;
462+ }
463+ logger.warning (" Detected '{}' late uplink C-Plane messages in the transmitter queue for slot '{}'" ,
464+ ul_cp_buffers.size (),
465+ used_buf.timestamp .get_slot ());
466+ cp_entry.reset_buffers (msg_type);
467+ break ;
468+ }
469+ }
470+
471+ // / Returns number of slots the pool can accommodate.
472+ size_t pool_size_in_slots () const { return NUM_SLOTS; }
473+
411474private:
412475 // / Buffer pool.
413476 std::vector<pool_entry> pool;
0 commit comments