From a48c36582ffa93f38b2b9cd18b16b4b1e3e831ca Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Mon, 27 Aug 2018 17:46:03 +0200
Subject: [PATCH] bugfix: fix threading in the UE

Various problems were found with the basic simulator.

Variables used by various threads for synchronization need to
be initialized properly. That is before the various threads
start using them.

This goes for:
- UE->is_synchronized
- UE->proc.instance_cnt_synch
- UE->proc.instance_cnt_rxtx

The function "UE->rfdevice.trx_start_func" was called in
"UE_thread_synch" but should be called in "UE_thread" because
"UE_thread" is the one that calls "UE->rfdevice.trx_read_func"
and there is no guaranty that the call to "UE->rfdevice.trx_start_func"
is done before as it has to (it's in another thread).

And finally "pthread_cond_signal(&proc->cond_rxtx)" was called twice,
which may not be a problem but was certainly not intended. Plus
removing one call simplifies the code by removing some "if" logic,
which is a good thing per se.

This commit was not tested with a real UE and may thus introduce some
issues. Hopefully not!
---
 targets/RT/USER/lte-ue.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index fbf0eff1cd..66107d79a4 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -446,7 +446,6 @@ static void *UE_thread_synch(void *arg)
   int freq_offset=0;
   char threadname[128];
 
-  UE->is_synchronized = 0;
   printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
 
   cpu_set_t cpuset;
@@ -522,11 +521,6 @@ static void *UE_thread_synch(void *arg)
 
   printf("Started device, unlocked sync_mutex (UE_sync_thread)\n");
 
-  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
-    LOG_E(HW,"Could not start the device\n");
-    oai_exit=1;
-  }
-
   while (oai_exit==0) {
     AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
     while (UE->proc.instance_cnt_synch < 0)
@@ -755,7 +749,6 @@ static void *UE_thread_rxn_txnp4(void *arg) {
   UE_rxtx_proc_t *proc = rtd->proc;
   PHY_VARS_UE    *UE   = rtd->UE;
 
-  proc->instance_cnt_rxtx=-1;
   proc->subframe_rx=proc->sub_frame_start;
 
   char threadname[256];
@@ -1457,6 +1450,10 @@ void *UE_thread(void *arg) {
   int sub_frame=-1;
   //int cumulated_shift=0;
 
+  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
+    LOG_E(HW,"Could not start the device\n");
+    oai_exit=1;
+  }
 
   while (!oai_exit) {
 #if BASIC_SIMULATOR
@@ -1662,12 +1659,7 @@ void *UE_thread(void *arg) {
 
                     proc->instance_cnt_rxtx++;
                     LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
-                    if (proc->instance_cnt_rxtx == 0) {
-                      if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
-                        LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
-                        exit_fun("nothing to add");
-                      }
-                    } else {
+                    if (proc->instance_cnt_rxtx != 0) {
                       LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
                       if (proc->instance_cnt_rxtx > 2)
                         exit_fun("instance_cnt_rxtx > 2");
@@ -1718,6 +1710,8 @@ void init_UE_threads(int inst) {
 
   pthread_mutex_init(&UE->proc.mutex_synch,NULL);
   pthread_cond_init(&UE->proc.cond_synch,NULL);
+  UE->proc.instance_cnt_synch = -1;
+  UE->is_synchronized = 0;
 
   // the threads are not yet active, therefore access is allowed without locking
   int nb_threads=RX_NB_TH;
@@ -1729,6 +1723,7 @@ void init_UE_threads(int inst) {
 
     pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
     pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
+    UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1;
     UE->proc.proc_rxtx[i].sub_frame_start=i;
     UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
     printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
-- 
GitLab