nr rlc: speedup RX path of RLC AM
rx_list is replaced by an array of size 2^(SN size - 1) which is 131072 for an SN size of 18 bits, leading to 1048576 bytes of memory used. (Less for smaller SN sizes.) A lot of RX processing was to run through rx_list. When the list was big (with some non-ideal channel), it can take some time. Removing this list should improve things. Checking with benchmark_nr_rlc_am_entity a speedup of more thant x10 is achieved (except for the case 1024 which is surprisingly faster than the others in the develop branch). The only thing that may be slower is when looking for cur->next where the SN is different, in which case we need to look for all SN one by one until we find something or reach the limit (rx_highest_status). These are the functions get_first_rx_pdu() and get_next_rx_pdu().
This commit is contained in:
@@ -4,7 +4,8 @@ add_library(nr_rlc_core OBJECT
|
||||
nr_rlc_entity_tm.c
|
||||
nr_rlc_entity_um.c
|
||||
nr_rlc_pdu.c
|
||||
nr_rlc_sdu.c)
|
||||
nr_rlc_sdu.c
|
||||
nr_rlc_rx_manager.c)
|
||||
target_include_directories(nr_rlc_core PRIVATE ../../..)
|
||||
target_link_libraries(nr_rlc_core PRIVATE ${T_LIB})
|
||||
add_library(nr_rlc STATIC
|
||||
|
||||
@@ -144,6 +144,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
|
||||
*/
|
||||
ret->common.txsdu_avg_time_to_tx = time_average_new(100 * 1000, 1024);
|
||||
|
||||
ret->rx = nr_rlc_new_rx_manager(1 << (sn_field_length - 1));
|
||||
|
||||
return (nr_rlc_entity_t *)ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,19 +111,17 @@ nr_rlc_sdu_segment_t *nr_rlc_tx_sdu_segment_list_add(nr_rlc_entity_am_t *entity,
|
||||
static int segment_already_received(nr_rlc_entity_am_t *entity,
|
||||
int sn, int so, int size)
|
||||
{
|
||||
nr_rlc_pdu_t *l = entity->rx_list;
|
||||
nr_rlc_pdu_t *l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
int covered;
|
||||
|
||||
while (l != NULL && size > 0) {
|
||||
if (l->sn == sn) {
|
||||
if (l->so <= so && so < l->so + l->size) {
|
||||
covered = l->size - (so - l->so);
|
||||
size -= covered;
|
||||
so += covered;
|
||||
} else if (l->so <= so+size-1 && so+size-1 < l->so + l->size) {
|
||||
covered = size - (l->so - so);
|
||||
size -= covered;
|
||||
}
|
||||
if (l->so <= so && so < l->so + l->size) {
|
||||
covered = l->size - (so - l->so);
|
||||
size -= covered;
|
||||
so += covered;
|
||||
} else if (l->so <= so+size-1 && so+size-1 < l->so + l->size) {
|
||||
covered = size - (l->so - so);
|
||||
size -= covered;
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
@@ -136,27 +134,20 @@ static int segment_already_received(nr_rlc_entity_am_t *entity,
|
||||
*/
|
||||
static int sdu_full(nr_rlc_entity_am_t *entity, int sn)
|
||||
{
|
||||
nr_rlc_pdu_t *l = entity->rx_list;
|
||||
int last_byte;
|
||||
int new_last_byte;
|
||||
nr_rlc_pdu_t *l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
|
||||
last_byte = -1;
|
||||
while (l != NULL) {
|
||||
if (l->sn == sn)
|
||||
break;
|
||||
l = l->next;
|
||||
}
|
||||
int last_byte = -1;
|
||||
|
||||
/* check if the data has already been processed */
|
||||
if (l != NULL && l->data == NULL)
|
||||
return 0;
|
||||
|
||||
while (l != NULL && l->sn == sn) {
|
||||
while (l != NULL) {
|
||||
if (l->so > last_byte + 1)
|
||||
return 0;
|
||||
if (l->is_last)
|
||||
return 1;
|
||||
new_last_byte = l->so + l->size - 1;
|
||||
int new_last_byte = l->so + l->size - 1;
|
||||
if (new_last_byte > last_byte)
|
||||
last_byte = new_last_byte;
|
||||
l = l->next;
|
||||
@@ -168,14 +159,7 @@ static int sdu_full(nr_rlc_entity_am_t *entity, int sn)
|
||||
/* checks that an SDU has already been delivered */
|
||||
static int sdu_delivered(nr_rlc_entity_am_t *entity, int sn)
|
||||
{
|
||||
nr_rlc_pdu_t *l = entity->rx_list;
|
||||
|
||||
while (l != NULL) {
|
||||
if (l->sn == sn)
|
||||
break;
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
nr_rlc_pdu_t *l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
return l != NULL && l->data == NULL;
|
||||
}
|
||||
|
||||
@@ -185,22 +169,17 @@ static int sdu_delivered(nr_rlc_entity_am_t *entity, int sn)
|
||||
*/
|
||||
static int sdu_has_missing_bytes(nr_rlc_entity_am_t *entity, int sn)
|
||||
{
|
||||
nr_rlc_pdu_t *l = entity->rx_list;
|
||||
nr_rlc_pdu_t *l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
int last_byte;
|
||||
int new_last_byte;
|
||||
|
||||
last_byte = -1;
|
||||
while (l != NULL) {
|
||||
if (l->sn == sn)
|
||||
break;
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
/* check if the data has already been processed */
|
||||
if (l != NULL && l->data == NULL)
|
||||
return 0; /* data already processed: no missing byte */
|
||||
|
||||
while (l != NULL && l->sn == sn) {
|
||||
while (l != NULL) {
|
||||
if (l->so > last_byte + 1)
|
||||
return 1;
|
||||
new_last_byte = l->so + l->size - 1;
|
||||
@@ -219,13 +198,10 @@ static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn)
|
||||
int so = 0;
|
||||
int bad_sdu = 0;
|
||||
|
||||
/* go to first segment of sn */
|
||||
pdu = entity->rx_list;
|
||||
while (pdu->sn != sn)
|
||||
pdu = pdu->next;
|
||||
pdu = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
|
||||
/* reassemble - free 'data' of each segment after processing */
|
||||
while (pdu != NULL && pdu->sn == sn) {
|
||||
while (pdu != NULL) {
|
||||
int len = pdu->size - (so - pdu->so);
|
||||
if (so + len > NR_SDU_MAX && !bad_sdu) {
|
||||
LOG_E(RLC, "%s:%d:%s: bad SDU, too big, discarding\n",
|
||||
@@ -262,7 +238,6 @@ static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu)
|
||||
if (sn_compare_rx(entity, x, entity->rx_next_highest) >= 0)
|
||||
entity->rx_next_highest = (x + 1) % entity->sn_modulus;
|
||||
|
||||
/* todo: room for optimization: we can run through rx_list only once */
|
||||
if (sdu_full(entity, x)) {
|
||||
reassemble_and_deliver(entity, x);
|
||||
|
||||
@@ -275,21 +250,26 @@ static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu)
|
||||
|
||||
if (x == entity->rx_next) {
|
||||
/* update rx_next and free all delivered SDUs at the head of the
|
||||
* rx_list
|
||||
* RX list
|
||||
*/
|
||||
int rx_next = entity->rx_next;
|
||||
while (entity->rx_list != NULL && entity->rx_list->data == NULL &&
|
||||
entity->rx_list->sn == rx_next) {
|
||||
int count = 0;
|
||||
nr_rlc_pdu_t *l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, rx_next);
|
||||
while (l != NULL && l->data == NULL) {
|
||||
/* free all segments of this SDU */
|
||||
do {
|
||||
nr_rlc_pdu_t *p = entity->rx_list;
|
||||
entity->rx_list = p->next;
|
||||
nr_rlc_pdu_t *p = l;
|
||||
l = l->next;
|
||||
free(p);
|
||||
} while (entity->rx_list != NULL &&
|
||||
entity->rx_list->sn == rx_next);
|
||||
} while (l != NULL);
|
||||
nr_rlc_rx_manager_clear_pdu(entity->rx, rx_next);
|
||||
count++;
|
||||
rx_next = (rx_next + 1) % entity->sn_modulus;
|
||||
l = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, rx_next);
|
||||
}
|
||||
entity->rx_next = rx_next;
|
||||
nr_rlc_rx_manager_advance(entity->rx, count);
|
||||
nr_rlc_rx_manager_set_start(entity->rx, rx_next);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,8 +844,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
entity->rx_size += data_size;
|
||||
pdu = nr_rlc_new_pdu(sn, so, is_first, is_last,
|
||||
buffer + size - data_size, data_size);
|
||||
entity->rx_list = nr_rlc_pdu_list_add(sn_compare_rx, entity,
|
||||
entity->rx_list, pdu);
|
||||
nr_rlc_rx_manager_add_pdu(entity->rx, pdu);
|
||||
|
||||
/* do reception actions (38.322 5.2.3.2.3) */
|
||||
LOG_D(RLC, "RLC received PDU sn %d so %d is_first %d is_last %d data_size = %d \n", sn, so, is_first, is_last, data_size);
|
||||
@@ -1037,6 +1016,55 @@ typedef struct {
|
||||
nr_rlc_pdu_t *next;
|
||||
} missing_data_t;
|
||||
|
||||
/* returns the first RX PDU with rx_next <= sn <= rx_highest_status
|
||||
* returns NULL if none is found
|
||||
*/
|
||||
static nr_rlc_pdu_t *get_first_rx_pdu(nr_rlc_entity_am_t *entity)
|
||||
{
|
||||
int first_sn = entity->rx_next;
|
||||
int last_sn = entity->rx_highest_status;
|
||||
int sn = first_sn;
|
||||
|
||||
while (sn != last_sn) {
|
||||
nr_rlc_pdu_t *ret = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
if (ret)
|
||||
return ret;
|
||||
sn = (sn + 1) % entity->sn_modulus;
|
||||
}
|
||||
|
||||
return nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
}
|
||||
|
||||
/* find the next RX PDU coming after 'cur'
|
||||
* two cases:
|
||||
* - there is a PDU with same SN, return it
|
||||
* - find PDU with SN <= rx_highest_status if any
|
||||
* limit search to rx_highest_status
|
||||
*/
|
||||
static nr_rlc_pdu_t *get_next_rx_pdu(nr_rlc_entity_am_t *entity,
|
||||
nr_rlc_pdu_t *cur)
|
||||
{
|
||||
if (cur->next)
|
||||
return cur->next;
|
||||
|
||||
/* don't process past rx_highest_status */
|
||||
if (cur->sn == entity->rx_highest_status)
|
||||
return NULL;
|
||||
|
||||
int first_sn = (cur->sn + 1) % entity->sn_modulus;
|
||||
int last_sn = entity->rx_highest_status;
|
||||
int sn = first_sn;
|
||||
|
||||
while (sn != last_sn) {
|
||||
nr_rlc_pdu_t *ret = nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
if (ret)
|
||||
return ret;
|
||||
sn = (sn + 1) % entity->sn_modulus;
|
||||
}
|
||||
|
||||
return nr_rlc_rx_manager_get_pdu_from_sn(entity->rx, sn);
|
||||
}
|
||||
|
||||
/* todo: rewrite this function, too messy */
|
||||
static missing_data_t next_missing(nr_rlc_entity_am_t *entity,
|
||||
nr_rlc_pdu_t *cur, int check_head)
|
||||
@@ -1076,8 +1104,10 @@ next_pdu:
|
||||
max_so = cur_max_so;
|
||||
last_reached = last_reached | cur->is_last;
|
||||
|
||||
nr_rlc_pdu_t *cur_next = get_next_rx_pdu(entity, cur);
|
||||
|
||||
/* no next? */
|
||||
if (cur->next == NULL) {
|
||||
if (cur_next == NULL) {
|
||||
/* inform the caller that work is over */
|
||||
ret.next = NULL;
|
||||
|
||||
@@ -1118,7 +1148,7 @@ next_pdu:
|
||||
return ret;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
cur = cur_next;
|
||||
|
||||
/* no discontinuity in data => process to next PDU */
|
||||
if (cur->sn == sn && max_so >= cur->so - 1)
|
||||
@@ -1374,7 +1404,7 @@ static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
/* first 3 bytes, ack_sn and e1 will be set later */
|
||||
nr_rlc_pdu_encoder_put_bits(&encoder, 0, 8*3);
|
||||
|
||||
cur = entity->rx_list;
|
||||
cur = get_first_rx_pdu(entity);
|
||||
|
||||
/* store the position of the e1 bit to be set if
|
||||
* there is a nack following
|
||||
@@ -1538,7 +1568,7 @@ static int status_size(nr_rlc_entity_am_t *entity, int maxsize)
|
||||
/* minimum 3 bytes */
|
||||
size = 3;
|
||||
|
||||
cur = entity->rx_list;
|
||||
cur = get_first_rx_pdu(entity);
|
||||
|
||||
while (cur != NULL) {
|
||||
m = next_missing(entity, cur, nack_count == 0);
|
||||
@@ -2020,8 +2050,6 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
|
||||
|
||||
static void clear_entity(nr_rlc_entity_am_t *entity)
|
||||
{
|
||||
nr_rlc_pdu_t *cur_rx;
|
||||
|
||||
entity->rx_next = 0;
|
||||
entity->rx_next_status_trigger = 0;
|
||||
entity->rx_highest_status = 0;
|
||||
@@ -2045,13 +2073,7 @@ static void clear_entity(nr_rlc_entity_am_t *entity)
|
||||
entity->t_reassembly_start = 0;
|
||||
entity->t_status_prohibit_start = 0;
|
||||
|
||||
cur_rx = entity->rx_list;
|
||||
while (cur_rx != NULL) {
|
||||
nr_rlc_pdu_t *p = cur_rx;
|
||||
cur_rx = cur_rx->next;
|
||||
nr_rlc_free_pdu(p);
|
||||
}
|
||||
entity->rx_list = NULL;
|
||||
nr_rlc_clear_rx_manager(entity->rx);
|
||||
entity->rx_size = 0;
|
||||
|
||||
nr_rlc_free_sdu_segment_list(entity->tx_list);
|
||||
@@ -2081,6 +2103,7 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity)
|
||||
{
|
||||
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
|
||||
clear_entity(entity);
|
||||
nr_rlc_free_rx_manager(entity->rx);
|
||||
time_average_free(entity->common.txsdu_avg_time_to_tx);
|
||||
free(entity);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "nr_rlc_entity.h"
|
||||
#include "nr_rlc_sdu.h"
|
||||
#include "nr_rlc_pdu.h"
|
||||
#include "nr_rlc_rx_manager.h"
|
||||
|
||||
typedef struct {
|
||||
nr_rlc_entity_t common;
|
||||
@@ -70,9 +71,9 @@ typedef struct {
|
||||
uint64_t t_status_prohibit_start;
|
||||
|
||||
/* rx management */
|
||||
nr_rlc_pdu_t *rx_list;
|
||||
int rx_size;
|
||||
int rx_maxsize;
|
||||
nr_rlc_rx_manager_t *rx;
|
||||
int rx_size;
|
||||
int rx_maxsize;
|
||||
|
||||
/* tx management */
|
||||
nr_rlc_sdu_segment_t *tx_list;
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_rlc_rx_manager.h"
|
||||
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
nr_rlc_rx_manager_t *nr_rlc_new_rx_manager(int size)
|
||||
{
|
||||
nr_rlc_rx_manager_t *ret = calloc_or_fail(1, sizeof(*ret));
|
||||
|
||||
ret->rx_list = calloc_or_fail(size, sizeof(*ret->rx_list));
|
||||
ret->size = size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nr_rlc_clear_rx_manager(nr_rlc_rx_manager_t *m)
|
||||
{
|
||||
for (int i = 0; i < m->size; i++) {
|
||||
nr_rlc_pdu_t *cur = m->rx_list[i];
|
||||
while (cur) {
|
||||
nr_rlc_pdu_t *f = cur;
|
||||
cur = cur->next;
|
||||
nr_rlc_free_pdu(f);
|
||||
}
|
||||
m->rx_list[i] = 0;
|
||||
}
|
||||
m->start = 0;
|
||||
m->sn_start = 0;
|
||||
}
|
||||
|
||||
void nr_rlc_free_rx_manager(nr_rlc_rx_manager_t *m)
|
||||
{
|
||||
nr_rlc_clear_rx_manager(m);
|
||||
free(m->rx_list);
|
||||
free(m);
|
||||
}
|
||||
|
||||
static inline int get_pos(nr_rlc_rx_manager_t *m, int sn)
|
||||
{
|
||||
return (m->start + (sn - m->sn_start + m->size * 2)) % m->size;
|
||||
}
|
||||
|
||||
nr_rlc_pdu_t *nr_rlc_rx_manager_get_pdu_from_sn(nr_rlc_rx_manager_t *m, int sn)
|
||||
{
|
||||
int pos = get_pos(m, sn);
|
||||
return m->rx_list[pos];
|
||||
}
|
||||
|
||||
void nr_rlc_rx_manager_clear_pdu(nr_rlc_rx_manager_t *m, int sn)
|
||||
{
|
||||
int pos = get_pos(m, sn);
|
||||
m->rx_list[pos] = 0;
|
||||
}
|
||||
|
||||
/* beware: after calling this function 'sn_start' is invalid, caller has
|
||||
* to call nr_rlc_rx_manager_set_start() just after
|
||||
*/
|
||||
void nr_rlc_rx_manager_advance(nr_rlc_rx_manager_t *m, int count)
|
||||
{
|
||||
m->start += count;
|
||||
m->start %= m->size;
|
||||
}
|
||||
|
||||
void nr_rlc_rx_manager_set_start(nr_rlc_rx_manager_t *m, int sn_start)
|
||||
{
|
||||
m->sn_start = sn_start;
|
||||
}
|
||||
|
||||
void nr_rlc_rx_manager_add_pdu(nr_rlc_rx_manager_t *m, nr_rlc_pdu_t *pdu)
|
||||
{
|
||||
int pos = get_pos(m, pdu->sn);
|
||||
|
||||
nr_rlc_pdu_t head;
|
||||
nr_rlc_pdu_t *cur;
|
||||
nr_rlc_pdu_t *prev;
|
||||
|
||||
head.next = m->rx_list[pos];
|
||||
cur = m->rx_list[pos];
|
||||
prev = &head;
|
||||
|
||||
/* order by 'so' */
|
||||
while (cur != NULL) {
|
||||
/* check if 'pdu' is before 'cur' in the list */
|
||||
if (cur->so > pdu->so) {
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
prev->next = pdu;
|
||||
pdu->next = cur;
|
||||
|
||||
m->rx_list[pos] = head.next;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_RLC_RX_MANAGER_H_
|
||||
#define _NR_RLC_RX_MANAGER_H_
|
||||
|
||||
#include "nr_rlc_pdu.h"
|
||||
|
||||
typedef struct {
|
||||
/* 'rx_list' is managed as a circular buffer
|
||||
* starts at rx_list[start] where is stored 'sn_start'
|
||||
* for an RLC entity with an SN of n bits, its size is 2^(n-1)
|
||||
* corresponding the the window size
|
||||
*/
|
||||
nr_rlc_pdu_t **rx_list;
|
||||
int size;
|
||||
int start;
|
||||
int sn_start;
|
||||
} nr_rlc_rx_manager_t;
|
||||
|
||||
nr_rlc_rx_manager_t *nr_rlc_new_rx_manager(int size);
|
||||
void nr_rlc_free_rx_manager(nr_rlc_rx_manager_t *m);
|
||||
void nr_rlc_clear_rx_manager(nr_rlc_rx_manager_t *m);
|
||||
|
||||
nr_rlc_pdu_t *nr_rlc_rx_manager_get_pdu_from_sn(nr_rlc_rx_manager_t *m, int sn);
|
||||
void nr_rlc_rx_manager_clear_pdu(nr_rlc_rx_manager_t *m, int sn);
|
||||
void nr_rlc_rx_manager_advance(nr_rlc_rx_manager_t *m, int count);
|
||||
void nr_rlc_rx_manager_set_start(nr_rlc_rx_manager_t *m, int sn_start);
|
||||
void nr_rlc_rx_manager_add_pdu(nr_rlc_rx_manager_t *m, nr_rlc_pdu_t *pdu);
|
||||
|
||||
#endif /* _NR_RLC_RX_MANAGER_H_ */
|
||||
@@ -2,7 +2,7 @@ CC=gcc
|
||||
CFLAGS=-Wall -g --coverage -I. -I../../../.. -D_STANDALONE_TESTING_
|
||||
|
||||
LIB=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o nr_rlc_entity_tm.o \
|
||||
nr_rlc_pdu.o nr_rlc_sdu.o time_stat.o
|
||||
nr_rlc_pdu.o nr_rlc_sdu.o nr_rlc_rx_manager.o time_stat.o
|
||||
|
||||
tests:
|
||||
@./run_tests.sh
|
||||
|
||||
Reference in New Issue
Block a user