adding parallel structure
This commit is contained in:
@@ -304,8 +304,6 @@ typedef struct RU_proc_t_s {
|
||||
int instance_pre_scd;
|
||||
#endif
|
||||
/// pipeline ready state
|
||||
int ru_rx_ready;
|
||||
int ru_tx_ready;
|
||||
int emulate_rf_busy;
|
||||
} RU_proc_t;
|
||||
|
||||
|
||||
@@ -77,6 +77,10 @@
|
||||
#include "NR_EUTRA-MBSFN-SubframeConfig.h"
|
||||
|
||||
extern uint16_t sf_ahead;
|
||||
extern void set_parallel_conf(char *parallel_conf);
|
||||
extern void set_worker_conf(char *worker_conf);
|
||||
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||
|
||||
void RCconfig_nr_flexran()
|
||||
{
|
||||
@@ -2976,6 +2980,36 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RCconfig_nr_parallel(void) {
|
||||
char *parallel_conf = NULL;
|
||||
char *worker_conf = NULL;
|
||||
extern char *parallel_config;
|
||||
extern char *worker_config;
|
||||
paramdef_t ThreadParams[] = THREAD_CONF_DESC;
|
||||
paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0};
|
||||
config_getlist( &THREADParamList,NULL,0,NULL);
|
||||
|
||||
if(THREADParamList.numelt>0) {
|
||||
config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
|
||||
parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr));
|
||||
} else {
|
||||
parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT");
|
||||
}
|
||||
|
||||
if(THREADParamList.numelt>0) {
|
||||
config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
|
||||
worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr));
|
||||
} else {
|
||||
worker_conf = strdup("WORKER_ENABLE");
|
||||
}
|
||||
|
||||
if(parallel_config == NULL) set_parallel_conf(parallel_conf);
|
||||
|
||||
if(worker_config == NULL) set_worker_conf(worker_conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NRRCConfig(void) {
|
||||
|
||||
paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
|
||||
@@ -3016,7 +3050,7 @@ void NRRCConfig(void) {
|
||||
config_getlist( &RUParamList,NULL,0, NULL);
|
||||
RC.nb_RU = RUParamList.numelt;
|
||||
|
||||
RCconfig_parallel();
|
||||
RCconfig_nr_parallel();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1099,3 +1099,29 @@ typedef enum {
|
||||
#define MACRLC_REMOTE_S_PORTD_IDX 16
|
||||
#define MACRLC_SCHED_MODE_IDX 17
|
||||
#define MACRLC_PHY_TEST_IDX 18
|
||||
|
||||
|
||||
/* thread configuration parameters section name */
|
||||
#define THREAD_CONFIG_STRING_THREAD_STRUCT "THREAD_STRUCT"
|
||||
|
||||
/* thread configuration parameters names */
|
||||
#define THREAD_CONFIG_STRING_PARALLEL "parallel_config"
|
||||
#define THREAD_CONFIG_STRING_WORKER "worker_config"
|
||||
|
||||
|
||||
#define THREAD_PARALLEL_IDX 0
|
||||
#define THREAD_WORKER_IDX 1
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* thread configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define THREAD_CONF_DESC { \
|
||||
{THREAD_CONFIG_STRING_PARALLEL, CONFIG_HLP_PARALLEL, 0, strptr:NULL, defstrval:"PARALLEL_RU_L1_TRX_SPLIT", TYPE_STRING, 0}, \
|
||||
{THREAD_CONFIG_STRING_WORKER, CONFIG_HLP_WORKER, 0, strptr:NULL, defstrval:"WORKER_ENABLE", TYPE_STRING, 0} \
|
||||
}
|
||||
|
||||
|
||||
#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
|
||||
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
+160
-14
@@ -143,6 +143,11 @@ extern double cpuf;
|
||||
void init_gNB(int,int);
|
||||
void stop_gNB(int nb_inst);
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB);
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB);
|
||||
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||
|
||||
|
||||
void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe);
|
||||
|
||||
@@ -227,7 +232,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
//if (wait_CCs(proc)<0) return(-1);
|
||||
|
||||
if (oai_exit) return(-1);
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
|
||||
stop_meas( &softmodem_stats_rxtx_sf );
|
||||
|
||||
@@ -278,6 +285,44 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void* gNB_L1_thread_tx(void* param) {
|
||||
|
||||
gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx;
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
|
||||
char thread_name[100];
|
||||
sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||
thread_top_init(thread_name,1,470000,500000,500000);
|
||||
|
||||
//wait_sync("tx_thread");
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,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)
|
||||
// *****************************************
|
||||
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
|
||||
pthread_mutex_lock( &proc->mutex );
|
||||
proc->instance_cnt = -1;
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&proc->cond) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
}
|
||||
pthread_mutex_unlock( &proc->mutex );
|
||||
wakeup_txfh(proc,gNB);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The RX UE-specific and TX thread of gNB.
|
||||
@@ -285,11 +330,11 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
|
||||
*/
|
||||
|
||||
static void* gNB_thread_rxtx( void* param ) {
|
||||
static void* gNB_L1_thread( void* param ) {
|
||||
|
||||
static int gNB_thread_rxtx_status;
|
||||
|
||||
gNB_L1_rxtx_proc_t *proc = (gNB_L1_rxtx_proc_t*)param;
|
||||
gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc;
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
|
||||
char thread_name[100];
|
||||
@@ -303,11 +348,9 @@ static void* gNB_thread_rxtx( void* param ) {
|
||||
thread_top_init(thread_name,1,850000L,1000000L,2000000L);
|
||||
|
||||
while (!oai_exit) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
|
||||
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
@@ -316,12 +359,19 @@ static void* gNB_thread_rxtx( void* param ) {
|
||||
if (rxtx(gNB,proc,thread_name) < 0) break;
|
||||
|
||||
}
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){
|
||||
wakeup_tx(gNB);
|
||||
}
|
||||
else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){
|
||||
wakeup_txfh(proc,gNB);
|
||||
}
|
||||
|
||||
} // while !oai_exit
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
|
||||
|
||||
LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
|
||||
|
||||
@@ -379,6 +429,101 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int subframe_rx, char *string, str
|
||||
}
|
||||
}
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) {
|
||||
|
||||
RU_t *ru;
|
||||
RU_proc_t *ru_proc;
|
||||
|
||||
|
||||
struct timespec wait;
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs);
|
||||
|
||||
if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
|
||||
LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx);
|
||||
return(-1);
|
||||
}
|
||||
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||
gNB->proc.RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||
if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
|
||||
|
||||
for(int i=0; i<gNB->num_RU; i++)
|
||||
{
|
||||
ru = gNB->RU_list[i];
|
||||
ru_proc = &ru->proc;
|
||||
if (ru_proc->instance_cnt_gNBs == 0) {
|
||||
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);
|
||||
return(-1);
|
||||
}
|
||||
if (pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&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_gNBs );
|
||||
exit_fun( "error locking mutex_gNB" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ru_proc->instance_cnt_gNBs = 0;
|
||||
ru_proc->timestamp_tx = proc->timestamp_tx;
|
||||
ru_proc->subframe_tx = proc->subframe_tx;
|
||||
ru_proc->frame_tx = proc->frame_tx;
|
||||
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &ru_proc->mutex_gNBs );
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
|
||||
gNB_L1_proc_t *proc=&gNB->proc;
|
||||
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||
|
||||
|
||||
struct timespec wait;
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
|
||||
|
||||
if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) {
|
||||
LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n");
|
||||
exit_fun("ERROR pthread_lock");
|
||||
return(-1);
|
||||
}
|
||||
while(L1_proc_tx->instance_cnt == 0){
|
||||
pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
|
||||
}
|
||||
|
||||
L1_proc_tx->instance_cnt = 0;
|
||||
|
||||
|
||||
L1_proc_tx->subframe_rx = L1_proc->subframe_rx;
|
||||
L1_proc_tx->frame_rx = L1_proc->frame_rx;
|
||||
L1_proc_tx->subframe_tx = L1_proc->subframe_tx;
|
||||
L1_proc_tx->frame_tx = L1_proc->frame_tx;
|
||||
L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx;
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc_tx->cond) != 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( &L1_proc_tx->mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
|
||||
@@ -619,13 +764,15 @@ void init_gNB_proc(int inst) {
|
||||
// pthread_attr_init( &proc->attr_te);
|
||||
pthread_attr_init( &L1_proc->attr);
|
||||
pthread_attr_init( &L1_proc_tx->attr);
|
||||
attr0 = &L1_proc->attr;
|
||||
attr1 = &L1_proc_tx->attr;
|
||||
|
||||
LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
|
||||
|
||||
/*if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
|
||||
pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
|
||||
}*/
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, proc );
|
||||
pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, proc);
|
||||
}
|
||||
//pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
|
||||
|
||||
char name[16];
|
||||
@@ -693,8 +840,7 @@ void kill_gNB_proc(int inst) {
|
||||
|
||||
LOG_I(PHY, "Destroying UL_INFO mutex\n");
|
||||
pthread_mutex_destroy(&gNB->UL_INFO_mutex);
|
||||
int i;
|
||||
if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
LOG_I(PHY, "Joining L1_proc mutex/cond\n");
|
||||
pthread_join( L1_proc->pthread, (void**)&status );
|
||||
LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
|
||||
|
||||
+187
-47
@@ -118,6 +118,9 @@ extern void nr_phy_init_RU(RU_t*);
|
||||
extern void nr_phy_free_RU(RU_t*);
|
||||
extern void nr_phy_config_request(NR_PHY_Config_t *gNB);
|
||||
|
||||
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||
|
||||
void init_RU(char*);
|
||||
void stop_RU(int nb_ru);
|
||||
void do_ru_sync(RU_t *ru);
|
||||
@@ -1131,12 +1134,12 @@ void do_ru_synch(RU_t *ru) {
|
||||
|
||||
|
||||
|
||||
void wakeup_gNBs(RU_t *ru) {
|
||||
void wakeup_gNB_L1s(RU_t *ru) {
|
||||
|
||||
int i;
|
||||
PHY_VARS_gNB **gNB_list = ru->gNB_list;
|
||||
|
||||
LOG_D(PHY,"wakeup_gNBs (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top);
|
||||
LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top);
|
||||
|
||||
if (ru->num_gNB==1 && ru->gNB_top!=0) {
|
||||
// call gNB function directly
|
||||
@@ -1378,6 +1381,118 @@ static void* ru_stats_thread(void* param) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static void* ru_thread_tx( void* param ) {
|
||||
RU_t *ru = (RU_t*)param;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
PHY_VARS_gNB *gNB;
|
||||
gNB_L1_proc_t *gNB_proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
char filename[40];
|
||||
int print_frame = 2;
|
||||
int i = 0;
|
||||
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
|
||||
|
||||
thread_top_init("ru_thread_tx",1,400000,500000,500000);
|
||||
|
||||
//CPU_SET(5, &cpuset);
|
||||
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
|
||||
//wait_sync("ru_thread_tx");
|
||||
|
||||
wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
|
||||
|
||||
|
||||
printf( "ru_thread_tx ready\n");
|
||||
while (!oai_exit) {
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu());
|
||||
if (oai_exit) break;
|
||||
|
||||
|
||||
LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n");
|
||||
// wait until eNBs are finished subframe RX n and TX n+4
|
||||
wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
|
||||
if (oai_exit) break;
|
||||
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(proc->frame_tx == print_frame)
|
||||
{
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
{
|
||||
sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx);
|
||||
LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
|
||||
if(proc->subframe_tx == 9)
|
||||
{
|
||||
sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
|
||||
LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
|
||||
sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
|
||||
FILE *output_fd = fopen(filename,"w");
|
||||
if (output_fd) {
|
||||
fwrite(&ru->common.txdata[i][0],
|
||||
sizeof(int32_t),
|
||||
fp->samples_per_frame,
|
||||
output_fd);
|
||||
fclose(output_fd);
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY,"Cannot write to file %s\n",filename);
|
||||
}
|
||||
}//if(proc->subframe_tx == 9)
|
||||
}//for (i=0; i<ru->nb_tx; i++)
|
||||
}//if(proc->frame_tx == print_frame)
|
||||
}//else emulate_rf
|
||||
release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
|
||||
for(i = 0; i<ru->num_gNB; i++)
|
||||
{
|
||||
gNB = ru->gNB_list[i];
|
||||
gNB_proc = &gNB->proc;
|
||||
L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc;
|
||||
pthread_mutex_lock(&gNB_proc->mutex_RU_tx);
|
||||
for (int j=0;j<gNB->num_RU;j++) {
|
||||
if (ru == gNB->RU_list[j]) {
|
||||
if ((gNB_proc->RU_mask_tx&(1<<j)) > 0)
|
||||
LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
|
||||
gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->subframe_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx);
|
||||
gNB_proc->RU_mask_tx |= (1<<j);
|
||||
}
|
||||
}
|
||||
if (gNB_proc->RU_mask_tx != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||
pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
|
||||
}
|
||||
else { // all RUs TX are finished so send the ready signal to eNB processing
|
||||
gNB_proc->RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
|
||||
|
||||
pthread_mutex_lock( &L1_proc->mutex_RUs);
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
}
|
||||
pthread_mutex_unlock( &L1_proc->mutex_RUs );
|
||||
}
|
||||
}
|
||||
}
|
||||
release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* ru_thread( void* param ) {
|
||||
|
||||
static int ru_thread_status;
|
||||
@@ -1440,6 +1555,11 @@ static void* ru_thread( void* param ) {
|
||||
RC.ru_mask &= ~(1<<ru->idx);
|
||||
pthread_cond_signal(&RC.ru_cond);
|
||||
pthread_mutex_unlock(&RC.ru_mutex);
|
||||
|
||||
pthread_mutex_lock(&proc->mutex_FH1);
|
||||
proc->instance_cnt_FH1 = 0;
|
||||
pthread_mutex_unlock(&proc->mutex_FH1);
|
||||
pthread_cond_signal(&proc->cond_FH1);
|
||||
|
||||
wait_sync("ru_thread");
|
||||
|
||||
@@ -1514,53 +1634,66 @@ static void* ru_thread( void* param ) {
|
||||
wakeup_slaves(proc);
|
||||
|
||||
// wakeup all gNB processes waiting for this RU
|
||||
if (ru->num_gNB>0) wakeup_gNBs(ru);
|
||||
if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
|
||||
|
||||
// wait until gNBs are finished subframe RX n and TX n+sf_ahead
|
||||
wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread");
|
||||
|
||||
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if(!emulate_rf)
|
||||
{
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(proc->frame_tx == print_frame)
|
||||
{
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
{
|
||||
sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx);
|
||||
LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
|
||||
if(proc->subframe_tx == 9)
|
||||
{
|
||||
sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
|
||||
LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
|
||||
sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
|
||||
FILE *output_fd = fopen(filename,"w");
|
||||
if (output_fd) {
|
||||
fwrite(&ru->common.txdata[i][0],
|
||||
sizeof(int32_t),
|
||||
fp->samples_per_frame,
|
||||
output_fd);
|
||||
fclose(output_fd);
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY,"Cannot write to file %s\n",filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
//else if (proc->frame_tx > print_frame) oai_exit = 1;
|
||||
proc->emulate_rf_busy = 0;
|
||||
}
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD)
|
||||
{
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if(!emulate_rf)
|
||||
{
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(proc->frame_tx == print_frame)
|
||||
{
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
{
|
||||
sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx);
|
||||
LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
|
||||
if(proc->subframe_tx == 9)
|
||||
{
|
||||
sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
|
||||
LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
|
||||
sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
|
||||
FILE *output_fd = fopen(filename,"w");
|
||||
if (output_fd) {
|
||||
fwrite(&ru->common.txdata[i][0],
|
||||
sizeof(int32_t),
|
||||
fp->samples_per_frame,
|
||||
output_fd);
|
||||
fclose(output_fd);
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY,"Cannot write to file %s\n",filename);
|
||||
}
|
||||
}//if(proc->subframe_tx == 9)
|
||||
}//for (i=0; i<ru->nb_tx; i++)
|
||||
}//if(proc->frame_tx == print_frame)
|
||||
}//else emulate_rf
|
||||
}//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD)
|
||||
}
|
||||
|
||||
|
||||
@@ -1680,7 +1813,7 @@ void init_RU_proc(RU_t *ru) {
|
||||
|
||||
int i=0;
|
||||
RU_proc_t *proc;
|
||||
pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL;
|
||||
pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL;
|
||||
//pthread_attr_t *attr_fep=NULL;
|
||||
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
//pthread_attr_t *attr_prach_br=NULL;
|
||||
@@ -1697,6 +1830,7 @@ void init_RU_proc(RU_t *ru) {
|
||||
proc->instance_cnt_prach = -1;
|
||||
proc->instance_cnt_synch = -1; ;
|
||||
proc->instance_cnt_FH = -1;
|
||||
proc->instance_cnt_FH1 = -1;
|
||||
proc->instance_cnt_asynch_rxtx = -1;
|
||||
proc->instance_cnt_emulateRF = -1;
|
||||
proc->first_rx = 1;
|
||||
@@ -1711,17 +1845,20 @@ void init_RU_proc(RU_t *ru) {
|
||||
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
|
||||
pthread_mutex_init( &proc->mutex_synch,NULL);
|
||||
pthread_mutex_init( &proc->mutex_FH,NULL);
|
||||
pthread_mutex_init( &proc->mutex_FH1,NULL);
|
||||
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
|
||||
pthread_mutex_init( &proc->mutex_gNBs, NULL);
|
||||
|
||||
pthread_cond_init( &proc->cond_prach, NULL);
|
||||
pthread_cond_init( &proc->cond_FH, NULL);
|
||||
pthread_cond_init( &proc->cond_FH1, NULL);
|
||||
pthread_cond_init( &proc->cond_emulateRF, NULL);
|
||||
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
|
||||
pthread_cond_init( &proc->cond_synch,NULL);
|
||||
pthread_cond_init( &proc->cond_gNBs, NULL);
|
||||
|
||||
pthread_attr_init( &proc->attr_FH);
|
||||
pthread_attr_init( &proc->attr_FH1);
|
||||
pthread_attr_init( &proc->attr_emulateRF);
|
||||
pthread_attr_init( &proc->attr_prach);
|
||||
pthread_attr_init( &proc->attr_synch);
|
||||
@@ -1731,6 +1868,7 @@ void init_RU_proc(RU_t *ru) {
|
||||
|
||||
#ifndef DEADLINE_SCHEDULER
|
||||
attr_FH = &proc->attr_FH;
|
||||
attr_FH1 = &proc->attr_FH1;
|
||||
attr_emulateRF = &proc->attr_emulateRF;
|
||||
attr_prach = &proc->attr_prach;
|
||||
//attr_synch = &proc->attr_synch;
|
||||
@@ -1738,6 +1876,8 @@ void init_RU_proc(RU_t *ru) {
|
||||
#endif
|
||||
|
||||
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
|
||||
pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru );
|
||||
if(emulate_rf)
|
||||
pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
|
||||
if (ru->function == NGFI_RRU_IF4p5) {
|
||||
|
||||
Reference in New Issue
Block a user