From 6fcc4f59709708fc4f6862b9eb87264d1015a7fe Mon Sep 17 00:00:00 2001
From: Robert Schmidt <robert.schmidt@eurecom.fr>
Date: Thu, 18 Jun 2020 17:32:01 +0200
Subject: [PATCH] Format to dynamically handle UL SCHED

---
 openair2/LAYER2/MAC/mac.h           | 16 +++++-
 openair2/LAYER2/MAC/main.c          |  5 ++
 openair2/LAYER2/MAC/pre_processor.c | 79 ++++++++++++++++++-----------
 3 files changed, 70 insertions(+), 30 deletions(-)

diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 0264951683..09585fae55 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -1276,7 +1276,7 @@ typedef struct {
 
 /**
  * definition of a scheduling algorithm implementation used in the
- * default scheduler
+ * default DL scheduler
  */
 typedef struct {
   char *name;
@@ -1287,6 +1287,19 @@ typedef struct {
   void *data;
 } default_sched_dl_algo_t;
 
+/**
+ * definition of a scheduling algorithm implementation used in the
+ * default UL scheduler
+ */
+typedef struct {
+  char *name;
+  void *(*setup)(void);
+  void (*unset)(void **);
+  int (*run)(
+      module_id_t, int, int, int, int, int, UE_list_t *, int, int, contig_rbs_t *, void *);
+  void *data;
+} default_sched_ul_algo_t;
+
 /*! \brief eNB common channels */
 typedef struct {
   int physCellId;
@@ -1447,6 +1460,7 @@ typedef struct eNB_MAC_INST_s {
   SCHEDULER_MODES scheduler_mode;
   /// scheduling algorithm used in default scheduler
   default_sched_dl_algo_t dl_algo;
+  default_sched_ul_algo_t ul_algo;
 
   int32_t puSch10xSnr;
   int32_t puCch10xSnr;
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 39e342cba0..294eb12159 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -133,6 +133,11 @@ void mac_top_init_eNB(void)
     AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s);
     mac[i]->dl_algo = *(default_sched_dl_algo_t *) d;
     mac[i]->dl_algo.data = mac[i]->dl_algo.setup();
+    s = "round_robin_ul";
+    d = dlsym(NULL, s);
+    AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s);
+    mac[i]->ul_algo = *(default_sched_ul_algo_t *) d;
+    mac[i]->ul_algo.data = mac[i]->ul_algo.setup();
     init_UE_info(&mac[i]->UE_info);
     init_slice_info(&mac[i]->slice_info);
   }
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 436ec2435e..07bbed22c3 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -830,17 +830,28 @@ int pp_find_rb_table_index(int approximate) {
   return p + 1;
 }
 
-int g_start_ue_ul = -1;
-int round_robin_ul(module_id_t Mod_id,
-                   int CC_id,
-                   int frame,
-                   int subframe,
-                   int sched_frame,
-                   int sched_subframe,
-                   UE_list_t *UE_list,
-                   int max_num_ue,
-                   int num_contig_rb,
-                   contig_rbs_t *rbs) {
+void *rr_ul_setup(void) {
+  void *data = malloc(sizeof(int));
+  *(int *) data = 0;
+  AssertFatal(data, "could not allocate data in %s()\n", __func__);
+  return data;
+}
+void rr_ul_unset(void **data) {
+  if (*data)
+    free(*data);
+  *data = NULL;
+}
+int rr_ul_run(module_id_t Mod_id,
+              int CC_id,
+              int frame,
+              int subframe,
+              int sched_frame,
+              int sched_subframe,
+              UE_list_t *UE_list,
+              int max_num_ue,
+              int num_contig_rb,
+              contig_rbs_t *rbs,
+              void *data) {
   AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n");
   UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
   const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length;
@@ -980,9 +991,10 @@ int round_robin_ul(module_id_t Mod_id,
     end = la > lb ? 2 : -1;
   }
 
-  if (g_start_ue_ul == -1)
-    g_start_ue_ul = UE_list->head;
-  int sUE_id = g_start_ue_ul;
+  int *start_ue = data;
+  if (*start_ue == -1)
+    *start_ue = UE_list->head;
+  int sUE_id = *start_ue;
   int rb_idx_given[MAX_MOBILES_PER_ENB];
   memset(rb_idx_given, 0, sizeof(rb_idx_given));
 
@@ -1061,10 +1073,17 @@ int round_robin_ul(module_id_t Mod_id,
   }
 
   /* just start with the next UE next time */
-  g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul);
+  *start_ue = next_ue_list_looped(UE_list, *start_ue);
 
   return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0);
 }
+default_sched_ul_algo_t round_robin_ul = {
+  .name  = "round_robin_ul",
+  .setup = rr_ul_setup,
+  .unset = rr_ul_unset,
+  .run   = rr_ul_run,
+  .data  = NULL
+};
 
 void ulsch_scheduler_pre_processor(module_id_t Mod_id,
                                    int CC_id,
@@ -1072,9 +1091,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
                                    sub_frame_t subframeP,
                                    int sched_frameP,
                                    unsigned char sched_subframeP) {
-  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
-  const int N_RB_UL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].ul_Bandwidth);
-  COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+  eNB_MAC_INST *mac = RC.mac[Mod_id];
+  UE_info_t *UE_info = &mac->UE_info;
+  const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth);
+  COMMON_channels_t *cc = &mac->common_channels[CC_id];
 
   UE_list_t UE_to_sched;
   UE_to_sched.head = -1;
@@ -1131,16 +1151,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
     }
   }
 
-  round_robin_ul(Mod_id,
-                 CC_id,
-                 frameP,
-                 subframeP,
-                 sched_frameP,
-                 sched_subframeP,
-                 &UE_to_sched,
-                 4, // max_num_ue
-                 n_contig,
-                 rbs);
+  mac->ul_algo.run(Mod_id,
+                   CC_id,
+                   frameP,
+                   subframeP,
+                   sched_frameP,
+                   sched_subframeP,
+                   &UE_to_sched,
+                   4, // max_num_ue
+                   n_contig,
+                   rbs,
+                   mac->ul_algo.data);
 
   // the following block is meant for validation of the pre-processor to check
   // whether all UE allocations are non-overlapping and is not necessary for
@@ -1159,7 +1180,7 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
       continue;
 
     print = 1;
-    uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id],
+    uint8_t harq_pid = subframe2harqpid(&mac->common_channels[CC_id],
                                         sched_frameP, sched_subframeP);
     LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n",
           frameP,
-- 
2.26.2