Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
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
lizhongxiao
OpenXG-RAN
Commits
90b773a4
Commit
90b773a4
authored
Jan 11, 2024
by
mir
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decoding in RF Sim working
parent
3f3a9869
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1159 additions
and
38 deletions
+1159
-38
CMakeLists.txt
CMakeLists.txt
+2
-0
common/utils/thread_pool/README.md
common/utils/thread_pool/README.md
+7
-0
common/utils/thread_pool/dyntickless.sh
common/utils/thread_pool/dyntickless.sh
+63
-0
common/utils/thread_pool/main.c
common/utils/thread_pool/main.c
+115
-0
common/utils/thread_pool/task.h
common/utils/thread_pool/task.h
+10
-0
common/utils/thread_pool/task_manager.c
common/utils/thread_pool/task_manager.c
+649
-0
common/utils/thread_pool/task_manager.h
common/utils/thread_pool/task_manager.h
+85
-0
executables/nr-gnb.c
executables/nr-gnb.c
+15
-0
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+5
-2
openair1/PHY/NR_TRANSPORT/nr_ulsch.h
openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+6
-1
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+44
-14
openair1/PHY/defs_gNB.h
openair1/PHY/defs_gNB.h
+12
-1
openair1/SCHED_NR/phy_procedures_nr_gNB.c
openair1/SCHED_NR/phy_procedures_nr_gNB.c
+69
-3
openair1/SIMULATION/NR_PHY/ulschsim.c
openair1/SIMULATION/NR_PHY/ulschsim.c
+46
-4
openair2/LAYER2/NR_MAC_UE/config_ue.c
openair2/LAYER2/NR_MAC_UE/config_ue.c
+2
-1
openair3/UICC/usim_interface.c
openair3/UICC/usim_interface.c
+29
-12
No files found.
CMakeLists.txt
View file @
90b773a4
...
...
@@ -650,6 +650,7 @@ add_library(UTIL
${
OPENAIR2_DIR
}
/UTIL/MATH/oml.c
${
OPENAIR2_DIR
}
/UTIL/OPT/probe.c
${
OPENAIR_DIR
}
/common/utils/threadPool/thread-pool.c
${
OPENAIR_DIR
}
/common/utils/thread_pool/task_manager.c
${
OPENAIR_DIR
}
/common/utils/utils.c
${
OPENAIR_DIR
}
/common/utils/system.c
${
OPENAIR_DIR
}
/common/utils/time_meas.c
...
...
@@ -2054,6 +2055,7 @@ add_executable(nr-softmodem
${
rrc_h
}
${
nr_rrc_h
}
${
s1ap_h
}
# ${OPENAIR_BIN_DIR}/messages_xml.h
${
OPENAIR_DIR
}
/executables/nr-gnb.c
${
OPENAIR_DIR
}
/executables/nr-ru.c
${
OPENAIR_DIR
}
/executables/nr-softmodem.c
...
...
common/utils/thread_pool/README.md
0 → 100644
View file @
90b773a4
Thread Pool implemented in C following the talk of Sean Parent "Better Code: Concurrency" from 2016
dyntickless contains the script to run if low-latency is needed
Remember that isolcpus, rcu_nocbs-4-7, nohz_full=4-7 and rcu_nocb_poll is needed.
The Kernel needs to be compiled appropiattely
common/utils/thread_pool/dyntickless.sh
0 → 100755
View file @
90b773a4
#!/bin/bash
# Full dyntick CPU on which we'll run the user loop,
# it must be part of nohz_full kernel parameter
TARGET
=
4
# Migrate all possible tasks to CPU 0
for
P
in
$(
ls
/proc
)
do
if
[
-x
"/proc/
$P
/task/"
]
then
echo
$P
taskset
-acp
0
$P
fi
done
# Migrate irqs to CPU 0
for
D
in
$(
ls
/proc/irq
)
do
if
[[
-x
"/proc/irq/
$D
"
&&
$D
!=
"0"
]]
then
echo
$D
echo
1
>
/proc/irq/
$D
/smp_affinity
fi
done
# Delay the annoying vmstat timer far away
sysctl vm.stat_interval
=
120
# Shutdown nmi watchdog as it uses perf events
sysctl
-w
kernel.watchdog
=
0
# Remove -rt task runtime limit
echo
-1
>
/proc/sys/kernel/sched_rt_runtime_us
# Pin the writeback workqueue to CPU0
echo
1
>
/sys/bus/workqueue/devices/writeback/cpumask
DIR
=
/sys/kernel/debug/tracing
echo
>
$DIR
/trace
echo
0
>
$DIR
/tracing_on
# Uncomment the below for more details on what disturbs the CPU
echo
0
>
$DIR
/events/irq/enable
echo
1
>
$DIR
/events/sched/sched_switch/enable
echo
1
>
$DIR
/events/workqueue/workqueue_queue_work/enable
echo
1
>
$DIR
/events/workqueue/workqueue_execute_start/enable
echo
1
>
$DIR
/events/timer/hrtimer_expire_entry/enable
echo
1
>
$DIR
/events/timer/tick_stop/enable
echo
nop
>
$DIR
/current_tracer
echo
1
>
$DIR
/tracing_on
# Run a 10 secs user loop on target
taskset
-c
3-7 ./a.out
#sleep 20
#killall a.out
# Checkout the trace in trace.* file
cat
/sys/kernel/debug/tracing/per_cpu/cpu4/trace
>
trace.4
cat
/sys/kernel/debug/tracing/per_cpu/cpu5/trace
>
trace.5
cat
/sys/kernel/debug/tracing/per_cpu/cpu6/trace
>
trace.6
cat
/sys/kernel/debug/tracing/per_cpu/cpu7/trace
>
trace.7
common/utils/thread_pool/main.c
0 → 100644
View file @
90b773a4
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "task_manager.h"
#define NUM_THREADS 4
#define NUM_JOBS 1024*1024
int64_t
time_now_us
(
void
)
{
struct
timespec
tms
;
/* The C11 way */
/* if (! timespec_get(&tms, TIME_UTC)) */
/* POSIX.1-2008 way */
if
(
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tms
))
{
return
-
1
;
}
/* seconds, multiplied with 1 million */
int64_t
micros
=
tms
.
tv_sec
*
1000000
;
/* Add full microseconds */
int64_t
const
tv_nsec
=
tms
.
tv_nsec
;
micros
+=
tv_nsec
/
1000
;
/* round up if necessary */
if
(
tv_nsec
%
1000
>=
500
)
{
++
micros
;
}
return
micros
;
}
typedef
struct
{
int64_t
a
;
int64_t
time
;
task_ans_t
*
ans
;
}
pair_t
;
static
inline
int64_t
naive_fibonnacci
(
int64_t
a
)
{
assert
(
a
<
1000
);
if
(
a
<
2
)
return
a
;
return
naive_fibonnacci
(
a
-
1
)
+
naive_fibonnacci
(
a
-
2
);
}
//static _Thread_local int64_t counter = 0;
static
int
marker_fd
;
void
do_work
(
void
*
arg
)
{
//int64_t now = time_now_us();
pair_t
*
a
=
(
pair_t
*
)
arg
;
naive_fibonnacci
(
23
+
a
->
a
);
completed_task_ans
(
a
->
ans
);
//int64_t stop = time_now_us();
//char buffer[100] = {0};
//int ret = snprintf(buffer, 100, "ID %lu Fib elapsed %ld start-stop %ld - %ld \n", pthread_self(), stop - now, now, stop);
//assert(ret > 0 && ret < 100);
// write_marker_ft_mir(marker_fd, buffer);
// puts(buffer);
}
int
main
()
{
task_manager_t
man
=
{
0
};
init_task_manager
(
&
man
,
NUM_THREADS
);
usleep
(
100
);
pair_t
*
arr
=
calloc
(
NUM_JOBS
,
sizeof
(
pair_t
));
assert
(
arr
!=
NULL
);
task_ans_t
*
ans
=
calloc
(
NUM_JOBS
,
sizeof
(
task_ans_t
));
assert
(
ans
!=
NULL
);
int64_t
now
=
time_now_us
();
for
(
int
i
=
0
;
i
<
NUM_JOBS
;
++
i
){
pair_t
*
pa
=
&
arr
[
i
];
pa
->
a
=
0
;
//i%10;
pa
->
time
=
0
;
pa
->
ans
=
&
ans
[
i
];
task_t
t
=
{.
args
=
pa
,
t
.
func
=
do_work
};
async_task_manager
(
&
man
,
t
);
}
printf
(
"Waiting %ld
\n
"
,
time_now_us
());
join_task_ans
(
ans
,
NUM_JOBS
);
printf
(
"Done %ld
\n
"
,
time_now_us
());
free_task_manager
(
&
man
,
NULL
);
printf
(
"Total elapsed %ld
\n
"
,
time_now_us
()
-
now
);
free
(
arr
);
return
EXIT_SUCCESS
;
}
common/utils/thread_pool/task.h
0 → 100644
View file @
90b773a4
#ifndef TASK_WORK_STEALING_THREAD_POOL_H
#define TASK_WORK_STEALING_THREAD_POOL_H
typedef
struct
{
void
*
args
;
void
(
*
func
)(
void
*
args
);
}
task_t
;
#endif
common/utils/thread_pool/task_manager.c
0 → 100644
View file @
90b773a4
#define _GNU_SOURCE
#include <unistd.h>
#include "task_manager.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <fcntl.h>
#include <linux/futex.h>
/* Definition of FUTEX_* constants */
#include <sys/syscall.h>
/* Definition of SYS_* constants */
#include <unistd.h>
#include <ctype.h> // toupper
#if defined (__i386__) || defined(__x86_64__)
#define pause_or_yield __builtin_ia32_pause
#elif __aarch64__
#define pause_or_yield() asm volatile("yield" ::: "memory")
#else
static_assert
(
0
!=
0
,
"Unknown CPU architecture"
);
#endif
/*
static
int64_t time_now_us(void)
{
struct timespec tms;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &tms)) {
return -1;
}
int64_t micros = tms.tv_sec * 1000000;
int64_t const tv_nsec = tms.tv_nsec;
micros += tv_nsec/1000;
if (tv_nsec % 1000 >= 500) {
++micros;
}
return micros;
}
static
void pin_thread_to_core(int core_num)
{
cpu_set_t set = {0};
CPU_ZERO(&set);
CPU_SET(core_num, &set);
int ret = sched_setaffinity(gettid(), sizeof(set), &set);
assert(ret != -1);
printf("Pining into core %d id %ld \n", core_num, pthread_self());
}
*/
//////////////////////////////
//////////////////////////////
////////// RING //
//////////////////////////////
//////////////////////////////
//////////////////////////////
// For working correctly, maintain the default elements to a 2^N e.g., 2^5=32
#define DEFAULT_ELM 32
typedef
struct
seq_ring_buf_s
{
// const size_t elt_size;
task_t
*
array
;
size_t
cap
;
uint32_t
head
;
uint32_t
tail
;
_Atomic
uint64_t
sz
;
}
seq_ring_task_t
;
typedef
void
(
*
seq_free_func
)(
task_t
*
);
static
size_t
size_seq_ring_task
(
seq_ring_task_t
*
r
)
{
assert
(
r
!=
NULL
);
return
r
->
head
-
r
->
tail
;
}
inline
static
uint32_t
mask
(
uint32_t
cap
,
uint32_t
val
)
{
return
val
&
(
cap
-
1
);
}
static
bool
full
(
seq_ring_task_t
*
r
)
{
return
size_seq_ring_task
(
r
)
==
r
->
cap
-
1
;
}
static
void
enlarge_buffer
(
seq_ring_task_t
*
r
)
{
assert
(
r
!=
NULL
);
assert
(
full
(
r
));
const
uint32_t
factor
=
2
;
task_t
*
tmp_buffer
=
calloc
(
r
->
cap
*
factor
,
sizeof
(
task_t
)
);
assert
(
tmp_buffer
!=
NULL
);
const
uint32_t
head_pos
=
mask
(
r
->
cap
,
r
->
head
);
const
uint32_t
tail_pos
=
mask
(
r
->
cap
,
r
->
tail
);
if
(
head_pos
>
tail_pos
){
memcpy
(
tmp_buffer
,
r
->
array
+
tail_pos
,
(
head_pos
-
tail_pos
)
*
sizeof
(
task_t
)
);
}
else
{
memcpy
(
tmp_buffer
,
r
->
array
+
tail_pos
,
(
r
->
cap
-
tail_pos
)
*
sizeof
(
task_t
));
memcpy
(
tmp_buffer
+
(
r
->
cap
-
tail_pos
),
r
->
array
,
head_pos
*
sizeof
(
task_t
));
}
r
->
cap
*=
factor
;
free
(
r
->
array
);
r
->
array
=
tmp_buffer
;
r
->
tail
=
0
;
r
->
head
=
r
->
cap
/
2
-
1
;
}
static
void
init_seq_ring_task
(
seq_ring_task_t
*
r
)
{
assert
(
r
!=
NULL
);
task_t
*
tmp_buffer
=
calloc
(
DEFAULT_ELM
,
sizeof
(
task_t
));
assert
(
tmp_buffer
!=
NULL
);
seq_ring_task_t
tmp
=
{.
array
=
tmp_buffer
,
.
head
=
0
,
.
tail
=
0
,
.
cap
=
DEFAULT_ELM
};
memcpy
(
r
,
&
tmp
,
sizeof
(
seq_ring_task_t
));
r
->
sz
=
0
;
}
static
void
free_seq_ring_task
(
seq_ring_task_t
*
r
,
seq_free_func
fp
)
{
assert
(
r
!=
NULL
);
assert
(
fp
==
NULL
);
free
(
r
->
array
);
}
static
void
push_back_seq_ring_task
(
seq_ring_task_t
*
r
,
task_t
t
)
{
assert
(
r
!=
NULL
);
if
(
full
(
r
))
enlarge_buffer
(
r
);
const
uint32_t
pos
=
mask
(
r
->
cap
,
r
->
head
);
r
->
array
[
pos
]
=
t
;
r
->
head
+=
1
;
r
->
sz
+=
1
;
}
static
task_t
pop_seq_ring_task
(
seq_ring_task_t
*
r
)
{
assert
(
r
!=
NULL
);
assert
(
size_seq_ring_task
(
r
)
>
0
);
const
uint32_t
pos
=
mask
(
r
->
cap
,
r
->
tail
);
task_t
t
=
r
->
array
[
pos
];
r
->
tail
+=
1
;
r
->
sz
-=
1
;
return
t
;
}
#undef DEFAULT_ELM
//////////////////////////////
//////////////////////////////
////////// END RING //
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
////////// Start Notification Queue //
//////////////////////////////
//////////////////////////////
//////////////////////////////
typedef
struct
{
pthread_mutex_t
mtx
;
pthread_cond_t
cv
;
seq_ring_task_t
r
;
// _Atomic int32_t* futex;
//_Atomic bool* waiting;
_Atomic
int
done
;
}
not_q_t
;
typedef
struct
{
task_t
t
;
bool
success
;
}
ret_try_t
;
static
void
init_not_q
(
not_q_t
*
q
/*, _Atomic int32_t* futex , _Atomic bool* waiting */
)
{
assert
(
q
!=
NULL
);
q
->
done
=
0
;
//q->waiting = waiting;
init_seq_ring_task
(
&
q
->
r
);
pthread_mutexattr_t
attr
=
{
0
};
#ifdef _DEBUG
int
const
rc_mtx
=
pthread_mutexattr_settype
(
&
attr
,
PTHREAD_MUTEX_ERRORCHECK
);
assert
(
rc_mtx
==
0
);
#endif
int
rc
=
pthread_mutex_init
(
&
q
->
mtx
,
&
attr
);
assert
(
rc
==
0
&&
"Error while creating the mtx"
);
pthread_condattr_t
*
c_attr
=
NULL
;
rc
=
pthread_cond_init
(
&
q
->
cv
,
c_attr
);
assert
(
rc
==
0
);
//q->futex = futex;
}
static
void
free_not_q
(
not_q_t
*
q
,
void
(
*
clean
)(
task_t
*
)
)
{
assert
(
q
!=
NULL
);
assert
(
q
->
done
==
1
);
free_seq_ring_task
(
&
q
->
r
,
clean
);
int
rc
=
pthread_mutex_destroy
(
&
q
->
mtx
);
assert
(
rc
==
0
);
rc
=
pthread_cond_destroy
(
&
q
->
cv
);
assert
(
rc
==
0
);
}
static
bool
try_push_not_q
(
not_q_t
*
q
,
task_t
t
)
{
assert
(
q
!=
NULL
);
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
assert
(
t
.
func
!=
NULL
);
assert
(
t
.
args
!=
NULL
);
if
(
pthread_mutex_trylock
(
&
q
->
mtx
)
!=
0
)
return
false
;
push_back_seq_ring_task
(
&
q
->
r
,
t
);
pthread_cond_signal
(
&
q
->
cv
);
int
const
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
return
true
;
}
static
void
push_not_q
(
not_q_t
*
q
,
task_t
t
)
{
assert
(
q
!=
NULL
);
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
assert
(
t
.
func
!=
NULL
);
int
const
rc
=
pthread_mutex_lock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
push_back_seq_ring_task
(
&
q
->
r
,
t
);
pthread_cond_signal
(
&
q
->
cv
);
pthread_mutex_unlock
(
&
q
->
mtx
);
}
static
ret_try_t
try_pop_not_q
(
not_q_t
*
q
)
{
assert
(
q
!=
NULL
);
ret_try_t
ret
=
{.
success
=
false
};
int
rc
=
pthread_mutex_trylock
(
&
q
->
mtx
);
assert
(
rc
==
0
||
rc
==
EBUSY
);
if
(
rc
==
EBUSY
)
return
ret
;
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
size_t
sz
=
size_seq_ring_task
(
&
q
->
r
);
if
(
sz
==
0
){
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
return
ret
;
}
assert
(
sz
>
0
);
ret
.
t
=
pop_seq_ring_task
(
&
q
->
r
);
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
ret
.
success
=
true
;
return
ret
;
}
static
bool
pop_not_q
(
not_q_t
*
q
,
ret_try_t
*
out
)
{
assert
(
q
!=
NULL
);
assert
(
out
!=
NULL
);
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
int
rc
=
pthread_mutex_lock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
while
(
size_seq_ring_task
(
&
q
->
r
)
==
0
&&
q
->
done
==
0
)
pthread_cond_wait
(
&
q
->
cv
,
&
q
->
mtx
);
/*
// Let's be conservative and not use memory_order_relaxed
// while (atomic_load_explicit(q->waiting, memory_order_seq_cst) == true){ //
// Issue X86 PAUSE or ARM YIELD instruction to reduce contention between
// hyper-threads
// pause_or_yield();
// }
pthread_mutex_lock(&q->mtx);
if(size_seq_ring_task(&q->r) == 0 && q->done == 0){
int rc = pthread_mutex_unlock(&q->mtx);
assert(rc == 0);
int val = atomic_load_explicit(q->futex, memory_order_acquire);
long r = syscall(SYS_futex, q->futex, FUTEX_WAIT_PRIVATE, val, NULL, 0);
assert(r != -1);
goto label;
}
*/
//printf("Waking %ld id %ld \n", time_now_us(), pthread_self());
assert
(
q
->
done
==
0
||
q
->
done
==
1
);
if
(
q
->
done
==
1
){
//printf("Done, returning \n");
int
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
return
false
;
}
out
->
t
=
pop_seq_ring_task
(
&
q
->
r
);
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
return
true
;
}
static
void
done_not_q
(
not_q_t
*
q
)
{
assert
(
q
!=
NULL
);
int
rc
=
pthread_mutex_lock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
q
->
done
=
1
;
rc
=
pthread_cond_signal
(
&
q
->
cv
);
assert
(
rc
==
0
);
//long r = syscall(SYS_futex, q->futex, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0);
//assert(r != -1);
rc
=
pthread_mutex_unlock
(
&
q
->
mtx
);
assert
(
rc
==
0
);
// q->futex++;
}
//////////////////////////////
//////////////////////////////
////////// END Notification Queue //
//////////////////////////////
//////////////////////////////
//////////////////////////////
//static int marker_fd;
typedef
struct
{
task_manager_t
*
man
;
int
idx
;
}
task_thread_args_t
;
// Just for debugging purposes, it is very slow!!!!
//static
//_Atomic int cnt_out = 0;
//static
//_Atomic int cnt_in = 0;
static
void
*
worker_thread
(
void
*
arg
)
{
assert
(
arg
!=
NULL
);
task_thread_args_t
*
args
=
(
task_thread_args_t
*
)
arg
;
int
const
idx
=
args
->
idx
;
//int const log_cores = get_nprocs_conf();
//assert(log_cores > 0);
// Assuming: 2 x Physical cores = Logical cores
//pin_thread_to_core(idx+log_cores/2);
task_manager_t
*
man
=
args
->
man
;
uint32_t
const
len
=
man
->
len_thr
;
uint32_t
const
num_it
=
2
*
(
man
->
len_thr
+
idx
);
not_q_t
*
q_arr
=
(
not_q_t
*
)
man
->
q_arr
;
int
acc_num_task
=
0
;
for
(;;){
ret_try_t
ret
=
{.
success
=
false
};
for
(
uint32_t
i
=
idx
;
i
<
num_it
;
++
i
){
ret
=
try_pop_not_q
(
&
q_arr
[
i
%
len
]);
if
(
ret
.
success
==
true
){
break
;
}
}
if
(
ret
.
success
==
false
){
man
->
num_task
-=
acc_num_task
;
acc_num_task
=
0
;
if
(
pop_not_q
(
&
q_arr
[
idx
],
&
ret
)
==
false
)
break
;
}
//int64_t now = time_now_us();
//printf("Calling fuinc \n");
ret
.
t
.
func
(
ret
.
t
.
args
);
//printf("Returning from func \n");
//int64_t stop = time_now_us();
//cnt_out++;
//printf("Tasks out %d %ld \n", cnt_out, time_now_us());
acc_num_task
+=
1
;
}
free
(
args
);
return
NULL
;
}
void
init_task_manager
(
task_manager_t
*
man
,
size_t
num_threads
)
{
assert
(
man
!=
NULL
);
assert
(
num_threads
>
0
&&
num_threads
<
33
&&
"Do you have zero or more than 32 processors??"
);
printf
(
"[MIR]: number of threads %ld
\n
"
,
num_threads
);
man
->
q_arr
=
calloc
(
num_threads
,
sizeof
(
not_q_t
));
assert
(
man
->
q_arr
!=
NULL
&&
"Memory exhausted"
);
not_q_t
*
q_arr
=
(
not_q_t
*
)
man
->
q_arr
;
for
(
size_t
i
=
0
;
i
<
num_threads
;
++
i
){
init_not_q
(
&
q_arr
[
i
]);
}
man
->
t_arr
=
calloc
(
num_threads
,
sizeof
(
pthread_t
));
assert
(
man
->
t_arr
!=
NULL
&&
"Memory exhausted"
);
man
->
len_thr
=
num_threads
;
for
(
size_t
i
=
0
;
i
<
num_threads
;
++
i
){
task_thread_args_t
*
args
=
malloc
(
sizeof
(
task_thread_args_t
)
);
args
->
idx
=
i
;
args
->
man
=
man
;
pthread_attr_t
attr
=
{
0
};
/*
int ret=pthread_attr_init(&attr);
assert(ret == 0);
ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
assert(ret == 0);
ret=pthread_attr_setschedpolicy(&attr, SCHED_RR);
assert(ret == 0);
struct sched_param sparam={0};
sparam.sched_priority = 94;
ret=pthread_attr_setschedparam(&attr, &sparam);
*/
int
rc
=
pthread_create
(
&
man
->
t_arr
[
i
],
&
attr
,
worker_thread
,
args
);
assert
(
rc
==
0
&&
"Error creating a thread"
);
}
man
->
index
=
0
;
//pin_thread_to_core(3);
}
void
free_task_manager
(
task_manager_t
*
man
,
void
(
*
clean
)(
task_t
*
))
{
not_q_t
*
q_arr
=
(
not_q_t
*
)
man
->
q_arr
;
//atomic_store(&man->waiting, false);
for
(
uint32_t
i
=
0
;
i
<
man
->
len_thr
;
++
i
){
done_not_q
(
&
q_arr
[
i
]);
}
for
(
uint32_t
i
=
0
;
i
<
man
->
len_thr
;
++
i
){
int
rc
=
pthread_join
(
man
->
t_arr
[
i
],
NULL
);
assert
(
rc
==
0
);
}
for
(
uint32_t
i
=
0
;
i
<
man
->
len_thr
;
++
i
){
free_not_q
(
&
q_arr
[
i
],
clean
);
}
free
(
man
->
q_arr
);
free
(
man
->
t_arr
);
}
void
async_task_manager
(
task_manager_t
*
man
,
task_t
t
)
{
assert
(
man
!=
NULL
);
assert
(
man
->
len_thr
>
0
);
assert
(
t
.
func
!=
NULL
);
//assert(t.args != NULL);
uint64_t
const
index
=
man
->
index
++
;
const
uint32_t
len_thr
=
man
->
len_thr
;
not_q_t
*
q_arr
=
(
not_q_t
*
)
man
->
q_arr
;
for
(
uint32_t
i
=
0
;
i
<
len_thr
;
++
i
){
if
(
try_push_not_q
(
&
q_arr
[(
i
+
index
)
%
len_thr
],
t
)){
man
->
num_task
+=
1
;
// Debbugging purposes
//cnt_in++;
//printf("Tasks in %d %ld \n", cnt_in, time_now_us());
return
;
}
}
push_not_q
(
&
q_arr
[
index
%
len_thr
],
t
);
man
->
num_task
+=
1
;
// Debbugging purposes
//cnt_in++;
//printf("Tasks in %d %ld \n", cnt_in, time_now_us());
}
void
completed_task_ans
(
task_ans_t
*
task
)
{
assert
(
task
!=
NULL
);
int
const
task_not_completed
=
0
;
assert
(
atomic_load_explicit
(
&
task
->
status
,
memory_order_acquire
)
==
task_not_completed
&&
"Task already finished?"
);
atomic_store_explicit
(
&
task
->
status
,
1
,
memory_order_release
);
}
// This function does not belong here logically
//
void
join_task_ans
(
task_ans_t
*
arr
,
size_t
len
)
{
assert
(
len
>
0
);
assert
(
arr
!=
NULL
);
// We are believing Fedor
const
struct
timespec
ns
=
{
0
,
1
};
uint64_t
i
=
0
;
int
j
=
len
-
1
;
for
(;
j
!=
-
1
;
i
++
){
for
(;
j
!=
-
1
;
--
j
){
int
const
task_completed
=
1
;
if
(
atomic_load_explicit
(
&
arr
[
j
].
status
,
memory_order_acquire
)
!=
task_completed
)
break
;
}
if
(
i
%
8
==
0
){
nanosleep
(
&
ns
,
NULL
);
}
//sched_yield();
// pause_or_yield();
}
}
// Compatibility with previous TPool
int
parse_num_threads
(
char
const
*
params
)
{
assert
(
params
!=
NULL
);
char
*
saveptr
=
NULL
;
char
*
params_cpy
=
strdup
(
params
);
char
*
curptr
=
strtok_r
(
params_cpy
,
","
,
&
saveptr
);
int
nbThreads
=
0
;
while
(
curptr
!=
NULL
)
{
int
const
c
=
toupper
(
curptr
[
0
]);
switch
(
c
)
{
case
'N'
:
{
// pool->activated=false;
free
(
params_cpy
);
return
1
;
break
;
}
default:
{
int
const
core_id
=
atoi
(
curptr
);
printf
(
"[MIR]: Ask to create a thread for core %d ignoring request
\n
"
,
core_id
);
nbThreads
++
;
}
}
curptr
=
strtok_r
(
NULL
,
","
,
&
saveptr
);
}
free
(
params_cpy
);
return
nbThreads
;
}
#undef pause_or_yield
common/utils/thread_pool/task_manager.h
0 → 100644
View file @
90b773a4
#ifndef TASK_MANAGER_WORKING_STEALING_H
#define TASK_MANAGER_WORKING_STEALING_H
// Comment for deactivating ws tpool
#define TASK_MANAGER_DECODING
//#define TASK_MANAGER_DEMODULATION
//#define TASK_MANAGER_CODING
//#define TASK_MANAGER_RU
//#define TASK_MANAGER_UE
//#define TASK_MANAGER_UE_DECODING
//#define TASK_MANAGER_SIM
//#define TASK_MANAGER_LTE
// LTE
//#define TASK_MANAGER_LTE
#include "task.h"
#ifndef __cplusplus
#include <stdalign.h>
#include <stdatomic.h>
#else
#include <atomic>
#define _Atomic(X) std::atomic< X >
#define _Alignas(X) alignas(X)
#endif
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#if defined (__i386__) || defined(__x86_64__)
#define LEVEL1_DCACHE_LINESIZE 64
#elif __aarch64__
// This is not always true for ARM
// in linux, you can obtain the size at runtime using sysconf (_SC_LEVEL1_DCACHE_LINESIZE)
// in c++ using std::hardware_destructive_interference_size
#define LEVEL1_DCACHE_LINESIZE 64
#else
static_assert
(
0
!=
0
,
"Unknown CPU architecture"
);
#endif
typedef
struct
{
// Avoid false sharing
_Alignas
(
LEVEL1_DCACHE_LINESIZE
)
_Atomic
(
int
)
status
;
}
task_ans_t
;
void
join_task_ans
(
task_ans_t
*
arr
,
size_t
len
);
void
completed_task_ans
(
task_ans_t
*
task
);
typedef
struct
{
uint8_t
*
buf
;
size_t
len
;
task_ans_t
*
ans
;
}
thread_info_tm_t
;
typedef
struct
{
pthread_t
*
t_arr
;
size_t
len_thr
;
_Atomic
(
uint64_t
)
index
;
void
*
q_arr
;
_Atomic
(
uint64_t
)
num_task
;
}
task_manager_t
;
void
init_task_manager
(
task_manager_t
*
man
,
size_t
num_threads
);
void
free_task_manager
(
task_manager_t
*
man
,
void
(
*
clean
)(
task_t
*
args
)
);
void
async_task_manager
(
task_manager_t
*
man
,
task_t
t
);
// Compatibility with previous TPool
int
parse_num_threads
(
char
const
*
params
);
#endif
executables/nr-gnb.c
View file @
90b773a4
...
...
@@ -90,6 +90,8 @@
#include <openair1/PHY/NR_TRANSPORT/nr_dlsch.h>
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
#include "common/utils/thread_pool/task_manager.h"
//#define USRP_DEBUG 1
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
...
...
@@ -366,8 +368,15 @@ void *nrL1_stats_thread(void *param) {
}
void
init_gNB_Tpool
(
int
inst
)
{
PHY_VARS_gNB
*
gNB
;
gNB
=
RC
.
gNB
[
inst
];
#ifdef TASK_MANAGER_DECODING
int
const
num_threads
=
parse_num_threads
(
get_softmodem_params
()
->
threadPoolConfig
);
init_task_manager
(
&
gNB
->
man
,
num_threads
);
#endif
gNB_L1_proc_t
*
proc
=
&
gNB
->
proc
;
// PUSCH symbols per thread need to be calculated by how many threads we have
gNB
->
num_pusch_symbols_per_thread
=
1
;
...
...
@@ -406,7 +415,13 @@ void init_gNB_Tpool(int inst) {
void
term_gNB_Tpool
(
int
inst
)
{
PHY_VARS_gNB
*
gNB
=
RC
.
gNB
[
inst
];
#ifdef TASK_MANAGER_DECODING
void
(
*
clean
)(
task_t
*
)
=
NULL
;
free_task_manager
(
&
gNB
->
man
,
clean
);
#else
abortTpool
(
&
gNB
->
threadPool
);
#endif
abortNotifiedFIFO
(
&
gNB
->
respDecode
);
abortNotifiedFIFO
(
&
gNB
->
resp_L1
);
abortNotifiedFIFO
(
&
gNB
->
L1_tx_free
);
...
...
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
View file @
90b773a4
...
...
@@ -144,6 +144,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) {
void
ldpc8blocks
(
void
*
p
)
{
// assert(0!=0);
encoder_implemparams_t
*
impp
=
(
encoder_implemparams_t
*
)
p
;
NR_DL_gNB_HARQ_t
*
harq
=
(
NR_DL_gNB_HARQ_t
*
)
impp
->
harq
;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t
*
rel15
=
&
harq
->
pdsch_pdu
.
pdsch_pdu_rel15
;
...
...
@@ -383,7 +384,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
r_offset
+=
impp
.
E
;
}
}
else
{
notifiedFIFO_t
nf
;
notifiedFIFO_t
nf
=
{
0
}
;
initNotifiedFIFO
(
&
nf
);
int
nbJobs
=
0
;
for
(
int
j
=
0
;
j
<
(
impp
.
n_segments
/
8
+
((
impp
.
n_segments
&
7
)
==
0
?
0
:
1
));
j
++
)
{
...
...
@@ -391,11 +392,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
encoder_implemparams_t
*
perJobImpp
=
(
encoder_implemparams_t
*
)
NotifiedFifoData
(
req
);
*
perJobImpp
=
impp
;
perJobImpp
->
macro_num
=
j
;
pushTpool
(
&
gNB
->
threadPool
,
req
);
nbJobs
++
;
}
while
(
nbJobs
)
{
notifiedFIFO_elt_t
*
req
=
pullTpool
(
&
nf
,
&
gNB
->
threadPool
);
notifiedFIFO_elt_t
*
req
=
pullNotifiedFIFO
(
&
nf
);
if
(
req
==
NULL
)
break
;
// Tpool has been stopped
delNotifiedFIFO_elt
(
req
);
...
...
openair1/PHY/NR_TRANSPORT/nr_ulsch.h
View file @
90b773a4
...
...
@@ -32,6 +32,7 @@
#include "PHY/defs_gNB.h"
#include "common/utils/threadPool/thread-pool.h"
#include "common/utils/thread_pool/task_manager.h"
void
free_gNB_ulsch
(
NR_gNB_ULSCH_t
*
ulsch
,
uint16_t
N_RB_UL
);
...
...
@@ -57,7 +58,11 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint32_t
frame
,
uint8_t
nr_tti_rx
,
uint8_t
harq_pid
,
uint32_t
G
);
uint32_t
G
#ifdef TASK_MANAGER_DECODING
,
thread_info_tm_t
*
t_info
#endif
);
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param llr, Pointer to llr bits
...
...
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
View file @
90b773a4
...
...
@@ -50,6 +50,11 @@
//#define DEBUG_ULSCH_DECODING
//#define gNB_DEBUG_TRACE
#include "common/utils/thread_pool/task_manager.h"
#include <stdint.h>
#include <time.h>
#include <stdalign.h>
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
//#define DEBUG_CRC
#ifdef DEBUG_CRC
...
...
@@ -180,6 +185,10 @@ static void nr_processULSegment(void *arg)
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate_matching
\n
"
);
rdata
->
decodeIterations
=
max_ldpc_iterations
+
1
;
#ifdef TASK_MANAGER_DECODING
completed_task_ans
(
rdata
->
ans
);
#endif
return
;
}
...
...
@@ -220,6 +229,10 @@ static void nr_processULSegment(void *arg)
if
(
rdata
->
decodeIterations
<=
p_decoderParms
->
numMaxIter
)
memcpy
(
ulsch_harq
->
c
[
r
],
llrProcBuf
,
Kr
>>
3
);
#ifdef TASK_MANAGER_DECODING
completed_task_ans
(
rdata
->
ans
);
#endif
}
int
decode_offload
(
PHY_VARS_gNB
*
phy_vars_gNB
,
...
...
@@ -325,8 +338,13 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint32_t
frame
,
uint8_t
nr_tti_rx
,
uint8_t
harq_pid
,
uint32_t
G
)
{
uint32_t
G
#ifdef TASK_MANAGER_DECODING
// This is a broken idea. But so is the code arquitecture
,
thread_info_tm_t
*
t_info
#endif
)
{
if
(
!
ulsch_llr
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: NULL ulsch_llr pointer
\n
"
);
return
-
1
;
...
...
@@ -434,9 +452,16 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
set_abort
(
&
harq_process
->
abort_decode
,
false
);
for
(
int
r
=
0
;
r
<
harq_process
->
C
;
r
++
)
{
int
E
=
nr_get_E
(
G
,
harq_process
->
C
,
Qm
,
n_layers
,
r
);
#ifdef TASK_MANAGER_DECODING
ldpcDecode_t
*
rdata
=
&
((
ldpcDecode_t
*
)
t_info
->
buf
)[
t_info
->
len
];
assert
(
t_info
->
len
<
16
);
rdata
->
ans
=
&
t_info
->
ans
[
t_info
->
len
];
t_info
->
len
+=
1
;
#else
union
ldpcReqUnion
id
=
{.
s
=
{
ulsch
->
rnti
,
frame
,
nr_tti_rx
,
0
,
0
}};
notifiedFIFO_elt_t
*
req
=
newNotifiedFIFO_elt
(
sizeof
(
ldpcDecode_t
),
id
.
p
,
&
phy_vars_gNB
->
respDecode
,
&
nr_processULSegment
);
ldpcDecode_t
*
rdata
=
(
ldpcDecode_t
*
)
NotifiedFifoData
(
req
);
#endif
decParams
.
R
=
nr_get_R_ldpc_decoder
(
pusch_pdu
->
pusch_data
.
rv_index
,
E
,
decParams
.
BG
,
...
...
@@ -461,7 +486,12 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
rdata
->
ulsch
=
ulsch
;
rdata
->
ulsch_id
=
ULSCH_id
;
rdata
->
tbslbrm
=
pusch_pdu
->
maintenance_parms_v3
.
tbSizeLbrmBytes
;
#ifdef TASK_MANAGER_DECODING
task_t
t
=
{
.
args
=
rdata
,
.
func
=
&
nr_processULSegment
};
async_task_manager
(
&
phy_vars_gNB
->
man
,
t
);
#else
pushTpool
(
&
phy_vars_gNB
->
threadPool
,
req
);
#endif
LOG_D
(
PHY
,
"Added a block to decode, in pipe: %d
\n
"
,
r
);
r_offset
+=
E
;
offset
+=
((
harq_process
->
K
>>
3
)
-
(
harq_process
->
F
>>
3
)
-
((
harq_process
->
C
>
1
)
?
3
:
0
));
...
...
openair1/PHY/defs_gNB.h
View file @
90b773a4
...
...
@@ -43,6 +43,7 @@
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#include "executables/rt_profiling.h"
#include "nfapi_nr_interface_scf.h"
#include "common/utils/thread_pool/task_manager.h"
#define MAX_NUM_RU_PER_gNB 8
#define MAX_PUCCH0_NID 8
...
...
@@ -718,7 +719,6 @@ typedef struct PHY_VARS_gNB_s {
notifiedFIFO_t
L1_tx_out
;
notifiedFIFO_t
L1_rx_out
;
notifiedFIFO_t
resp_RU_tx
;
tpool_t
threadPool
;
int
nbSymb
;
int
num_pusch_symbols_per_thread
;
pthread_t
L1_rx_thread
;
...
...
@@ -729,6 +729,14 @@ typedef struct PHY_VARS_gNB_s {
void
*
scopeData
;
/// structure for analyzing high-level RT measurements
rt_L1_profiling_t
rt_L1_profiling
;
#if defined(TASK_MANAGER_DECODING) && defined(TASK_MANAGER_CODING) && defined(TASK_MANAGER_DEMODULATION) && defined(TASK_MANAGER_RU) && defined(TASK_MANAGER_SIM)
task_manager_t
man
;
#elif !defined(TASK_MANAGER_DECODING) || !defined(TASK_MANAGER_CODING) || !defined(TASK_MANAGER_DEMODULATION) || !defined(TASK_MANAGER_RU) || !defined(TASK_MANAGER_SIM)
task_manager_t
man
;
tpool_t
threadPool
;
#else
tpool_t
threadPool
;
#endif
}
PHY_VARS_gNB
;
typedef
struct
puschSymbolProc_s
{
...
...
@@ -777,6 +785,9 @@ typedef struct LDPCDecode_s {
int
offset
;
int
decodeIterations
;
uint32_t
tbslbrm
;
#ifdef TASK_MANAGER_DECODING
task_ans_t
*
ans
;
#endif
}
ldpcDecode_t
;
struct
ldpcReqId
{
...
...
openair1/SCHED_NR/phy_procedures_nr_gNB.c
View file @
90b773a4
...
...
@@ -43,6 +43,20 @@
#include "assertions.h"
#include <time.h>
#include <stdint.h>
static
int64_t
time_now_ns
(
void
)
{
struct
timespec
tms
;
if
(
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tms
))
{
return
-
1
;
}
int64_t
nanos
=
tms
.
tv_sec
*
1000000000
+
tms
.
tv_nsec
;
return
nanos
;
}
//#define DEBUG_RXDATA
//#define SRS_IND_DEBUG
...
...
@@ -240,9 +254,14 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX
+
gNB
->
CC_id
,
0
);
}
#ifdef TASK_MANAGER_DECODING
static
void
nr_postDecode
(
PHY_VARS_gNB
*
gNB
,
ldpcDecode_t
*
rdata
)
{
#else
static
void
nr_postDecode
(
PHY_VARS_gNB
*
gNB
,
notifiedFIFO_elt_t
*
req
)
{
ldpcDecode_t
*
rdata
=
(
ldpcDecode_t
*
)
NotifiedFifoData
(
req
);
#endif
NR_UL_gNB_HARQ_t
*
ulsch_harq
=
rdata
->
ulsch_harq
;
NR_gNB_ULSCH_t
*
ulsch
=
rdata
->
ulsch
;
int
r
=
rdata
->
segment_r
;
...
...
@@ -355,7 +374,11 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
}
}
#ifdef TASK_MANAGER_DECODING
static
int
nr_ulsch_procedures
(
PHY_VARS_gNB
*
gNB
,
int
frame_rx
,
int
slot_rx
,
int
ULSCH_id
,
uint8_t
harq_pid
,
thread_info_tm_t
*
t_info
)
#else
static
int
nr_ulsch_procedures
(
PHY_VARS_gNB
*
gNB
,
int
frame_rx
,
int
slot_rx
,
int
ULSCH_id
,
uint8_t
harq_pid
)
#endif
{
NR_DL_FRAME_PARMS
*
frame_parms
=
&
gNB
->
frame_parms
;
nfapi_nr_pusch_pdu_t
*
pusch_pdu
=
&
gNB
->
ulsch
[
ULSCH_id
].
harq_process
->
ulsch_pdu
;
...
...
@@ -401,8 +424,12 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
int
nbDecode
=
nr_ulsch_decoding
(
gNB
,
ULSCH_id
,
gNB
->
pusch_vars
[
ULSCH_id
].
llr
,
frame_parms
,
pusch_pdu
,
frame_rx
,
slot_rx
,
harq_pid
,
G
);
start_meas
(
&
gNB
->
ulsch_decoding_stats
);
#ifdef TASK_MANAGER_DECODING
int
const
nbDecode
=
nr_ulsch_decoding
(
gNB
,
ULSCH_id
,
gNB
->
pusch_vars
[
ULSCH_id
].
llr
,
frame_parms
,
pusch_pdu
,
frame_rx
,
slot_rx
,
harq_pid
,
G
,
t_info
);
#else
int
const
nbDecode
=
nr_ulsch_decoding
(
gNB
,
ULSCH_id
,
gNB
->
pusch_vars
[
ULSCH_id
].
llr
,
frame_parms
,
pusch_pdu
,
frame_rx
,
slot_rx
,
harq_pid
,
G
);
#endif
return
nbDecode
;
}
...
...
@@ -737,6 +764,10 @@ int check_srs_pdu(const nfapi_nr_srs_pdu_t *srs_pdu, nfapi_nr_srs_pdu_t *saved_s
return
0
;
}
static
int
cnt
=
0
;
int
phy_procedures_gNB_uespec_RX
(
PHY_VARS_gNB
*
gNB
,
int
frame_rx
,
int
slot_rx
)
{
/* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
...
...
@@ -836,6 +867,13 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
}
#ifdef TASK_MANAGER_DECODING
ldpcDecode_t
arr
[
16
];
task_ans_t
ans
[
16
]
=
{
0
};
thread_info_tm_t
t_info
=
{.
buf
=
(
uint8_t
*
)
arr
,
.
len
=
0
,
.
ans
=
ans
};
#endif
int64_t
const
t0
=
time_now_ns
();
int
totalDecode
=
0
;
for
(
int
ULSCH_id
=
0
;
ULSCH_id
<
gNB
->
max_nb_pusch
;
ULSCH_id
++
)
{
NR_gNB_ULSCH_t
*
ulsch
=
&
gNB
->
ulsch
[
ULSCH_id
];
...
...
@@ -933,13 +971,32 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
// LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
// LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX
,
1
);
#ifdef TASK_MANAGER_DECODING
int
const
tasks_added
=
nr_ulsch_procedures
(
gNB
,
frame_rx
,
slot_rx
,
ULSCH_id
,
ulsch
->
harq_pid
,
&
t_info
);
#else
int
const
tasks_added
=
nr_ulsch_procedures
(
gNB
,
frame_rx
,
slot_rx
,
ULSCH_id
,
ulsch
->
harq_pid
);
#endif
if
(
tasks_added
>
0
)
totalDecode
+=
tasks_added
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX
,
0
);
}
}
++
cnt
;
#ifdef TASK_MANAGER_DECODING
if
(
totalDecode
>
0
)
{
assert
(
totalDecode
==
t_info
.
len
);
join_task_ans
(
t_info
.
ans
,
t_info
.
len
);
for
(
int
i
=
0
;
i
<
t_info
.
len
;
++
i
){
nr_postDecode
(
gNB
,
&
arr
[
i
]);
}
if
(
cnt
%
1024
==
0
)
printf
(
"Decoding time %ld
\n
"
,
time_now_ns
()
-
t0
);
}
#else
bool
const
loop
=
totalDecode
>
0
;
while
(
totalDecode
>
0
)
{
notifiedFIFO_elt_t
*
req
=
pullTpool
(
&
gNB
->
respDecode
,
&
gNB
->
threadPool
);
if
(
req
==
NULL
)
...
...
@@ -948,6 +1005,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
delNotifiedFIFO_elt
(
req
);
totalDecode
--
;
}
<<<<<<<
HEAD
=======
if
(
loop
&&
(
cnt
%
1024
==
0
))
printf
(
"Decoding time %ld
\n
"
,
time_now_ns
()
-
t0
);
#endif
stop_meas
(
&
gNB
->
ulsch_decoding_stats
);
>>>>>>>
ac01afe8d2
(
Decoding
in
RF
Sim
working
)
for
(
int
i
=
0
;
i
<
gNB
->
max_nb_srs
;
i
++
)
{
NR_gNB_SRS_t
*
srs
=
&
gNB
->
srs
[
i
];
if
(
srs
)
{
...
...
openair1/SIMULATION/NR_PHY/ulschsim.c
View file @
90b773a4
...
...
@@ -50,6 +50,8 @@
#include "executables/nr-uesoftmodem.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "common/utils/thread_pool/task_manager.h"
//#define DEBUG_NR_ULSCHSIM
THREAD_STRUCT
thread_struct
;
...
...
@@ -91,9 +93,15 @@ void deref_sched_response(int _)
exit
(
1
);
}
#ifdef TASK_MANAGER_DECODING
int
nr_postDecode_sim
(
PHY_VARS_gNB
*
gNB
,
ldpcDecode_t
*
rdata
,
int
*
nb_ok
)
{
#else
int
nr_postDecode_sim
(
PHY_VARS_gNB
*
gNB
,
notifiedFIFO_elt_t
*
req
,
int
*
nb_ok
)
{
ldpcDecode_t
*
rdata
=
(
ldpcDecode_t
*
)
NotifiedFifoData
(
req
);
#endif
NR_UL_gNB_HARQ_t
*
ulsch_harq
=
rdata
->
ulsch_harq
;
int
r
=
rdata
->
segment_r
;
...
...
@@ -107,8 +115,16 @@ int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *nb_ok)
}
// if all segments are done
if
(
rdata
->
nbSegments
==
ulsch_harq
->
processedSegments
)
if
(
rdata
->
nbSegments
==
ulsch_harq
->
processedSegments
){
#ifdef TASK_MANAGER_DECODING
completed_task_ans
(
rdata
->
ans
);
#endif
return
*
nb_ok
==
rdata
->
nbSegments
;
}
#ifdef TASK_MANAGER_DECODING
completed_task_ans
(
rdata
->
ans
);
#endif
return
0
;
}
...
...
@@ -407,7 +423,13 @@ int main(int argc, char **argv)
gNB
=
RC
.
gNB
[
0
];
//gNB_config = &gNB->gNB_config;
#ifdef TASK_MANAGER_DECODING
int
const
num_threads
=
parse_num_threads
(
"n"
);
init_task_manager
(
&
gNB
->
man
,
num_threads
);
#else
initTpool
(
"n"
,
&
gNB
->
threadPool
,
true
);
#endif
initNotifiedFIFO
(
&
gNB
->
respDecode
);
frame_parms
=
&
gNB
->
frame_parms
;
//to be initialized I suppose (maybe not necessary for PBCH)
frame_parms
->
N_RB_DL
=
N_RB_DL
;
...
...
@@ -588,8 +610,23 @@ int main(int argc, char **argv)
exit
(
-
1
);
#endif
#ifdef TASK_MANAGER_DECODING
ldpcDecode_t
arr
[
16
]
=
{
0
};
task_ans_t
ans
[
16
]
=
{
0
};
thread_info_tm_t
t_info
=
{.
buf
=
(
uint8_t
*
)
arr
,
.
len
=
0
,
.
ans
=
ans
};
int
nbDecode
=
nr_ulsch_decoding
(
gNB
,
UE_id
,
channel_output_fixed
,
frame_parms
,
rel15_ul
,
frame
,
subframe
,
harq_pid
,
G
,
&
t_info
);
assert
(
nbDecode
>
0
);
#else
int
nbDecode
=
nr_ulsch_decoding
(
gNB
,
UE_id
,
channel_output_fixed
,
frame_parms
,
rel15_ul
,
frame
,
subframe
,
harq_pid
,
G
);
#endif
int
nb_ok
=
0
;
#ifdef TASK_MANAGER_DECODING
join_task_ans
(
t_info
.
ans
,
t_info
.
len
);
for
(
size_t
i
=
0
;
i
<
nbDecode
;
++
i
){
ret
=
nr_postDecode_sim
(
gNB
,
&
arr
[
i
],
&
nb_ok
);
}
nbDecode
=
0
;
#else
if
(
nbDecode
>
0
)
while
(
nbDecode
>
0
)
{
notifiedFIFO_elt_t
*
req
=
pullTpool
(
&
gNB
->
respDecode
,
&
gNB
->
threadPool
);
...
...
@@ -597,7 +634,7 @@ int main(int argc, char **argv)
delNotifiedFIFO_elt
(
req
);
nbDecode
--
;
}
#endif
if
(
ret
)
n_errors
++
;
}
...
...
@@ -624,6 +661,11 @@ int main(int argc, char **argv)
free
(
gNB
->
gNB_config
.
tdd_table
.
max_tdd_periodicity_list
[
i
].
max_num_of_symbol_per_slot_list
);
free
(
gNB
->
gNB_config
.
tdd_table
.
max_tdd_periodicity_list
);
#ifdef TASK_MANAGER_DECODING
void
(
*
clean
)(
task_t
*
args
)
=
NULL
;
free_task_manager
(
&
gNB
->
man
,
clean
);
#endif
term_nr_ue_signal
(
UE
,
1
);
free
(
UE
);
...
...
openair2/LAYER2/NR_MAC_UE/config_ue.c
View file @
90b773a4
/*
/*
* 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.
...
...
@@ -1944,4 +1944,5 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
if
(
!
mac
->
dl_config_request
||
!
mac
->
ul_config_request
)
ue_init_config_request
(
mac
,
mac
->
current_DL_BWP
->
scs
);
}
openair3/UICC/usim_interface.c
View file @
90b773a4
...
...
@@ -37,18 +37,35 @@ extern uint16_t NB_UE_INST;
/* configuration parameters for the rfsimulator device */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define UICC_PARAMS_DESC { \
{"imsi", "USIM IMSI\n", 0, .strptr=&uicc->imsiStr, .defstrval="2089900007487", TYPE_STRING, 0 }, \
{"nmc_size" "number of digits in NMC", 0, .iptr=&uicc->nmc_size, .defintval=2, TYPE_INT, 0 }, \
{"key", "USIM Ki\n", 0, .strptr=&uicc->keyStr, .defstrval="fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 }, \
{"opc", "USIM OPc\n", 0, .strptr=&uicc->opcStr, .defstrval="c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 }, \
{"amf", "USIM amf\n", 0, .strptr=&uicc->amfStr, .defstrval="8000", TYPE_STRING, 0 }, \
{"sqn", "USIM sqn\n", 0, .strptr=&uicc->sqnStr, .defstrval="000000", TYPE_STRING, 0 }, \
{"dnn", "UE dnn (apn)\n", 0, .strptr=&uicc->dnnStr, .defstrval="oai", TYPE_STRING, 0 }, \
{"nssai_sst", "UE nssai\n", 0, .iptr=&uicc->nssai_sst, .defintval=1, TYPE_INT, 0 }, \
{"nssai_sd", "UE nssai\n", 0, .iptr=&uicc->nssai_sd, .defintval=0xffffff, TYPE_INT, 0 }, \
{"imeisv", "IMEISV\n", 0, .strptr=&uicc->imeisvStr, .defstrval="6754567890123413", TYPE_STRING, 0 }, \
};
//#define UICC_PARAMS_DESC { \
// {"imsi", "USIM IMSI\n", 0, .strptr=&uicc->imsiStr, .defstrval="2089900007487", TYPE_STRING, 0 }, \
// {"nmc_size" "number of digits in NMC", 0, .iptr=&uicc->nmc_size, .defintval=2, TYPE_INT, 0 }, \
// {"key", "USIM Ki\n", 0, .strptr=&uicc->keyStr, .defstrval="fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 }, \
// {"opc", "USIM OPc\n", 0, .strptr=&uicc->opcStr, .defstrval="c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 }, \
// {"amf", "USIM amf\n", 0, .strptr=&uicc->amfStr, .defstrval="8000", TYPE_STRING, 0 }, \
// {"sqn", "USIM sqn\n", 0, .strptr=&uicc->sqnStr, .defstrval="000000", TYPE_STRING, 0 }, \
// {"dnn", "UE dnn (apn)\n", 0, .strptr=&uicc->dnnStr, .defstrval="oai", TYPE_STRING, 0 }, \
// {"nssai_sst", "UE nssai\n", 0, .iptr=&uicc->nssai_sst, .defintval=1, TYPE_INT, 0 }, \
// {"nssai_sd", "UE nssai\n", 0, .iptr=&uicc->nssai_sd, .defintval=0xffffff, TYPE_INT, 0 }, \
// {"imeisv", "IMEISV\n", 0, .strptr=&uicc->imeisvStr, .defstrval="6754567890123413", TYPE_STRING, 0 }, \
// };
//
#define UICC_PARAMS_DESC {\
{"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"001010000000001", TYPE_STRING, 0 },\
{"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\
{"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 },\
{"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 },\
{"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\
{"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\
{"dnn", "UE dnn (apn)\n", 0, strptr:&(uicc->dnnStr), defstrval:"oai", TYPE_STRING, 0 },\
{"nssai_sst", "UE nssai\n", 0, iptr:&(uicc->nssai_sst), defintval:1, TYPE_INT, 0 }, \
{"nssai_sd", "UE nssai\n", 0, iptr:&(uicc->nssai_sd), defintval:0xffffff, TYPE_INT, 0 }, \
{"imeisv", "IMEISV\n", 0, strptr:&(uicc->imeisvStr), defstrval:"6754567890123413", TYPE_STRING, 0 }, \
};
static
uicc_t
**
uiccArray
=
NULL
;
...
...
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