Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Michael Black
OpenXG UE
Commits
eee157ee
Commit
eee157ee
authored
Aug 07, 2016
by
Raymond Knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
testing of low-level parallelization of FEP in eNodeB RX.
parent
3e5c274d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
185 additions
and
10 deletions
+185
-10
openair1/PHY/defs.h
openair1/PHY/defs.h
+12
-0
openair1/SCHED/phy_procedures_lte_eNb.c
openair1/SCHED/phy_procedures_lte_eNb.c
+152
-0
openair1/SIMULATION/LTE_PHY/ulsim.c
openair1/SIMULATION/LTE_PHY/ulsim.c
+9
-1
targets/RT/USER/lte-enb.c
targets/RT/USER/lte-enb.c
+12
-9
No files found.
openair1/PHY/defs.h
View file @
eee157ee
...
...
@@ -246,6 +246,8 @@ typedef struct eNB_proc_t_s {
int
frame_rx
;
/// frame to act upon for PRACH
int
frame_prach
;
/// \internal This variable is protected by \ref mutex_fep.
int
instance_cnt_fep
;
/// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH.
int
instance_cnt_FH
;
...
...
@@ -264,6 +266,8 @@ typedef struct eNB_proc_t_s {
int
first_rx
;
/// flag to indicate first TX transmission
int
first_tx
;
/// pthread attributes for parallel fep thread
pthread_attr_t
attr_fep
;
/// pthread attributes for FH processing thread
pthread_attr_t
attr_FH
;
/// pthread attributes for single eNB processing thread
...
...
@@ -272,6 +276,8 @@ typedef struct eNB_proc_t_s {
pthread_attr_t
attr_prach
;
/// pthread attributes for asynchronous RX thread
pthread_attr_t
attr_asynch_rxtx
;
/// scheduling parameters for parallel fep thread
struct
sched_param
sched_param_fep
;
/// scheduling parameters for FH thread
struct
sched_param
sched_param_FH
;
/// scheduling parameters for single eNB thread
...
...
@@ -280,14 +286,20 @@ typedef struct eNB_proc_t_s {
struct
sched_param
sched_param_prach
;
/// scheduling parameters for asynch_rxtx thread
struct
sched_param
sched_param_asynch_rxtx
;
/// pthread structure for parallel fep thread
pthread_t
pthread_fep
;
/// pthread structure for PRACH thread
pthread_t
pthread_prach
;
/// condition variable for parallel fep thread
pthread_cond_t
cond_fep
;
/// condition variable for FH thread
pthread_cond_t
cond_FH
;
/// condition variable for PRACH processing thread;
pthread_cond_t
cond_prach
;
/// condition variable for asynch RX/TX thread
pthread_cond_t
cond_asynch_rxtx
;
/// mutex for parallel fep thread
pthread_mutex_t
mutex_fep
;
/// mutex for FH
pthread_mutex_t
mutex_FH
;
/// mutex for PRACH thread
...
...
openair1/SCHED/phy_procedures_lte_eNb.c
View file @
eee157ee
...
...
@@ -2497,6 +2497,158 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
}
typedef
struct
{
PHY_VARS_eNB
*
eNB
;
int
slot
;
}
fep_task
;
void
fep0
(
PHY_VARS_eNB
*
eNB
,
int
slot
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
LTE_DL_FRAME_PARMS
*
fp
=
&
eNB
->
frame_parms
;
int
l
;
remove_7_5_kHz
(
eNB
,(
slot
&
1
)
+
(
proc
->
subframe_rx
<<
1
));
for
(
l
=
0
;
l
<
fp
->
symbols_per_tti
/
2
;
l
++
)
{
slot_fep_ul
(
fp
,
&
eNB
->
common_vars
,
l
,
(
slot
&
1
)
+
(
proc
->
subframe_rx
<<
1
),
0
,
0
);
}
}
static
inline
int
release_thread
(
pthread_mutex_t
*
mutex
,
int
*
instance_cnt
,
char
*
name
)
{
if
(
pthread_mutex_lock
(
mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][eNB] error locking mutex for %s
\n
"
,
name
);
exit_fun
(
"nothing to add"
);
return
(
-
1
);
}
*
instance_cnt
=*
instance_cnt
-
1
;
if
(
pthread_mutex_unlock
(
mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][eNB] error unlocking mutex for %s
\n
"
,
name
);
exit_fun
(
"nothing to add"
);
return
(
-
1
);
}
return
(
0
);
}
static
inline
int
wait_on_condition
(
pthread_mutex_t
*
mutex
,
pthread_cond_t
*
cond
,
int
*
instance_cnt
,
char
*
name
)
{
if
(
pthread_mutex_lock
(
mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][eNB] error locking mutex for %s
\n
"
,
name
);
exit_fun
(
"nothing to add"
);
return
(
-
1
);
}
while
(
*
instance_cnt
<
0
)
{
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
pthread_cond_wait
(
cond
,
mutex
);
// this unlocks mutex_rxtx while waiting and then locks it again
}
if
(
pthread_mutex_unlock
(
mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][eNB] error unlocking mutex for %s
\n
"
,
name
);
exit_fun
(
"nothing to add"
);
return
(
-
1
);
}
return
(
0
);
}
extern
int
oai_exit
;
static
void
*
fep_thread
(
void
*
param
)
{
PHY_VARS_eNB
*
eNB
=
(
PHY_VARS_eNB
*
)
param
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
while
(
!
oai_exit
)
{
printf
(
"Waiting for parallel FEP signal
\n
"
);
if
(
wait_on_condition
(
&
proc
->
mutex_fep
,
&
proc
->
cond_fep
,
&
proc
->
instance_cnt_fep
,
"fep thread"
)
<
0
)
break
;
printf
(
"Running parallel FEP on first slot
\n
"
);
fep0
(
eNB
,
0
);
if
(
release_thread
(
&
proc
->
mutex_fep
,
&
proc
->
instance_cnt_fep
,
"fep thread"
)
<
0
)
break
;
}
return
(
NULL
);
}
void
init_fep_thread
(
PHY_VARS_eNB
*
eNB
,
pthread_attr_t
*
attr_fep
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
proc
->
instance_cnt_fep
=
-
1
;
pthread_mutex_init
(
&
proc
->
mutex_fep
,
NULL
);
pthread_cond_init
(
&
proc
->
cond_fep
,
NULL
);
pthread_create
(
&
proc
->
pthread_fep
,
attr_fep
,
fep_thread
,
(
void
*
)
eNB
);
}
void
eNB_fep_full_2thread
(
PHY_VARS_eNB
*
eNB
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
struct
timespec
wait
;
int
wait_cnt
=
0
;
wait
.
tv_sec
=
0
;
wait
.
tv_nsec
=
5000000L
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP
,
1
);
start_meas
(
&
eNB
->
ofdm_demod_stats
);
printf
(
"Running 2 thread FEP
\n
"
);
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_fep
,
&
wait
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_mutex_lock for fep thread %d (IC %d)
\n
"
,
proc
->
instance_cnt_fep
);
exit_fun
(
"error locking mutex_fep"
);
return
;
}
if
(
proc
->
instance_cnt_fep
==
0
)
{
printf
(
"[eNB] FEP thread busy
\n
"
);
exit_fun
(
"FEP thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_fep
);
return
;
}
++
proc
->
instance_cnt_fep
;
printf
(
"[eNB] waking up FEP thread
\n
"
);
if
(
pthread_cond_signal
(
&
proc
->
cond_fep
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for fep thread
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
;
}
pthread_mutex_unlock
(
&
proc
->
mutex_fep
);
// call second slot in this symbol
printf
(
"Calling FEP for 2nd slot
\n
"
);
fep0
(
eNB
,
1
);
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_fep
,
&
wait
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_mutex_lock for fep thread %d (IC %d)
\n
"
,
proc
->
instance_cnt_fep
);
exit_fun
(
"error locking mutex_fep"
);
return
;
}
while
(
proc
->
instance_cnt_fep
==
0
)
{
wait_cnt
++
;
if
(
wait_cnt
>
10000
)
break
;
};
pthread_mutex_unlock
(
&
proc
->
mutex_fep
);
if
(
wait_cnt
>
10000
)
{
printf
(
"[eNB] parallel FEP didn't finish
\n
"
);
exit_fun
(
"error"
);
}
}
void
eNB_fep_full
(
PHY_VARS_eNB
*
eNB
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
...
...
openair1/SIMULATION/LTE_PHY/ulsim.c
View file @
eee157ee
...
...
@@ -85,6 +85,8 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */
int
n_tx_dropped
=
0
;
/*!< \brief initial max process time for tx */
int
n_rx_dropped
=
0
;
/*!< \brief initial max process time for rx */
int
oai_exit
=
0
;
void
fill_ulsch_dci
(
PHY_VARS_eNB
*
eNB
,
void
*
UL_dci
,
int
first_rb
,
int
nb_rb
,
int
mcs
,
int
ndi
,
int
cqi_flag
)
{
...
...
@@ -171,6 +173,7 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mc
}
extern
void
eNB_fep_full
(
PHY_VARS_eNB
*
eNB
);
extern
void
eNB_fep_full_2thread
(
PHY_VARS_eNB
*
eNB
);
int
main
(
int
argc
,
char
**
argv
)
{
...
...
@@ -688,6 +691,8 @@ int main(int argc, char **argv)
eNB
->
ulsch
[
0
]
=
new_eNB_ulsch
(
max_turbo_iterations
,
N_RB_DL
,
0
);
UE
->
ulsch
[
0
]
=
new_ue_ulsch
(
N_RB_DL
,
0
);
init_fep_thread
(
eNB
,
&
eNB
->
proc
.
attr_fep
);
// Create transport channel structures for 2 transport blocks (MIMO)
for
(
i
=
0
;
i
<
2
;
i
++
)
{
eNB
->
dlsch
[
0
][
i
]
=
new_eNB_dlsch
(
1
,
8
,
1827072
,
N_RB_DL
,
0
);
...
...
@@ -1181,7 +1186,7 @@ int main(int argc, char **argv)
}
eNB
->
fep
=
eNB_fep_full
;
eNB
->
fep
=
eNB_fep_full
_2thread
;
eNB
->
do_prach
=
NULL
;
phy_procedures_eNB_common_RX
(
eNB
);
...
...
@@ -1700,6 +1705,9 @@ int main(int argc, char **argv)
}
//ch realization
oai_exit
=
1
;
pthread_cond_signal
(
&
eNB
->
proc
.
cond_fep
);
if
(
abstx
)
{
// ABSTRACTION
fprintf
(
csv_fdUL
,
"];"
);
fclose
(
csv_fdUL
);
...
...
targets/RT/USER/lte-enb.c
View file @
eee157ee
...
...
@@ -1329,6 +1329,7 @@ static void* eNB_thread_single( void* param ) {
}
extern
void
init_fep_thread
(
PHY_VARS_eNB
*
,
pthread_attr_t
*
);
void
init_eNB_proc
(
int
inst
)
{
...
...
@@ -1337,7 +1338,7 @@ void init_eNB_proc(int inst) {
PHY_VARS_eNB
*
eNB
;
eNB_proc_t
*
proc
;
eNB_rxtx_proc_t
*
proc_rxtx
;
pthread_attr_t
*
attr0
=
NULL
,
*
attr1
=
NULL
,
*
attr_FH
=
NULL
,
*
attr_prach
=
NULL
,
*
attr_asynch
=
NULL
,
*
attr_single
=
NULL
;
pthread_attr_t
*
attr0
=
NULL
,
*
attr1
=
NULL
,
*
attr_FH
=
NULL
,
*
attr_prach
=
NULL
,
*
attr_asynch
=
NULL
,
*
attr_single
=
NULL
,
*
attr_fep
=
NULL
;
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
eNB
=
PHY_vars_eNB_g
[
inst
][
CC_id
];
...
...
@@ -1373,6 +1374,7 @@ void init_eNB_proc(int inst) {
attr_prach
=
&
proc
->
attr_prach
;
attr_asynch
=
&
proc
->
attr_asynch_rxtx
;
attr_single
=
&
proc
->
attr_single
;
attr_fep
=
&
proc
->
attr_fep
;
#endif
if
(
eNB
->
single_thread_flag
==
0
)
{
...
...
@@ -1380,9 +1382,10 @@ void init_eNB_proc(int inst) {
pthread_create
(
&
proc_rxtx
[
1
].
pthread_rxtx
,
attr1
,
eNB_thread_rxtx
,
&
proc_rxtx
[
1
]
);
pthread_create
(
&
proc
->
pthread_FH
,
attr_FH
,
eNB_thread_FH
,
&
eNB
->
proc
);
}
else
else
{
pthread_create
(
&
proc
->
pthread_single
,
attr_single
,
eNB_thread_single
,
&
eNB
->
proc
);
init_fep_thread
(
eNB
,
attr_fep
);
}
pthread_create
(
&
proc
->
pthread_prach
,
attr_prach
,
eNB_thread_prach
,
&
eNB
->
proc
);
if
((
eNB
->
node_timing
==
synch_to_other
)
||
(
eNB
->
node_function
==
NGFI_RRU_IF5
)
||
...
...
@@ -1631,7 +1634,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
break
;
case
NGFI_RRU_IF4p5
:
eNB
->
do_prach
=
do_prach
;
eNB
->
fep
=
eNB_fep_full
;
eNB
->
fep
=
(
eNB
->
single_thread_flag
==
0
)
?
NB_fep_full
:
eNB_fep_full_2thread
;
eNB
->
proc_uespec_rx
=
NULL
;
eNB
->
proc_tx
=
NULL
;
//proc_tx_rru_if4p5;
eNB
->
tx_fh
=
NULL
;
...
...
@@ -1658,7 +1661,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
break
;
case
eNodeB_3GPP
:
eNB
->
do_prach
=
do_prach
;
eNB
->
fep
=
eNB_fep_full
;
eNB
->
fep
=
(
eNB
->
single_thread_flag
==
0
)
?
NB_fep_full
:
eNB_fep_full_2thread
;
eNB
->
proc_uespec_rx
=
phy_procedures_eNB_uespec_RX
;
eNB
->
proc_tx
=
proc_tx_full
;
eNB
->
tx_fh
=
NULL
;
...
...
@@ -1676,7 +1679,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
break
;
case
eNodeB_3GPP_BBU
:
eNB
->
do_prach
=
do_prach
;
eNB
->
fep
=
eNB_fep_full
;
eNB
->
fep
=
(
eNB
->
single_thread_flag
==
0
)
?
NB_fep_full
:
eNB_fep_full_2thread
;
eNB
->
proc_uespec_rx
=
phy_procedures_eNB_uespec_RX
;
eNB
->
proc_tx
=
proc_tx_full
;
eNB
->
tx_fh
=
tx_fh_if5
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment