lte-enb.c 45.6 KB
Newer Older
1
2
3
4
5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21
22
23
24
25
26
27
28
29
30
31

/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
 * \date 2012
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
 * \note
 * \warning
 */
32

knopp's avatar
knopp committed
33
34
#define _GNU_SOURCE
#include <pthread.h>
35

36
37
#include "time_utils.h"

38
39
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all

40
41
#include "rt_wrapper.h"

42
#include "assertions.h"
43

44
45
46
47
48
49
50
51
52
53
54

#include "PHY/types.h"

#include "PHY/defs.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all

#include "../../ARCH/COMMON/common_lib.h"

//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all

55
#include "PHY/LTE_TRANSPORT/if4_tools.h"
56
#include "PHY/LTE_TRANSPORT/if5_tools.h"
57

58
59
60
61
62
63
64
65
66
67
68
#include "PHY/extern.h"
#include "SCHED/extern.h"
#include "LAYER2/MAC/extern.h"

#include "../../SIMU/USER/init_lte.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/proto.h"
#include "RRC/LITE/extern.h"
#include "PHY_INTERFACE/extern.h"
69
#include "PHY_INTERFACE/defs.h"
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
//#include "PHY/TOOLS/time_meas.h"

#ifndef OPENAIR2
#include "UTIL/OTG/otg_extern.h"
#endif

#if defined(ENABLE_ITTI)
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
# endif
#endif

Rohit Gupta's avatar
bugfix    
Rohit Gupta committed
96
97
#include "T.h"

98
99
100
101
102
103
104
105
106
107
//#define DEBUG_THREADS 1

//#define USRP_DEBUG 1
struct timing_info_t {
  //unsigned int frame, hw_slot, last_slot, next_slot;
  RTIME time_min, time_max, time_avg, time_last, time_now;
  //unsigned int mbox0, mbox1, mbox2, mbox_target;
  unsigned int n_samples;
} timing_info;

108
109
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
110

knopp's avatar
knopp committed
111

112
113
114
115
116
117
118
119
#if defined(ENABLE_ITTI)
extern volatile int             start_eNB;
extern volatile int             start_UE;
#endif
extern volatile int                    oai_exit;

extern openair0_config_t openair0_cfg[MAX_CARDS];

Cedric Roux's avatar
Cedric Roux committed
120
extern int transmission_mode;
121

122
123
extern int oaisim_flag;

124
125
uint16_t sf_ahead=4;

126
//pthread_t                       main_eNB_thread;
127
128
129

time_stats_t softmodem_stats_mt; // main thread
time_stats_t softmodem_stats_hw; //  hw acquisition
knopp's avatar
knopp committed
130
time_stats_t softmodem_stats_rxtx_sf; // total tx time
131
time_stats_t nfapi_meas; // total tx time
132
time_stats_t softmodem_stats_rx_sf; // total rx time
133
134
135
136
137
138
139
140
141

/* mutex, cond and variable to serialize phy proc TX calls
 * (this mechanism may be relaxed in the future for better
 * performances)
 */
static struct {
  pthread_mutex_t  mutex_phy_proc_tx;
  pthread_cond_t   cond_phy_proc_tx;
  volatile uint8_t phy_proc_CC_id;
142
} sync_phy_proc;
143

144
145
extern double cpuf;

146
147
void exit_fun(const char* s);

148
void init_eNB(int,int);
149
void stop_eNB(int nb_inst);
150

151
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
152
int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc);
153
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
154
155
156
#ifdef Rel14
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#endif
Wang Tsu-Han's avatar
Wang Tsu-Han committed
157
extern int codingw;
158

159
160
161
162
163
164
extern uint8_t nfapi_mode;
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);

//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
knopp's avatar
knopp committed
165

166

