diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index a4186a78b..e48144b6f 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -164,6 +164,7 @@ public: } b->reset(); pool->deallocate(b); + b = NULL; } private: buffer_pool *pool; diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 2311b23cb..7601baefa 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -71,6 +71,7 @@ class rlc_am { public: rlc_am(); + ~rlc_am(); void init(log *rlc_entity_log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 0a2469a7c..6d8eb6d08 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -50,6 +50,7 @@ class rlc_um { public: rlc_um(); + ~rlc_um(); void init(log *rlc_entity_log_, uint32_t lcid_, diff --git a/lib/src/phy/fec/viterbi.c b/lib/src/phy/fec/viterbi.c index 25d77ef36..4e5801b94 100644 --- a/lib/src/phy/fec/viterbi.c +++ b/lib/src/phy/fec/viterbi.c @@ -166,9 +166,15 @@ void free37_avx2_16bit(void *o) { if (q->symbols_uc) { free(q->symbols_uc); } + if (q->symbols_us) { + free(q->symbols_us); + } if (q->tmp) { free(q->tmp); } + if (q->tmp_s) { + free(q->tmp_s); + } delete_viterbi37_avx2_16bit(q->ptr); } diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 413a02ac1..b34b0cb0b 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -68,6 +68,12 @@ rlc_am::rlc_am() : tx_sdu_queue(16) do_status = false; } +rlc_am::~rlc_am() +{ + // reset RLC and dealloc SDUs + stop(); +} + void rlc_am::init(srslte::log *log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 213e8c840..3fbcbaadf 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -59,6 +59,11 @@ rlc_um::rlc_um() : tx_sdu_queue(16) pdu_lost = false; } +rlc_um::~rlc_um() +{ + stop(); +} + void rlc_um::init(srslte::log *log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, @@ -114,12 +119,13 @@ void rlc_um::empty_queue() { void rlc_um::stop() { reset(); - mac_timers->timer_release_id(reordering_timer_id); + if (mac_timers) { + mac_timers->timer_release_id(reordering_timer_id); + } } void rlc_um::reset() { - // Empty tx_sdu_queue before locking the mutex empty_queue(); @@ -129,12 +135,17 @@ void rlc_um::reset() vr_ux = 0; vr_uh = 0; pdu_lost = false; - if(rx_sdu) + if(rx_sdu) { rx_sdu->reset(); - if(tx_sdu) + } + + if(tx_sdu) { tx_sdu->reset(); - if(mac_timers) + } + + if(mac_timers) { reordering_timer->stop(); + } // Drop all messages in RX window std::map::iterator it; diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index 086a41bd8..137236b4a 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -85,6 +85,7 @@ private: usleep(100); } running = false; + byte_buffer_pool::get_instance()->deallocate(pdu); } rlc_interface_mac *rlc1; diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 0b8c63668..67305c093 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -59,6 +59,14 @@ public: n_sdus = 0; } + ~rlc_am_tester(){ + for (uint32_t i = 0; i < 10; i++) { + if (sdus[i] != NULL) { + byte_buffer_pool::get_instance()->deallocate(sdus[i]); + } + } + } + // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) { @@ -1048,24 +1056,91 @@ void resegment_test_6() } } +void reset_test() +{ + srslte::log_filter log1("RLC_AM_1"); + srslte::log_filter log2("RLC_AM_2"); + log1.set_level(srslte::LOG_LEVEL_DEBUG); + log2.set_level(srslte::LOG_LEVEL_DEBUG); + log1.set_hex_limit(-1); + log2.set_hex_limit(-1); + rlc_am_tester tester; + mac_dummy_timers timers; + + rlc_am rlc1; + int len; + + log1.set_level(srslte::LOG_LEVEL_DEBUG); + + rlc1.init(&log1, 1, &tester, &tester, &timers); + + LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; + cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; + cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS5; + cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS5; + cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; + cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; + cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; + + rlc1.configure(&cnfg); + + // Push 1 SDU of size 10 into RLC1 + byte_buffer_t sdu_buf; + *sdu_buf.msg = 1; // Write the index into the buffer + sdu_buf.N_bytes = 100; + rlc1.write_sdu(&sdu_buf); + + // read 1 PDU from RLC1 and force segmentation + byte_buffer_t pdu_bufs; + len = rlc1.read_pdu(pdu_bufs.msg, 4); + pdu_bufs.N_bytes = len; + + // reset RLC1 + rlc1.reset(); + + // read another PDU segment from RLC1 + len = rlc1.read_pdu(pdu_bufs.msg, 4); + pdu_bufs.N_bytes = len; + + // now empty RLC buffer + len = rlc1.read_pdu(pdu_bufs.msg, 100); + pdu_bufs.N_bytes = len; + + assert(0 == rlc1.get_buffer_state()); +} + int main(int argc, char **argv) { basic_test(); byte_buffer_pool::get_instance()->cleanup(); + concat_test(); byte_buffer_pool::get_instance()->cleanup(); + segment_test(); byte_buffer_pool::get_instance()->cleanup(); + retx_test(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_1(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_2(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_3(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_4(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_5(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_6(); + byte_buffer_pool::get_instance()->cleanup(); + + reset_test(); + byte_buffer_pool::get_instance()->cleanup(); } diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 6ce39ef7f..3755c1174 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -62,6 +62,14 @@ public: n_sdus = 0; } + ~rlc_um_tester(){ + for (uint32_t i = 0; i < NBUFS; i++) { + if (sdus[i] != NULL) { + byte_buffer_pool::get_instance()->deallocate(sdus[i]); + } + } + } + // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) {