Commit 3baf81cd authored by Lionel Gauthier's avatar Lionel Gauthier

patches13/0009-simplified-and-documented-rx-tx-threads.patch

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7055 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 4649f42a
...@@ -57,10 +57,6 @@ ...@@ -57,10 +57,6 @@
#include "rt_wrapper.h" #include "rt_wrapper.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#ifndef EXMIMO
static int hw_subframe;
#endif
#include "assertions.h" #include "assertions.h"
#ifdef EMOS #ifdef EMOS
...@@ -998,7 +994,9 @@ static void* eNB_thread_tx( void* param ) ...@@ -998,7 +994,9 @@ static void* eNB_thread_tx( void* param )
} }
while (proc->instance_cnt_tx < 0) { while (proc->instance_cnt_tx < 0) {
pthread_cond_wait( &proc->cond_tx, &proc->mutex_tx ); // most of the time the thread is waiting here
// proc->instance_cnt_tx is -1
pthread_cond_wait( &proc->cond_tx, &proc->mutex_tx ); // this unlocks mutex_tx while waiting and then locks it again
} }
if (pthread_mutex_unlock(&proc->mutex_tx) != 0) { if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {
...@@ -1141,7 +1139,9 @@ static void* eNB_thread_rx( void* param ) ...@@ -1141,7 +1139,9 @@ static void* eNB_thread_rx( void* param )
} }
while (proc->instance_cnt_rx < 0) { while (proc->instance_cnt_rx < 0) {
pthread_cond_wait( &proc->cond_rx, &proc->mutex_rx ); // most of the time the thread is waiting here
// proc->instance_cnt_rx is -1
pthread_cond_wait( &proc->cond_rx, &proc->mutex_rx ); // this unlocks mutex_rx while waiting and then locks it again
} }
if (pthread_mutex_unlock(&proc->mutex_rx) != 0) { if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {
...@@ -1357,18 +1357,10 @@ static void* eNB_thread( void* arg ) ...@@ -1357,18 +1357,10 @@ static void* eNB_thread( void* arg )
UNUSED(arg); UNUSED(arg);
static int eNB_thread_status; static int eNB_thread_status;
#ifdef EXMIMO unsigned char slot;
unsigned char slot=0;
#else
unsigned char slot=1;
#endif
int frame=0; int frame=0;
int CC_id;
RTIME time_diff;
int sf;
#ifdef EXMIMO #ifdef EXMIMO
slot=0;
RTIME time_in; RTIME time_in;
volatile unsigned int *DAQ_MBOX = openair0_daq_cnt(); volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
int mbox_target=0,mbox_current=0; int mbox_target=0,mbox_current=0;
...@@ -1377,30 +1369,23 @@ static void* eNB_thread( void* arg ) ...@@ -1377,30 +1369,23 @@ static void* eNB_thread( void* arg )
int ret; int ret;
int first_run=1; int first_run=1;
#else #else
slot=1;
unsigned int rx_pos = 0; unsigned int rx_pos = 0;
unsigned int tx_pos; unsigned int tx_pos;
int spp; int spp;
int tx_launched=0; int tx_launched=0;
void *rxp[2], *txp[2]; void *rxp[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_rx
int i; void *txp[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_tx
openair0_timestamp timestamp; openair0_timestamp timestamp;
// int trace_cnt=0; int hw_subframe = 0; // 0..NUM_ENB_THREADS-1 => 0..9
hw_subframe = 0;
spp = openair0_cfg[0].samples_per_packet; spp = openair0_cfg[0].samples_per_packet;
tx_pos = spp*tx_delay; tx_pos = spp*tx_delay;
#endif #endif
struct timespec trx_time0,trx_time1,trx_time2; struct timespec trx_time0, trx_time1, trx_time2;
/*
#if defined(ENABLE_ITTI)
// Wait for eNB application initialization to be complete (eNB registration to MME)
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif
*/
#ifdef RTAI #ifdef RTAI
RT_TASK* task = rt_task_init_schmod(nam2num("eNBmain"), 0, 0, 0, SCHED_FIFO, 0xF); RT_TASK* task = rt_task_init_schmod(nam2num("eNBmain"), 0, 0, 0, SCHED_FIFO, 0xF);
...@@ -1436,12 +1421,15 @@ static void* eNB_thread( void* arg ) ...@@ -1436,12 +1421,15 @@ static void* eNB_thread( void* arg )
#endif #endif
#endif #endif
if (!oai_exit) { // stop early, if an exit is requested
// FIXME really neccessary?
if (oai_exit)
goto eNB_thread_cleanup;
#ifdef RTAI #ifdef RTAI
printf("[SCHED][eNB] Started eNB main thread (id %p)\n",task); printf( "[SCHED][eNB] Started eNB main thread (id %p)\n", task );
#else #else
printf("[SCHED][eNB] Started eNB main thread on CPU %d\n", printf( "[SCHED][eNB] Started eNB main thread on CPU %d\n", sched_getcpu());
sched_getcpu());
#endif #endif
#ifdef HARD_RT #ifdef HARD_RT
...@@ -1457,14 +1445,15 @@ static void* eNB_thread( void* arg ) ...@@ -1457,14 +1445,15 @@ static void* eNB_thread( void* arg )
timing_info.time_avg = 0; timing_info.time_avg = 0;
timing_info.n_samples = 0; timing_info.n_samples = 0;
printf("waiting for sync (eNB_thread)\n"); printf( "waiting for sync (eNB_thread)\n" );
pthread_mutex_lock(&sync_mutex); pthread_mutex_lock( &sync_mutex );
while (sync_var<0) while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex); pthread_cond_wait( &sync_cond, &sync_mutex );
pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
while (!oai_exit) { while (!oai_exit) {
start_meas(&softmodem_stats_mt); start_meas( &softmodem_stats_mt );
#ifdef EXMIMO #ifdef EXMIMO
hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
// LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]); // LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]);
...@@ -1537,44 +1526,45 @@ static void* eNB_thread( void* arg ) ...@@ -1537,44 +1526,45 @@ static void* eNB_thread( void* arg )
} }
#else // EXMIMO #else // EXMIMO
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe );
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame );
tx_launched = 0; tx_launched = 0;
while (rx_pos < ((1+hw_subframe)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti)) { while (rx_pos < ((1+hw_subframe)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti)) {
// openair0_timestamp time0,time1;
unsigned int rxs; unsigned int rxs;
#ifndef USRP_DEBUG #ifndef USRP_DEBUG
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1); vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,tx_pos); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos );
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,rx_pos); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos );
clock_gettime( CLOCK_MONOTONIC, &trx_time0 );
clock_gettime(CLOCK_MONOTONIC,&trx_time0); // prepare rx buffer pointers
for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx;i++) for (int i=0; i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&rxdata[i][rx_pos]; rxp[i] = (void*)&rxdata[i][rx_pos];
start_meas(&softmodem_stats_hw);
// printf("rxp[0] %p\n",rxp[0]); start_meas( &softmodem_stats_hw );
rxs = openair0.trx_read_func(&openair0, rxs = openair0.trx_read_func(&openair0,
&timestamp, &timestamp,
rxp, rxp,
spp, spp,
PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx); PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
stop_meas(&softmodem_stats_hw); stop_meas( &softmodem_stats_hw );
clock_gettime(CLOCK_MONOTONIC,&trx_time1); clock_gettime( CLOCK_MONOTONIC, &trx_time1 );
if (rxs != spp) if (rxs != spp)
exit_fun("problem receiving samples"); exit_fun( "problem receiving samples" );
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0); vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1); vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx;i++) // prepare tx buffer pointers
for (int i=0; i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&txdata[i][tx_pos]; txp[i] = (void*)&txdata[i][tx_pos];
if (frame > 50) { if (frame > 50) {
openair0.trx_write_func(&openair0, openair0.trx_write_func(&openair0,
(timestamp+(tx_delay*spp)-tx_forward_nsamps), (timestamp+(tx_delay*spp)-tx_forward_nsamps),
...@@ -1584,49 +1574,51 @@ static void* eNB_thread( void* arg ) ...@@ -1584,49 +1574,51 @@ static void* eNB_thread( void* arg )
1); 1);
} }
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,timestamp&0xffffffff); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, timestamp&0xffffffff );
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,(timestamp+(tx_delay*spp)-tx_forward_nsamps)&0xffffffff); vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp+(tx_delay*spp)-tx_forward_nsamps)&0xffffffff );
stop_meas( &softmodem_stats_mt );
stop_meas(&softmodem_stats_mt); clock_gettime( CLOCK_MONOTONIC, &trx_time2 );
clock_gettime(CLOCK_MONOTONIC,&trx_time2);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
/*
if (trace_cnt++<10)
printf("TRX: t1 %llu (trx_read), t2 %llu (trx_write)\n",(long long unsigned int)(trx_time1.tv_nsec - trx_time0.tv_nsec), (long long unsigned int)(trx_time2.tv_nsec - trx_time1.tv_nsec));
*/
#else #else
// USRP_DEBUG is active
rt_sleep_ns(1000000); rt_sleep_ns(1000000);
#endif #endif
if ((tx_launched == 0) && if ((tx_launched == 0) &&
(rx_pos >=(((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) { (rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) {
tx_launched = 1; tx_launched = 1;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx) != 0) { if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx); LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", hw_subframe, PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx );
exit_fun( "error locking mutex_tx" );
break;
} }
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d,rx_cnt %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx,rx_cnt); int cnt_tx = ++PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx;
PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx); pthread_mutex_unlock( &PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx );
if (PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx == 0) {
if (cnt_tx == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].cond_tx) != 0) { if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].cond_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",hw_subframe); LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n", hw_subframe );
} exit_fun( "ERROR pthread_cond_signal" );
} break;
else {
LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!! (rx_cnt %d)\n",PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].frame_tx,hw_subframe,rx_pos);
exit_fun("nothing to add");
} }
} else {
LOG_W( PHY,"[eNB] Frame %d, eNB TX thread %d busy!! (rx_cnt %u, cnt_tx %i)\n", PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].frame_tx, hw_subframe, rx_pos, cnt_tx );
exit_fun( "TX thread busy" );
break;
} }
} }
} }
rx_pos += spp; rx_pos += spp;
tx_pos += spp; tx_pos += spp;
if (tx_pos >= samples_per_frame)
if(tx_pos >= samples_per_frame)
tx_pos -= samples_per_frame; tx_pos -= samples_per_frame;
} }
...@@ -1638,13 +1630,11 @@ static void* eNB_thread( void* arg ) ...@@ -1638,13 +1630,11 @@ static void* eNB_thread( void* arg )
if (oai_exit) break; if (oai_exit) break;
timing_info.time_last = timing_info.time_now; timing_info.time_last = timing_info.time_now;
timing_info.time_now = rt_get_time_ns(); timing_info.time_now = rt_get_time_ns();
if (timing_info.n_samples>0) { if (timing_info.n_samples>0) {
time_diff = timing_info.time_now - timing_info.time_last; RTIME time_diff = timing_info.time_now - timing_info.time_last;
if (time_diff < timing_info.time_min) if (time_diff < timing_info.time_min)
timing_info.time_min = time_diff; timing_info.time_min = time_diff;
if (time_diff > timing_info.time_max) if (time_diff > timing_info.time_max)
...@@ -1666,13 +1656,13 @@ static void* eNB_thread( void* arg ) ...@@ -1666,13 +1656,13 @@ static void* eNB_thread( void* arg )
if ((slot&1) == 1) { if ((slot&1) == 1) {
#ifdef EXMIMO #ifdef EXMIMO
sf = ((slot>>1)+1)%10; int sf = ((slot>>1)+1)%10;
#else #else
sf = hw_subframe; int sf = hw_subframe;
#endif #endif
// LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); // LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
#ifdef EXMIMO #ifdef EXMIMO
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) { if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx); LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx);
...@@ -1692,37 +1682,32 @@ static void* eNB_thread( void* arg ) ...@@ -1692,37 +1682,32 @@ static void* eNB_thread( void* arg )
} }
} }
#endif #endif
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) { if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx); LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n", sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx );
exit_fun( "error locking mutex_rx" );
break;
} }
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d) CC_id %d rx_cnt %d\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx,CC_id,rx_cnt); int cnt_rx = ++PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx;
PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx); pthread_mutex_unlock( &PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx );
if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx == 0) {
if (cnt_rx == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) { if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n",sf); LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n", sf );
} exit_fun( "ERROR pthread_cond_signal" );
//else break;
// LOG_I(PHY,"[eNB] pthread_cond_signal for eNB RX thread %d instance_cnt_rx %d\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx);
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!! instance_cnt %d CC_id %d\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx,CC_id);
exit_fun("nothing to add");
} }
} else {
LOG_W( PHY, "[eNB] Frame %d, eNB RX thread %d busy!! instance_cnt %d CC_id %d\n", PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx, sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx, CC_id );
exit_fun( "RX thread busy" );
break;
} }
} }
} }
#ifndef RTAI
//pthread_mutex_lock(&tti_mutex);
#endif
#ifdef EXMIMO #ifdef EXMIMO
slot++; slot++;
if (slot == 20) { if (slot == 20) {
...@@ -1731,39 +1716,35 @@ static void* eNB_thread( void* arg ) ...@@ -1731,39 +1716,35 @@ static void* eNB_thread( void* arg )
} }
#else #else
hw_subframe++; hw_subframe++;
slot+=2; slot += 2;
if(hw_subframe==10) { if (hw_subframe == NUM_ENB_THREADS) {
hw_subframe = 0; hw_subframe = 0;
frame++; frame++;
slot = 1; slot = 1;
} }
#endif #endif
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
itti_update_lte_time(frame, slot); itti_update_lte_time(frame, slot);
#endif #endif
} }
}
eNB_thread_cleanup:
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf("eNB_thread: finished, ran %d times.\n",frame); printf( "eNB_thread: finished, ran %d times.\n", frame );
#endif #endif
#ifdef HARD_RT #ifdef HARD_RT
rt_make_soft_real_time(); rt_make_soft_real_time();
#endif #endif
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf("Exiting eNB_thread ..."); printf( "Exiting eNB_thread ..." );
#endif #endif
// clean task // clean task
#ifdef RTAI #ifdef RTAI
rt_task_delete(task); rt_task_delete(task);
#endif #endif
#ifdef DEBUG_THREADS
printf("eNB_thread deleted. returning\n");
#endif
eNB_thread_status = 0; eNB_thread_status = 0;
return &eNB_thread_status; return &eNB_thread_status;
......
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