knopp's avatar
knopp committed
167
168
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
  start_meas(&softmodem_stats_rxtx_sf);
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  // *******************************************************************

  if (nfapi_mode == 1) {

    // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
    uint16_t frame = proc->frame_rx;
    uint16_t subframe = proc->subframe_rx;

    //add_subframe(&frame, &subframe, 4);

    //oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
    //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
    start_meas(&nfapi_meas);
    oai_subframe_ind(frame, subframe);
    stop_meas(&nfapi_meas);

    if (eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
        eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
        eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
        eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
        eNB->UL_INFO.cqi_ind.number_of_cqis
       ) {
      LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf),   eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf),  eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
          eNB->UL_INFO.cqi_ind.number_of_cqis, 
          proc->frame_rx, proc->subframe_rx, 
      proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols);
    }
  }

  if (nfapi_mode == 1 && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) {
    LOG_E(PHY, "eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0");
    return 0;
  }

knopp's avatar
knopp committed
208
209
  // ****************************************
  // Common RX procedures subframe n
210

Cedric Roux's avatar
Cedric Roux committed
211
212
  T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));

213
  // if this is IF5 or 3GPP_eNB
214
  if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
215
216
217
218
219
    wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#ifdef Rel14
    wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#endif
  }
220

knopp's avatar
knopp committed
221
  // UE-specific RX processing for subframe n
222
223
224
  if (nfapi_mode == 0 || nfapi_mode == 1) {
    phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
  }
225
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 );
226

227
228
229
230
231
232
  if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) {
    LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx);
    return(-1);
  }
  if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0)  return(-1);

233
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
234

235
236
237
238
  eNB->UL_INFO.frame     = proc->frame_rx;
  eNB->UL_INFO.subframe  = proc->subframe_rx;
  eNB->UL_INFO.module_id = eNB->Mod_id;
  eNB->UL_INFO.CC_id     = eNB->CC_id;
239

240
  eNB->if_inst->UL_indication(&eNB->UL_INFO);
241

242
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
knopp's avatar
knopp committed
243
  
244
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
245
  if(oai_exit) return(-1);
246
  if(get_nprocs() <= 4)    phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
knopp's avatar
knopp committed
247
248
249


  stop_meas( &softmodem_stats_rxtx_sf );
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx);

#if 0
  LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
      softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
      TICK_TO_US(eNB->phy_proc),
      TICK_TO_US(eNB->phy_proc_tx),
      TICK_TO_US(eNB->phy_proc_rx),
      TICK_TO_US(eNB->rx_prach),
      TICK_TO_US(eNB->ofdm_mod_stats),
      softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
  LOG_D(PHY,
    "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
      TICK_TO_US(eNB->dlsch_encoding_stats),
      TICK_TO_US(eNB->dlsch_modulation_stats),
      TICK_TO_US(eNB->dlsch_scrambling_stats),
      TICK_TO_US(eNB->dlsch_rate_matching_stats),
      TICK_TO_US(eNB->dlsch_turbo_encoding_stats),
      TICK_TO_US(eNB->dlsch_interleaving_stats),
      TICK_TO_US(eNB->rx_dft_stats));

  LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
      TICK_TO_US(eNB->ulsch_channel_estimation_stats),
      TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats),
      TICK_TO_US(eNB->ulsch_decoding_stats),
      TICK_TO_US(eNB->ulsch_demodulation_stats),
      TICK_TO_US(eNB->ulsch_rate_unmatching_stats));

  LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
      TICK_TO_US(eNB->ulsch_turbo_decoding_stats),
      TICK_TO_US(eNB->ulsch_deinterleaving_stats),
      TICK_TO_US(eNB->ulsch_demultiplexing_stats),
      TICK_TO_US(eNB->ulsch_llr_stats),
      TICK_TO_US(eNB->ulsch_tc_init_stats));
  LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", 
      TICK_TO_US(eNB->ulsch_tc_alpha_stats),
      TICK_TO_US(eNB->ulsch_tc_beta_stats),
      TICK_TO_US(eNB->ulsch_tc_gamma_stats),
      TICK_TO_US(eNB->ulsch_tc_ext_stats),
      TICK_TO_US(eNB->ulsch_tc_intl1_stats),
      TICK_TO_US(eNB->ulsch_tc_intl2_stats)
      );
