Commit c21b593f authored by Cedric Roux's avatar Cedric Roux

nr rlc: speedup buffer status computation

TX and ReTX should be faster now (for RLC AM, UM and TM).

RLC AM Status (function nr_rlc_entity_am.c:status_size()) was not modified,
so its CPU usage is the same as before. (It's more complicated to change
than for TX and ReTX.)
parent a718ba33
......@@ -63,6 +63,8 @@ typedef struct nr_rlc_entity_t {
void (*max_retx_reached)(void *max_retx_reached_data,
struct nr_rlc_entity_t *entity);
void *max_retx_reached_data;
/* buffer status computation */
nr_rlc_entity_buffer_status_t bstatus;
} nr_rlc_entity_t;
nr_rlc_entity_t *new_nr_rlc_entity_am(
......
......@@ -28,6 +28,19 @@
#include "LOG/log.h"
/* for a given SDU/SDU segment, computes the corresponding PDU header size */
static int compute_pdu_header_size(nr_rlc_entity_am_t *entity,
nr_rlc_sdu_segment_t *sdu)
{
int header_size = 2;
/* one more byte if SN field length is 18 */
if (entity->sn_field_length == 18)
header_size++;
/* two more bytes for SO if SDU segment is not the first */
if (!sdu->is_first) header_size += 2;
return header_size;
}
/*************************************************************************/
/* PDU RX functions */
/*************************************************************************/
......@@ -114,6 +127,10 @@ static void consider_retransmission(nr_rlc_entity_am_t *entity,
nr_rlc_sdu_segment_list_append(&entity->retransmit_list,
&entity->retransmit_end,
cur);
/* update buffer status */
entity->common.bstatus.retx_size += compute_pdu_header_size(entity, cur)
+ cur->size;
}
/* checks that all the bytes of the SDU sn have been received (but SDU
......@@ -351,6 +368,9 @@ static void process_received_ack(nr_rlc_entity_am_t *entity, int ack_sn)
}
/* remove from retransmit list */
prev->next = cur->next;
/* update buffer status */
entity->common.bstatus.retx_size -= compute_pdu_header_size(entity, cur)
+ cur->size;
/* put the PDU in the ack list */
entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
entity->ack_list, cur);
......@@ -840,19 +860,6 @@ static int serialize_sdu(nr_rlc_entity_am_t *entity,
return encoder.byte + sdu->size;
}
/* for a given SDU/SDU segment, computes the corresponding PDU header size */
static int compute_pdu_header_size(nr_rlc_entity_am_t *entity,
nr_rlc_sdu_segment_t *sdu)
{
int header_size = 2;
/* one more byte if SN field length is 18 */
if (entity->sn_field_length == 18)
header_size++;
/* two more bytes for SO if SDU segment is not the first */
if (!sdu->is_first) header_size += 2;
return header_size;
}
/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size'
* bytes
* - modifies SDU/SDU segment to become an SDU segment
......@@ -1426,8 +1433,12 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
sdu->next = NULL;
/* segment if necessary */
pdu_size = pdu_header_size + sdu->size;
/* update buffer status */
entity->common.bstatus.retx_size -= pdu_size;
/* segment if necessary */
if (pdu_size > size) {
nr_rlc_sdu_segment_t *next_sdu;
next_sdu = resegment(sdu, entity, size);
......@@ -1436,6 +1447,9 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
entity->retransmit_list = next_sdu;
if (entity->retransmit_end == NULL)
entity->retransmit_end = entity->retransmit_list;
/* update buffer status */
entity->common.bstatus.retx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size;
}
/* put SDU/SDU segment in the wait list */
......@@ -1479,11 +1493,15 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
sdu->next = NULL;
pdu_size = pdu_header_size + sdu->size;
/* update buffer status */
entity->common.bstatus.tx_size -= pdu_size;
/* assign SN to SDU */
sdu->sdu->sn = entity->tx_next;
/* segment if necessary */
pdu_size = pdu_header_size + sdu->size;
if (pdu_size > size) {
nr_rlc_sdu_segment_t *next_sdu;
next_sdu = resegment(sdu, entity, size);
......@@ -1492,6 +1510,9 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
entity->tx_list = next_sdu;
if (entity->tx_end == NULL)
entity->tx_end = entity->tx_list;
/* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size;
}
/* update tx_next if the SDU segment is the last */
......@@ -1520,24 +1541,6 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
return serialize_sdu(entity, sdu, buffer, size, p);
}
/* Pretend to serialize all the SDUs in a list and return the size
* of all the PDUs it would produce, limited to 'maxsize'.
* Used for buffer status reporting.
*/
static int tx_list_size(nr_rlc_entity_am_t *entity,
nr_rlc_sdu_segment_t *l, int maxsize)
{
int ret = 0;
while (l != NULL && ret < maxsize) {
ret += compute_pdu_header_size(entity, l) + l->size;
l = l->next;
}
if (ret > maxsize) ret = maxsize;
return ret;
}
nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status(
nr_rlc_entity_t *_entity, int maxsize)
{
......@@ -1549,8 +1552,8 @@ nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status(
else
ret.status_size = 0;
ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize);
ret.retx_size = tx_list_size(entity, entity->retransmit_list, maxsize);
ret.tx_size = entity->common.bstatus.tx_size;
ret.retx_size = entity->common.bstatus.retx_size;
return ret;
}
......@@ -1606,6 +1609,10 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
LOG_D(RLC, "Created new RLC SDU and append it to the RLC list \n");
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
/* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, sdu)
+ sdu->size;
}
/*************************************************************************/
......@@ -1793,6 +1800,10 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
entity->tx_end = NULL;
}
/* update buffer status */
entity->common.bstatus.tx_size -= compute_pdu_header_size(entity, cur)
+ cur->size;
nr_rlc_free_sdu_segment(cur);
}
......@@ -1845,6 +1856,9 @@ static void clear_entity(nr_rlc_entity_am_t *entity)
entity->retransmit_end = NULL;
entity->ack_list = NULL;
entity->common.bstatus.tx_size = 0;
entity->common.bstatus.retx_size = 0;
}
void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity)
......
......@@ -68,22 +68,12 @@ static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size)
memcpy(buffer, sdu->sdu->data, sdu->size);
entity->tx_size -= sdu->size;
nr_rlc_free_sdu_segment(sdu);
return ret;
}
static int tx_list_size(nr_rlc_entity_tm_t *entity,
nr_rlc_sdu_segment_t *l, int maxsize)
{
int ret = 0;
/* update buffer status */
entity->common.bstatus.tx_size -= sdu->size;
while (l != NULL && ret < maxsize) {
ret += l->size;
l = l->next;
}
nr_rlc_free_sdu_segment(sdu);
if (ret > maxsize) ret = maxsize;
return ret;
}
......@@ -94,7 +84,7 @@ nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status(
nr_rlc_entity_buffer_status_t ret;
ret.status_size = 0;
ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize);
ret.tx_size = entity->common.bstatus.tx_size;
ret.retx_size = 0;
return ret;
......@@ -136,6 +126,9 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
/* update buffer status */
entity->common.bstatus.tx_size += sdu->size;
}
/*************************************************************************/
......@@ -165,6 +158,8 @@ static void clear_entity(nr_rlc_entity_tm_t *entity)
entity->tx_list = NULL;
entity->tx_end = NULL;
entity->tx_size = 0;
entity->common.bstatus.tx_size = 0;
}
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity)
......
......@@ -28,6 +28,20 @@
#include "LOG/log.h"
/* for a given SDU/SDU segment, computes the corresponding PDU header size */
static int compute_pdu_header_size(nr_rlc_entity_um_t *entity,
nr_rlc_sdu_segment_t *sdu)
{
int header_size = 1;
/* if SN to be included then one more byte if SN field length is 12 */
if (!(sdu->is_first && sdu->is_last) && entity->sn_field_length == 12)
header_size++;
/* two more bytes for SO if SDU segment is not the first */
if (!sdu->is_first) header_size += 2;
return header_size;
}
/*************************************************************************/
/* PDU RX functions */
/*************************************************************************/
......@@ -375,20 +389,6 @@ static int serialize_sdu(nr_rlc_entity_um_t *entity,
return encoder.byte + sdu->size;
}
/* for a given SDU/SDU segment, computes the corresponding PDU header size */
static int compute_pdu_header_size(nr_rlc_entity_um_t *entity,
nr_rlc_sdu_segment_t *sdu)
{
int header_size = 1;
/* if SN to be included then one more byte if SN field length is 12 */
if (!(sdu->is_first && sdu->is_last) && entity->sn_field_length == 12)
header_size++;
/* two more bytes for SO if SDU segment is not the first */
if (!sdu->is_first) header_size += 2;
return header_size;
}
/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size'
* bytes
* - modifies SDU/SDU segment to become an SDU segment
......@@ -462,8 +462,12 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
/* assign SN to SDU */
sdu->sdu->sn = entity->tx_next;
/* segment if necessary */
pdu_size = pdu_header_size + sdu->size;
/* update buffer status */
entity->common.bstatus.tx_size -= pdu_size;
/* segment if necessary */
if (pdu_size > size) {
nr_rlc_sdu_segment_t *next_sdu;
next_sdu = resegment(sdu, entity, size);
......@@ -474,6 +478,9 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
entity->tx_list = next_sdu;
if (entity->tx_end == NULL)
entity->tx_end = entity->tx_list;
/* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size;
}
/* update tx_next if the SDU is an SDU segment and is the last */
......@@ -488,24 +495,6 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
return ret;
}
/* Pretend to serialize all the SDUs in a list and return the size
* of all the PDUs it would produce, limited to 'maxsize'.
* Used for buffer status reporting.
*/
static int tx_list_size(nr_rlc_entity_um_t *entity,
nr_rlc_sdu_segment_t *l, int maxsize)
{
int ret = 0;
while (l != NULL && ret < maxsize) {
ret += compute_pdu_header_size(entity, l) + l->size;
l = l->next;
}
if (ret > maxsize) ret = maxsize;
return ret;
}
nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status(
nr_rlc_entity_t *_entity, int maxsize)
{
......@@ -513,7 +502,7 @@ nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status(
nr_rlc_entity_buffer_status_t ret;
ret.status_size = 0;
ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize);
ret.tx_size = entity->common.bstatus.tx_size;
ret.retx_size = 0;
return ret;
......@@ -555,6 +544,10 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
/* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, sdu)
+ sdu->size;
}
/*************************************************************************/
......@@ -650,6 +643,10 @@ void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
entity->tx_end = NULL;
}
/* update buffer status */
entity->common.bstatus.tx_size -= compute_pdu_header_size(entity, cur)
+ cur->size;
nr_rlc_free_sdu_segment(cur);
}
......@@ -682,6 +679,8 @@ static void clear_entity(nr_rlc_entity_um_t *entity)
entity->tx_list = NULL;
entity->tx_end = NULL;
entity->tx_size = 0;
entity->common.bstatus.tx_size = 0;
}
void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment