Commit d67b46a1 authored by Cedric Roux's avatar Cedric Roux

nr pdcp: introduce a thread to do pdcp_data_ind

Before this commit, pdcp_data_ind is done in the realtime PHY/MAC
thread, and this may have an impact on realtime performances.

Let's introduce a new thread to do the job, freeing the realtime
PHY/MAC logic.

This is not a minor change. It may have positive and/or negative
effects. To be tested carefully.
parent e19460a9
......@@ -215,6 +215,182 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
/* rlc_data_req queue - end */
/****************************************************************************/
/****************************************************************************/
/* pdcp_data_ind thread - begin */
/****************************************************************************/
typedef struct {
protocol_ctxt_t ctxt_pP;
srb_flag_t srb_flagP;
MBMS_flag_t MBMS_flagP;
rb_id_t rb_id;
sdu_size_t sdu_buffer_size;
mem_block_t *sdu_buffer;
} pdcp_data_ind_queue_item;
#define PDCP_DATA_IND_QUEUE_SIZE 10000
typedef struct {
pdcp_data_ind_queue_item q[PDCP_DATA_IND_QUEUE_SIZE];
volatile int start;
volatile int length;
pthread_mutex_t m;
pthread_cond_t c;
} pdcp_data_ind_queue;
static pdcp_data_ind_queue pq;
static void do_pdcp_data_ind(
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t *const sdu_buffer)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
if (ctxt_pP->module_id != 0 ||
//ctxt_pP->enb_flag != 1 ||
ctxt_pP->instance != 0 ||
ctxt_pP->eNB_index != 0 ||
ctxt_pP->configured != 1 ||
ctxt_pP->brOption != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (ctxt_pP->enb_flag)
T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(rnti),
T_INT(rb_id), T_INT(sdu_buffer_size));
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
if (srb_flagP == 1) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > 5)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
} else {
LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n",
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
exit(1);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
free_mem_block(sdu_buffer, __FUNCTION__);
}
static void *pdcp_data_ind_thread(void *_)
{
int i;
pthread_setname_np(pthread_self(), "PDCP data ind");
while (1) {
if (pthread_mutex_lock(&pq.m) != 0) abort();
while (pq.length == 0)
if (pthread_cond_wait(&pq.c, &pq.m) != 0) abort();
i = pq.start;
if (pthread_mutex_unlock(&pq.m) != 0) abort();
do_pdcp_data_ind(&pq.q[i].ctxt_pP,
pq.q[i].srb_flagP,
pq.q[i].MBMS_flagP,
pq.q[i].rb_id,
pq.q[i].sdu_buffer_size,
pq.q[i].sdu_buffer);
if (pthread_mutex_lock(&pq.m) != 0) abort();
pq.length--;
pq.start = (pq.start + 1) % PDCP_DATA_IND_QUEUE_SIZE;
if (pthread_cond_signal(&pq.c) != 0) abort();
if (pthread_mutex_unlock(&pq.m) != 0) abort();
}
}
static void init_nr_pdcp_data_ind_queue(void)
{
pthread_t t;
pthread_mutex_init(&pq.m, NULL);
pthread_cond_init(&pq.c, NULL);
if (pthread_create(&t, NULL, pdcp_data_ind_thread, NULL) != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
static void enqueue_pdcp_data_ind(
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t *const sdu_buffer)
{
int i;
int logged = 0;
if (pthread_mutex_lock(&pq.m) != 0) abort();
while (pq.length == PDCP_DATA_IND_QUEUE_SIZE) {
if (!logged) {
logged = 1;
LOG_W(PDCP, "%s: pdcp_data_ind queue is full\n", __FUNCTION__);
}
if (pthread_cond_wait(&pq.c, &pq.m) != 0) abort();
}
i = (pq.start + pq.length) % PDCP_DATA_IND_QUEUE_SIZE;
pq.length++;
pq.q[i].ctxt_pP = *ctxt_pP;
pq.q[i].srb_flagP = srb_flagP;
pq.q[i].MBMS_flagP = MBMS_flagP;
pq.q[i].rb_id = rb_id;
pq.q[i].sdu_buffer_size = sdu_buffer_size;
pq.q[i].sdu_buffer = sdu_buffer;
if (pthread_cond_signal(&pq.c) != 0) abort();
if (pthread_mutex_unlock(&pq.m) != 0) abort();
}
boolean_t pdcp_data_ind(
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t *const sdu_buffer)
{
enqueue_pdcp_data_ind(ctxt_pP,
srb_flagP,
MBMS_flagP,
rb_id,
sdu_buffer_size,
sdu_buffer);
return true;
}
/****************************************************************************/
/* pdcp_data_ind thread - end */
/****************************************************************************/
/****************************************************************************/
/* hacks to be cleaned up at some point - begin */
/****************************************************************************/
......@@ -375,6 +551,7 @@ void pdcp_layer_init(void)
init_nr_rlc_data_req_queue();
}
init_nr_pdcp_data_ind_queue();
nr_pdcp_init_timer_thread(nr_pdcp_ue_manager);
}
......@@ -639,62 +816,6 @@ srb_found:
}
}
boolean_t pdcp_data_ind(
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t *const sdu_buffer)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
if (ctxt_pP->module_id != 0 ||
//ctxt_pP->enb_flag != 1 ||
ctxt_pP->instance != 0 ||
ctxt_pP->eNB_index != 0 ||
ctxt_pP->configured != 1 ||
ctxt_pP->brOption != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (ctxt_pP->enb_flag)
T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(rnti),
T_INT(rb_id), T_INT(sdu_buffer_size));
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
if (srb_flagP == 1) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > 5)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
} else {
LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n",
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
exit(1);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
free_mem_block(sdu_buffer, __FUNCTION__);
return 1;
}
void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
{
MessageDef *msg_p;
......
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