#endif
knopp's avatar
knopp committed
294
295
296
297
  
  return(0);
}

298

299
300
301
302
303
304
305
static void* tx_thread(void* param) {

  eNB_proc_t *eNB_proc  = (eNB_proc_t*)param;
  eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1];
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
  
  char thread_name[100];
306
  sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
307
  thread_top_init(thread_name,1,470000,500000,500000);
308
  
309
  //wait_sync("tx_thread");
Eurecom's avatar
Eurecom committed
310
  
311
  while (!oai_exit) {
312
    
313
314
315
316
317
318
319
320

    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
    if (oai_exit) break;    
    // *****************************************
    // TX processing for subframe n+4
    // run PHY TX procedures the one after the other for all CCs to avoid race conditions
    // (may be relaxed in the future for performance reasons)
    // *****************************************
321
322
323
324
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_ENB,proc->subframe_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_ENB,proc->subframe_rx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx);
325
326
    
    phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
327
    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
328
	
329
330
331
332
333
334
335
336
    pthread_mutex_lock( &proc->mutex_rxtx );
    proc->pipe_ready++;
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
    }
    pthread_mutex_unlock( &proc->mutex_rxtx );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
337
    wakeup_txfh(proc,eNB_proc->ru_proc);
338
339
340
341
342
  }

  return 0;
}

