From 77c7fe5b871348ff137651a9c6ae3c08bc3b56c1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 Dec 2020 17:02:34 +0100 Subject: [PATCH] Create more generic NR_list_t with helper functions --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 102 +++++++++++++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 4 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 11 +- openair2/LAYER2/NR_MAC_gNB/main.c | 3 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 20 ++-- 7 files changed, 110 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 282c6a3b49..0d5b581a00 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -512,7 +512,7 @@ void nr_schedule_ue_spec(module_id_t module_id, nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - NR_UE_list_t *UE_list = &UE_info->list; + NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index c49ae10ca2..05f7890dff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1442,35 +1442,105 @@ int extract_length(int startSymbolAndLength) { /* * Dump the UL or DL UE_info into LOG_T(MAC) */ -void dump_nr_ue_list(NR_UE_list_t *listP) { +void dump_nr_list(NR_list_t *listP) +{ for (int j = listP->head; j >= 0; j = listP->next[j]) - LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]); + LOG_T(MAC, "NR list node %d => %d\n", j, listP->next[j]); } /* - * Add a UE to NR_UE_list listP + * Create a new NR_list */ -inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) { +void create_nr_list(NR_list_t *list, int len) +{ + list->head = -1; + list->next = calloc(len, sizeof(*list->next)); + AssertFatal(list, "cannot calloc() memory for NR_list_t->next\n"); + for (int i = 0; i < len; ++i) + list->next[i] = -1; + list->tail = -1; + list->len = len; +} + +/* + * Destroy an NR_list + */ +void destroy_nr_list(NR_list_t *list) +{ + free(list->next); +} + +/* + * Add an ID to an NR_list at the end, traversing the whole list. Note: + * add_tail_nr_list() is a faster alternative, but this implementation ensures + * we do not add an existing ID. + */ +void add_nr_list(NR_list_t *listP, int id) +{ int *cur = &listP->head; while (*cur >= 0) { - AssertFatal(*cur != UE_id, "UE_id %d already in NR_UE_list!\n", UE_id); + AssertFatal(*cur != id, "id %d already in NR_UE_list!\n", id); cur = &listP->next[*cur]; } - *cur = UE_id; + *cur = id; + if (listP->next[id] < 0) + listP->tail = id; } /* - * Remove a UE from NR_UE_list listP + * Remove an ID from an NR_list */ -static inline void remove_nr_ue_list(NR_UE_list_t *listP, int UE_id) { +void remove_nr_list(NR_list_t *listP, int id) +{ int *cur = &listP->head; - while (*cur != -1 && *cur != UE_id) + int *prev = &listP->head; + while (*cur != -1 && *cur != id) { + prev = cur; cur = &listP->next[*cur]; - AssertFatal(*cur != -1, "UE %d not found in UE_list\n", UE_id); + } + AssertFatal(*cur != -1, "ID %d not found in UE_list\n", id); int *next = &listP->next[*cur]; *cur = listP->next[*cur]; *next = -1; - return; + listP->tail = *prev >= 0 && listP->next[*prev] >= 0 ? listP->tail : *prev; +} + +/* + * Add an ID to the tail of the NR_list in O(1). Note that there is + * corresponding remove_tail_nr_list(), as we cannot set the tail backwards and + * therefore need to go through the whole list (use remove_nr_list()) + */ +void add_tail_nr_list(NR_list_t *listP, int id) +{ + int *last = listP->tail < 0 ? &listP->head : &listP->next[listP->tail]; + *last = id; + listP->next[id] = -1; + listP->tail = id; +} + +/* + * Add an ID to the front of the NR_list in O(1) + */ +void add_front_nr_list(NR_list_t *listP, int id) +{ + const int ohead = listP->head; + listP->head = id; + listP->next[id] = ohead; + if (listP->tail < 0) + listP->tail = id; +} + +/* + * Remove an ID from the front of the NR_list in O(1) + */ +void remove_front_nr_list(NR_list_t *listP) +{ + AssertFatal(listP->head >= 0, "Nothing to remove\n"); + const int ohead = listP->head; + listP->head = listP->next[ohead]; + listP->next[ohead] = -1; + if (listP->head < 0) + listP->tail = -1; } int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) @@ -1536,7 +1606,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ mod_idP, rntiP, UE_info->num_UEs); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { if (UE_info->active[i]) @@ -1546,7 +1616,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ UE_info->num_UEs++; UE_info->active[UE_id] = true; UE_info->rnti[UE_id] = rntiP; - add_nr_ue_list(&UE_info->list, UE_id); + add_nr_list(&UE_info->list, UE_id); set_Y(UE_info->Y[UE_id], rntiP); memset((void *) &UE_info->UE_sched_ctrl[UE_id], 0, @@ -1561,13 +1631,13 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ mod_idP, UE_id, rntiP); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); return (UE_id); } // printf("MAC: cannot add new UE for rnti %x\n", rntiP); LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n"); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); return -1; } @@ -1595,7 +1665,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) UE_info->num_UEs--; UE_info->active[UE_id] = FALSE; UE_info->rnti[UE_id] = 0; - remove_nr_ue_list(&UE_info->list, UE_id); + remove_nr_list(&UE_info->list, UE_id); memset((void *) &UE_info->UE_sched_ctrl[UE_id], 0, sizeof(NR_UE_sched_ctrl_t)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index d10a4ceca2..4eab78a1f2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -83,7 +83,7 @@ void nr_schedule_pucch(int Mod_idP, frame_t frameP, sub_frame_t slotP) { NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - const NR_UE_list_t *UE_list = &UE_info->list; + const NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; @@ -198,7 +198,7 @@ void nr_csi_meas_reporting(int Mod_idP, const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - NR_UE_list_t *UE_list = &UE_info->list; + NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { const NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 387365f19a..d0476cbe18 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -607,7 +607,7 @@ void nr_schedule_ulsch(module_id_t module_id, NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; - const NR_UE_list_t *UE_list = &UE_info->list; + const NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 8a314d9b29..ded327880f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -293,8 +293,15 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); -void dump_nr_ue_list(NR_UE_list_t *listP); -void add_nr_ue_list(NR_UE_list_t *listP, int UE_id); +/* Functions to manage an NR_list_t */ +void dump_nr_list(NR_list_t *listP); +void create_nr_list(NR_list_t *listP, int len); +void destroy_nr_list(NR_list_t *list); +void add_nr_list(NR_list_t *listP, int id); +void remove_nr_list(NR_list_t *listP, int id); +void add_tail_nr_list(NR_list_t *listP, int id); +void add_front_nr_list(NR_list_t *listP, int id); +void remove_front_nr_list(NR_list_t *listP); int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 78a0dbb649..d6330eb805 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -113,9 +113,8 @@ void mac_top_init_gNB(void) UE_info = &nrmac->UE_info; UE_info->num_UEs = 0; - UE_info->list.head = -1; + create_nr_list(&UE_info->list, MAX_MOBILES_PER_GNB); for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) { - UE_info->list.next[list_el] = -1; UE_info->active[list_el] = false; for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) { UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 52bc0b5952..46b7aa8b4c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -79,6 +79,15 @@ #define NR_NB_RA_PROC_MAX 4 #define MAX_NUM_OF_SSB 64 +/*! \brief NR_list_t is a "list" (of users, HARQ processes, slices, ...). + * Especially useful in the scheduler and to keep "classes" of users. */ +typedef struct { + int head; + int *next; + int tail; + int len; +} NR_list_t; + typedef enum { RA_IDLE = 0, Msg2 = 1, @@ -447,15 +456,6 @@ typedef struct { } NR_mac_stats_t; - -/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in - * the scheduler and to keep "classes" of users. */ -typedef struct { - int head; - int next[MAX_MOBILES_PER_GNB]; -} NR_UE_list_t; - - /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ #define MAX_CSI_REPORTCONFIG 48 typedef struct { @@ -463,7 +463,7 @@ typedef struct { nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; - NR_UE_list_t list; + NR_list_t list; int num_UEs; bool active[MAX_MOBILES_PER_GNB];