343
/*!
knopp's avatar
knopp committed
344
 * \brief The RX UE-specific and TX thread of eNB.
345
346
347
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
348

Sandeep Kumar's avatar
Sandeep Kumar committed
349
350
static void* eNB_thread_rxtx( void* param ) {

knopp's avatar
knopp committed
351
  static int eNB_thread_rxtx_status;
352
353
  eNB_proc_t *eNB_proc  = (eNB_proc_t*)param;
  eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[0];
354
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
355
  //RU_proc_t *ru_proc = NULL;
356

knopp's avatar
knopp committed
357
358
  char thread_name[100];

359
360
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
361

362
  // set default return value
knopp's avatar
knopp committed
363
  eNB_thread_rxtx_status = 0;
364
365


knopp's avatar
knopp committed
366
  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
367
368
369
  thread_top_init(thread_name,1,470000,500000,500000);
  pthread_setname_np( pthread_self(),"rxtx processing");
  LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid));
370

371

372

373
  while (!oai_exit) {
374
375
    
    
knopp's avatar
knopp committed
376
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
377
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
378

knopp's avatar
knopp committed
379
    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
380

381
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
knopp's avatar
knopp committed
382
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
383
384
385
386
387
388
   
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,proc->frame_rx);
 
389

390
391
    if (oai_exit) break;

392
    if (eNB->CC_id==0)
393
    {
394
      if (rxtx(eNB,proc,thread_name) < 0) break;
395
    }
396
397

    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    pthread_mutex_lock( &proc->mutex_rxtx );
    proc->pipe_ready++;
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
    }
    pthread_mutex_unlock( &proc->mutex_rxtx );
    if(get_nprocs() >= 8)      wakeup_tx(eNB,eNB->proc.ru_proc);
    else if(get_nprocs() > 4)
    {  
      phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
      wakeup_txfh(proc,eNB->proc.ru_proc);
    }
412

knopp's avatar
knopp committed
413
  } // while !oai_exit
414

knopp's avatar
knopp committed
415
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
416

417
  LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n");
418

knopp's avatar
knopp committed
419
420
  eNB_thread_rxtx_status = 0;
  return &eNB_thread_rxtx_status;
421
422
}

423

knopp's avatar
knopp committed
424
425
#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
// Wait for eNB application initialization to be complete (eNB registration to MME)
Sandeep Kumar's avatar
Sandeep Kumar committed
426
427
static void wait_system_ready (char *message, volatile int *start_flag) {
  
428
  static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
Sandeep Kumar's avatar
Sandeep Kumar committed
429
			      " ....", "  ...", "   ..", "    .", "     "};
430
431
432
433
434
435
436
  int i = 0;
  
  while ((!oai_exit) && (*start_flag == 0)) {
    LOG_N(EMU, message, indicator[i]);
    fflush(stdout);
    i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
    usleep(200000);
437
  }
438
439
  
  LOG_D(EMU,"\n");
440
441
}
#endif
442

knopp's avatar
knopp committed
443
444


knopp's avatar
knopp committed
445

knopp's avatar
knopp committed
446

Wang Tsu-Han's avatar
Wang Tsu-Han committed
447
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru)
Cedric Roux's avatar
Cedric Roux committed
448
{
449
450
  eNB_proc_t *proc           = &eNB->proc;
  eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
knopp's avatar
knopp committed
451
452
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
  RU_proc_t *ru_proc=&ru->proc;
453

454
455
  proc->frame_rx    = frame_rx;
  proc->subframe_rx = subframe_rx;
knopp's avatar
knopp committed
456

Cedric Roux's avatar
Cedric Roux committed
457
  if (!oai_exit) {
458
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
knopp's avatar
knopp committed
459

knopp's avatar
knopp committed
460
461
462
463
464
    proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
    proc_rxtx->frame_rx     = ru_proc->frame_rx;
    proc_rxtx->subframe_rx  = ru_proc->subframe_rx;
    proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
    proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + sf_ahead)%10;
knopp's avatar
knopp committed
465

466
    if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
knopp's avatar
knopp committed
467
468
469
    ru_proc->timestamp_tx = proc_rxtx->timestamp_tx;
    ru_proc->subframe_tx  = proc_rxtx->subframe_tx;
    ru_proc->frame_tx     = proc_rxtx->frame_tx;
470
  }
knopp's avatar
knopp committed
471
472
}

Wang Tsu-Han's avatar
Wang Tsu-Han committed
473
int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) {
474
475
476
477
  
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
478

479
  
480
481
482
  if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) {
    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx);
    return(-1);
483
  }
484
485
  if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1);
  
486
  if (ru_proc->instance_cnt_eNBs == 0) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
487
    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx);
488
489
    return(-1);
  }
490
491
492
493
494
495
496
  if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
    exit_fun( "error locking mutex_eNB" );
    return(-1);
  }

    ++ru_proc->instance_cnt_eNBs;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
497
498
499
    ru_proc->timestamp_tx = proc->timestamp_tx;
    ru_proc->subframe_tx  = proc->subframe_tx;
    ru_proc->frame_tx     = proc->frame_tx;
500
501
502
503
504
505
506
507
508
509
510
511
512
  
  // the thread can now be woken up
  if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
  pthread_mutex_unlock( &ru_proc->mutex_eNBs );

  return(0);
}

513
514
515
516
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {

  eNB_proc_t *proc=&eNB->proc;

517
518
  eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
519
520
521
522
523
524

  
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
  
525
  
526
  
527
528
  if (proc_rxtx1->instance_cnt_rxtx == 0) {
    LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
529
530
531
    return(-1);
  }
  
532
533
  if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx );
534
    exit_fun( "error locking mutex_tx" );
535
536
537
    return(-1);
  }

538
  ++proc_rxtx1->instance_cnt_rxtx;
539
540

  
541
542
543
544
545
  proc_rxtx1->subframe_rx   = proc_rxtx0->subframe_rx;
  proc_rxtx1->frame_rx      = proc_rxtx0->frame_rx;
  proc_rxtx1->subframe_tx   = proc_rxtx0->subframe_tx;
  proc_rxtx1->frame_tx      = proc_rxtx0->frame_tx;
  proc_rxtx1->timestamp_tx  = proc_rxtx0->timestamp_tx;
546
547
  
  // the thread can now be woken up
548
  if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 0) {
549
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
550
551
552
553
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
554
  pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx );
555
556
557

  return(0);
}
knopp's avatar
knopp committed
558

559
560
561
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {

  eNB_proc_t *proc=&eNB->proc;
562
  RU_proc_t *ru_proc=&ru->proc;
563

564
  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
Wang Tsu-Han's avatar
Wang Tsu-Han committed
565
  //eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
566
  
567
568

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
569
570
571
572

  int i;
  struct timespec wait;
  
573
574
575
576
577
578
579
580
581
582
  pthread_mutex_lock(&proc->mutex_RU);
  for (i=0;i<eNB->num_RU;i++) {
    if (ru == eNB->RU_list[i]) {
      if ((proc->RU_mask&(1<<i)) > 0)
	LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
	      eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
      proc->RU_mask |= (1<<i);
    }
  }
  if (proc->RU_mask != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
583
    LOG_E(PHY,"Not all RUs have provided their info\n");
584
585
586
587
588
589
590
591
592
593
594
    pthread_mutex_unlock(&proc->mutex_RU);
    return(0);
  }
  else { // all RUs have provided their information so continue on and wakeup eNB processing
    proc->RU_mask = 0;
    pthread_mutex_unlock(&proc->mutex_RU);
  }




595
596
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
597

598
  
599
600
601
  if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) {
    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
    return(-1);
602
  }
603
604
  if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1);
  
605
606
  if (proc_rxtx0->instance_cnt_rxtx == 0) {
    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
607
608
609
    return(-1);
  }

Cedric Roux's avatar
Cedric Roux committed
610
  // wake up TX for subframe n+sf_ahead
611
  // lock the TX mutex and make sure the thread is ready
612
613
  if (pthread_mutex_timedlock(&proc_rxtx0->mutex_rxtx,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx0->subframe_rx&1,proc_rxtx0->instance_cnt_rxtx );
614
615
616
617
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }
  
618

619
  ++proc_rxtx0->instance_cnt_rxtx;
620
621
622
623
624
  
  // We have just received and processed the common part of a subframe, say n. 
  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
  // transmitted timestamp of the next TX slot (first).
  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, 
625
626
  // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
  // and proc->subframe_tx = proc->subframe_rx+sf_ahead
627
628
629
630
631
  proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
  proc_rxtx0->frame_rx     = ru_proc->frame_rx;
  proc_rxtx0->subframe_rx  = ru_proc->subframe_rx;
  proc_rxtx0->frame_tx     = (proc_rxtx0->subframe_rx > (9-sf_ahead)) ? (proc_rxtx0->frame_rx+1)&1023 : proc_rxtx0->frame_rx;
  proc_rxtx0->subframe_tx  = (proc_rxtx0->subframe_rx + sf_ahead)%10;
632

633
  // the thread can now be woken up
634
  if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) {
635
636
637
638
639
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
640
  pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx );
641
642
643
644

  return(0);
}

645
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
knopp's avatar
knopp committed
646
647
648

  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
649
  int i;
knopp's avatar
knopp committed
650

651
652
653
654
  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH);
    for (i=0;i<eNB->num_RU;i++) {
      if (ru == eNB->RU_list[i]) {
knopp's avatar
knopp committed
655
	LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
656
657
	if ((proc->RU_mask_prach&(1<<i)) > 0)
	  LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
658
		eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);
659
660
661
662
663
	proc->RU_mask_prach |= (1<<i);
      }
    }
    if (proc->RU_mask_prach != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
knopp's avatar
knopp committed
664
      return;
665
666
667
668
669
670
671
    }
    else { // all RUs have provided their information so continue on and wakeup eNB processing
      proc->RU_mask_prach = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
    }
  }
    
knopp's avatar
knopp committed
672
  // check if we have to detect PRACH first
673
  if (is_prach_subframe(fp,frame,subframe)>0) { 
674
    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
knopp's avatar
knopp committed
675
    if (proc->instance_cnt_prach == 0) {
676
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
knopp's avatar
knopp committed
677
678
679
680
681
682
683
684
685
686
687
688
      return;
    }
    
    // wake up thread for PRACH RX
    if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
      exit_fun( "error locking mutex_prach" );
      return;
    }
    
    ++proc->instance_cnt_prach;
    // set timing for prach thread
689
690
    proc->frame_prach = frame;
    proc->subframe_prach = subframe;
knopp's avatar
knopp committed
691
692
693
694
695
696
697
698
699
700
701
702
703
    
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_prach) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
    
    pthread_mutex_unlock( &proc->mutex_prach );
  }

}

704
705
706
707
708
709
710
711
712
713
714
#ifdef Rel14
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {

  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int i;

  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH_br);
    for (i=0;i<eNB->num_RU;i++) {
      if (ru == eNB->RU_list[i]) {
knopp's avatar
knopp committed
715
	LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH BR (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach_br,eNB->num_RU);
716
717
718
719
720
721
722
723
	if ((proc->RU_mask_prach_br&(1<<i)) > 0)
	  LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH BR) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
		eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach_br);
	proc->RU_mask_prach_br |= (1<<i);
      }
    }
    if (proc->RU_mask_prach_br != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
      pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
knopp's avatar
knopp committed
724
      return;
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
    }
    else { // all RUs have provided their information so continue on and wakeup eNB processing
      proc->RU_mask_prach_br = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
    }
  }
    
  // check if we have to detect PRACH first
  if (is_prach_subframe(fp,frame,subframe)>0) { 
    LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe);
    if (proc->instance_cnt_prach_br == 0) {
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe);
      return;
    }
    
    // wake up thread for PRACH RX
    if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br);
      exit_fun( "error locking mutex_prach" );
      return;
    }
    
    ++proc->instance_cnt_prach_br;
    // set timing for prach thread
    proc->frame_prach_br = frame;
    proc->subframe_prach_br = subframe;
    
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_prach_br) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index);
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
    
    pthread_mutex_unlock( &proc->mutex_prach_br );
  }

}
#endif

765
766
767
768
769
/*!
 * \brief The prach receive thread of eNB.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
Sandeep Kumar's avatar
Sandeep Kumar committed
770
static void* eNB_thread_prach( void* param ) {
771
772
  static int eNB_thread_prach_status;

773
774
775

  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;
Raymond Knopp's avatar
Raymond Knopp committed
776

777
778
779
  // set default return value
  eNB_thread_prach_status = 0;

Wang Tsu-Han's avatar
Wang Tsu-Han committed
780
  thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
781

782
  //wait_sync("eNB_thread_prach");
783

Sandeep Kumar's avatar
Sandeep Kumar committed
784
785
786
787
  while (!oai_exit) {
    
    if (oai_exit) break;

788
    
knopp's avatar
knopp committed
789
    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
knopp's avatar
knopp committed
790
791

    LOG_D(PHY,"Running eNB prach procedures\n");
792
793
794
795
796
    prach_procedures(eNB
#ifdef Rel14
		     ,0
#endif
		     );
797
    
knopp's avatar
knopp committed
798
    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
Sandeep Kumar's avatar
Sandeep Kumar committed
799
  }
800

knopp's avatar
knopp committed
801
  LOG_I(PHY, "Exiting eNB thread PRACH\n");
Raymond Knopp's avatar
Raymond Knopp committed
802

803
804
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
805
806
}

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
#ifdef Rel14
/*!
 * \brief The prach receive thread of eNB for BL/CE UEs.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
static void* eNB_thread_prach_br( void* param ) {
  static int eNB_thread_prach_status;


  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;

  // set default return value
  eNB_thread_prach_status = 0;

Wang Tsu-Han's avatar
Wang Tsu-Han committed
823
  thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844

  while (!oai_exit) {
    
    if (oai_exit) break;
    

    if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;

    LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n");
    prach_procedures(eNB,1);
    
    if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;
  }

  LOG_I(PHY, "Exiting eNB thread PRACH BR\n");

  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
}

#endif
knopp's avatar
knopp committed
845

knopp's avatar
knopp committed
846

847

Wang Tsu-Han's avatar
Wang Tsu-Han committed
848
extern void init_td_thread(PHY_VARS_eNB *);
Eurecom's avatar
Eurecom committed
849
extern void init_te_thread(PHY_VARS_eNB *);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
850
851
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
852
853
//////////////////////////////////////need to modified////////////////*****

854
static void* process_stats_thread(void* param) {
855
856
857

  PHY_VARS_eNB     *eNB      = (PHY_VARS_eNB*)param;

858
  wait_sync("process_stats_thread");
859
860
861
862
863

  while (!oai_exit) {
     sleep(1);
     if (opp_enabled == 1) {
       if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL);
864
865
       if (eNB->te)
       {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
866
         print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL);
867
         print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL);
868
         print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL);
869
         print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL);
870
871
         print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL);
         print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL);
872
873
874
875
         print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL);
         print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL);
	   }
       print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL);
876
877
878
879
880
     }
  }
  return(NULL);
}

881

882
void init_eNB_proc(int inst) {
Sandeep Kumar's avatar
Sandeep Kumar committed
883
  
Rohit Gupta's avatar
Rohit Gupta committed
884
  int i=0;
885
  int CC_id;
886
887
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
knopp's avatar
knopp committed
888
  eNB_rxtx_proc_t *proc_rxtx;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
889
  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
890
891
892
#ifdef Rel14
  pthread_attr_t *attr_prach_br=NULL;
#endif
knopp's avatar
knopp committed
893

894
895
  LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);

knopp's avatar
knopp committed
896
  for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
897
    eNB = RC.eNB[inst][CC_id];
laurent's avatar
small2    
laurent committed
898
#ifndef OCP_FRAMEWORK
899
    LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
laurent's avatar
small2    
laurent committed
900
#endif
901
    proc = &eNB->proc;
knopp's avatar
knopp committed
902

903
    proc_rxtx                      = proc->proc_rxtx;
904
905
    proc_rxtx[0].instance_cnt_rxtx = -1;
    proc_rxtx[1].instance_cnt_rxtx = -1;
906
907
    proc_rxtx[0].pipe_ready        = 0;
    proc_rxtx[1].pipe_ready        = 0;
908
    proc->instance_cnt_prach       = -1;
909
    proc->instance_cnt_asynch_rxtx = -1;
Eurecom's avatar
Eurecom committed
910
    proc->instance_cnt_synch       = -1;
911
    proc->CC_id                    = CC_id;    
912

knopp's avatar
knopp committed
913
914
    proc->first_rx=1;
    proc->first_tx=1;
915
916
    proc->RU_mask=0;
    proc->RU_mask_prach=0;
knopp's avatar
knopp committed
917

918
    pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
919
920
921
922
    pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
    pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
knopp's avatar
knopp committed
923
924
925

    pthread_mutex_init( &proc->mutex_prach, NULL);
    pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
926
927
    pthread_mutex_init( &proc->mutex_RU,NULL);
    pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
knopp's avatar
knopp committed
928

929
    pthread_cond_init( &proc->cond_prach, NULL);
930
    pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
931
932
933
934
935

    pthread_attr_init( &proc->attr_prach);
    pthread_attr_init( &proc->attr_asynch_rxtx);
    pthread_attr_init( &proc_rxtx[0].attr_rxtx);
    pthread_attr_init( &proc_rxtx[1].attr_rxtx);
936
937
938
939
940
941
942
943
#ifdef Rel14
    proc->instance_cnt_prach_br    = -1;
    proc->RU_mask_prach_br=0;
    pthread_mutex_init( &proc->mutex_prach_br, NULL);
    pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL);
    pthread_cond_init( &proc->cond_prach_br, NULL);
    pthread_attr_init( &proc->attr_prach_br);
#endif
944
#ifndef DEADLINE_SCHEDULER
knopp's avatar
knopp committed
945
946
947
    attr0       = &proc_rxtx[0].attr_rxtx;
    attr1       = &proc_rxtx[1].attr_rxtx;
    attr_prach  = &proc->attr_prach;
948
949
950
951
#ifdef Rel14
    attr_prach_br  = &proc->attr_prach_br;
#endif

knopp's avatar
knopp committed
952
953
    //    attr_td     = &proc->attr_td;
    //    attr_te     = &proc->attr_te; 
knopp's avatar
knopp committed
954
#endif
955
956
957
958
    //////////////////////////////////////need to modified////////////////*****
    if(get_nprocs() > 2 && codingw)
    {
      init_te_thread(eNB);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
959
      init_td_thread(eNB);
960
961
    }
    //////////////////////////////////////need to modified////////////////*****
962
	pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc );
963
	pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc);
knopp's avatar
knopp committed
964

965
966
    LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);

967
968
969
970
    if (eNB->single_thread_flag==0) {
      pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
      pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
    }
971
    pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
972
973
974
#ifdef Rel14
    pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
#endif
975
    char name[16];
976
977
978
979
980
981
    if (eNB->single_thread_flag==0) {
      snprintf( name, sizeof(name), "RXTX0 %d", i );
      pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
      snprintf( name, sizeof(name), "RXTX1 %d", i );
      pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
    }
knopp's avatar
knopp committed
982
983

    AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
984
	
985

Wang Tsu-Han's avatar
Wang Tsu-Han committed
986
    if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void*)eNB);
knopp's avatar
knopp committed
987

988
    
989
  }
990

991
  //for multiple CCs: setup master and slaves
992
993
994
  /* 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB = PHY_vars_eNB_g[inst][CC_id];
995

996
997
998
     if (eNB->node_timing == synch_to_ext_device) { //master
     eNB->proc.num_slaves = MAX_NUM_CCs-1;
     eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*));
999

1000
1001
1002
1003
1004
1005
1006
     for (i=0; i< eNB->proc.num_slaves; i++) {
     if (i < CC_id)  eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
     if (i >= CC_id)  eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc);
     }
     }
     }
  */
1007

1008
1009
1010
1011
  /* setup PHY proc TX sync mechanism */
  pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
  pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
  sync_phy_proc.phy_proc_CC_id = 0;
1012
1013
  
  
1014
1015
}

1016

1017

1018
1019
1020
/*!
 * \brief Terminate eNB TX and RX threads.
 */
1021
void kill_eNB_proc(int inst) {
Sandeep Kumar's avatar
Sandeep Kumar committed
1022

1023
  int *status;
1024
1025
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
knopp's avatar
knopp committed
1026
  eNB_rxtx_proc_t *proc_rxtx;
1027
  int i;
1028
  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1029
    eNB=RC.eNB[inst][CC_id];
1030
1031
    
    proc = &eNB->proc;
knopp's avatar
knopp committed
1032
    proc_rxtx = &proc->proc_rxtx[0];
knopp's avatar
knopp committed
1033

Wang Tsu-Han's avatar
Wang Tsu-Han committed
1034
1035
    kill_td_thread(eNB);
    kill_te_thread(eNB);
knopp's avatar
knopp committed
1036
    LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
1037
1038
1039
    for (i=0; i<2; i++) {
      pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx);
      proc_rxtx[i].instance_cnt_rxtx = 0;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1040
      proc_rxtx[i].pipe_ready = 0;
knopp's avatar
knopp committed
1041
      pthread_cond_signal(&proc_rxtx[i].cond_rxtx);
1042
      pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx);
1043
    }
Raymond Knopp's avatar
Raymond Knopp committed
1044
1045
    proc->instance_cnt_prach = 0;
    pthread_cond_signal( &proc->cond_prach );
1046

1047
    pthread_cond_signal( &proc->cond_asynch_rxtx );
1048
    pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
Raymond Knopp's avatar
Raymond Knopp committed
1049

1050
    LOG_D(PHY, "joining pthread_prach\n");