Do not start processSlotTx before it is ready to run.
Implement run-to-completion for processSlotTX. This is achieved by using a new dynamic_barrier_t which allows to specify callback after the first join has been made.
This commit is contained in:
+14
-13
@@ -43,7 +43,7 @@ include("cmake_targets/CPM.cmake")
|
||||
option(CCACHE_ACTIVE "CCache" ON)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND AND CCACHE_ACTIVE)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.4.0")
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.4.0")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
message(STATUS "Found ccache in ${CCACHE_FOUND}. Using ccache. CMake < 3.4")
|
||||
else()
|
||||
@@ -105,13 +105,13 @@ add_list_string_option(CMAKE_BUILD_TYPE "RelWithDebInfo" "Choose the type of bui
|
||||
|
||||
# in case /proc/cpuinfo exists we want to inspect available Intrinsics
|
||||
# -so not to go always through SIMDE emulation
|
||||
# -so to avoid AVX512 instructions generation by gcc
|
||||
# -so to avoid AVX512 instructions generation by gcc
|
||||
if(EXISTS "/proc/cpuinfo" AND NOT CROSS_COMPILE)
|
||||
file(STRINGS "/proc/cpuinfo" CPUFLAGS REGEX flags LIMIT_COUNT 1)
|
||||
else()
|
||||
message(WARNING "did not find /proc/cpuinfo -- not setting any x86-specific compilation variables")
|
||||
endif()
|
||||
|
||||
|
||||
eval_boolean(AUTODETECT_AVX512 DEFINED CPUFLAGS AND CPUFLAGS MATCHES "avx512")
|
||||
add_boolean_option(AVX512 ${AUTODETECT_AVX512} "Whether AVX512 intrinsics is available on the host processor" ON)
|
||||
|
||||
@@ -636,7 +636,7 @@ if (cap_FOUND)
|
||||
target_link_libraries(UTIL PRIVATE cap)
|
||||
target_compile_definitions(UTIL PRIVATE HAVE_LIB_CAP)
|
||||
endif()
|
||||
target_link_libraries(UTIL PUBLIC ${T_LIB} pthread LOG thread-pool utils)
|
||||
target_link_libraries(UTIL PUBLIC ${T_LIB} pthread LOG thread-pool utils barrier)
|
||||
|
||||
set(SECURITY_SRC
|
||||
${OPENAIR3_DIR}/SECU/secu_defs.c
|
||||
@@ -677,7 +677,7 @@ set(SCHED_NR_SRC
|
||||
${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
|
||||
)
|
||||
add_library(SCHED_NR_LIB ${SCHED_NR_SRC})
|
||||
target_link_libraries(SCHED_NR_LIB PRIVATE asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(SCHED_NR_LIB PRIVATE asn1_nr_rrc_hdrs UTIL)
|
||||
|
||||
set(SCHED_SRC_RU
|
||||
${OPENAIR1_DIR}/SCHED/ru_procedures.c
|
||||
@@ -695,7 +695,7 @@ set(SCHED_SRC_UE
|
||||
${OPENAIR1_DIR}/SCHED_UE/srs_pc.c
|
||||
)
|
||||
add_library(SCHED_UE_LIB ${SCHED_SRC_UE})
|
||||
target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
|
||||
|
||||
set(SCHED_SRC_NR_UE
|
||||
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
|
||||
@@ -706,7 +706,7 @@ set(SCHED_SRC_NR_UE
|
||||
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
|
||||
)
|
||||
add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
|
||||
target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
|
||||
|
||||
# nFAPI
|
||||
#################################
|
||||
@@ -758,7 +758,7 @@ set(NFAPI_USER_SRC
|
||||
${NFAPI_USER_DIR}/gnb_ind_vars.c
|
||||
)
|
||||
add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
|
||||
target_link_libraries(NFAPI_USER_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(NFAPI_USER_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
|
||||
include_directories(${NFAPI_USER_DIR})
|
||||
|
||||
# Layer 1
|
||||
@@ -1118,7 +1118,7 @@ set(PHY_SRC_UE ${PHY_SRC_UE} ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_comp
|
||||
add_library(PHY_COMMON ${PHY_SRC_COMMON})
|
||||
target_link_libraries(PHY_COMMON PRIVATE shlib_loader)
|
||||
add_dependencies(PHY_COMMON dfts)
|
||||
target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs PUBLIC UTIL)
|
||||
|
||||
add_library(PHY ${PHY_SRC})
|
||||
target_link_libraries(PHY PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
@@ -1127,7 +1127,7 @@ pkg_check_modules(blas REQUIRED blas)
|
||||
pkg_check_modules(lapacke REQUIRED lapacke)
|
||||
|
||||
add_library(PHY_UE ${PHY_SRC_UE})
|
||||
target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
|
||||
# RHEL needs also cblas, but Ubuntu does not have it. So `cblas_LIBRARIES` will
|
||||
# be empty for Ubuntu, a no-op
|
||||
pkg_check_modules(cblas cblas)
|
||||
@@ -1135,6 +1135,7 @@ target_link_libraries(PHY_UE PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapa
|
||||
target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE_DIRS})
|
||||
|
||||
add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
|
||||
target_link_libraries(PHY_NR_COMMON PUBLIC UTIL)
|
||||
|
||||
add_library(PHY_NR ${PHY_NR_SRC})
|
||||
target_link_libraries(PHY_NR nr_phy_common nr_common)
|
||||
@@ -1147,7 +1148,7 @@ add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
|
||||
target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs nr_phy_common nr_common)
|
||||
|
||||
add_library(PHY_RU ${PHY_SRC_RU})
|
||||
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs UTIL)
|
||||
|
||||
#Library for mex functions
|
||||
#########################3
|
||||
@@ -1216,7 +1217,7 @@ set(NR_SDAP_SRC
|
||||
${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap.c
|
||||
${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_entity.c
|
||||
)
|
||||
|
||||
|
||||
set(L2_SRC
|
||||
${PDCP_DIR}/pdcp.c
|
||||
${PDCP_DIR}/pdcp_fifo.c
|
||||
@@ -2064,7 +2065,7 @@ if(E2_AGENT)
|
||||
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
|
||||
target_compile_definitions(nr-cuup PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
# nr-uesoftmodem is UE implementation
|
||||
#######################################
|
||||
|
||||
|
||||
@@ -31,6 +31,16 @@ void dynamic_barrier_init(dynamic_barrier_t* barrier)
|
||||
barrier->completed_jobs = 0;
|
||||
}
|
||||
|
||||
void dynamic_barrier_reset(dynamic_barrier_t* barrier)
|
||||
{
|
||||
barrier->callback = NULL;
|
||||
if (barrier->callback_arg != NULL) {
|
||||
free(barrier->callback_arg);
|
||||
}
|
||||
barrier->callback_arg = NULL;
|
||||
barrier->completed_jobs = 0;
|
||||
}
|
||||
|
||||
void dynamic_barrier_join(dynamic_barrier_t* barrier)
|
||||
{
|
||||
int ret = pthread_mutex_lock(&barrier->barrier_lock);
|
||||
|
||||
@@ -39,6 +39,10 @@ typedef struct dynamic_barrier_t {
|
||||
/// @param barrier
|
||||
void dynamic_barrier_init(dynamic_barrier_t* barrier);
|
||||
|
||||
/// @brief Reset the barrier
|
||||
/// @param barrier
|
||||
void dynamic_barrier_reset(dynamic_barrier_t* barrier);
|
||||
|
||||
/// @brief Perform join on the barrier. May run callback if it is already set
|
||||
/// @param barrier
|
||||
void dynamic_barrier_join(dynamic_barrier_t* barrier);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
add_library(nr_common nr_common.c)
|
||||
target_include_directories(nr_common PUBLIC .)
|
||||
target_link_libraries(nr_common PRIVATE UTIL)
|
||||
target_link_libraries(nr_common PUBLIC UTIL)
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -53,7 +53,7 @@ message(STATUS "No specific telnet functions for 4Gue")
|
||||
message(STATUS "Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so")
|
||||
add_library(telnetsrv_5Gue MODULE telnetsrv_5Gue_measurements.c)
|
||||
add_dependencies(telnetsrv telnetsrv_5Gue)
|
||||
target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
|
||||
|
||||
message(STATUS "Add CI specific telnet functions in libtelnetsrv_ci.so")
|
||||
add_library(telnetsrv_ci MODULE telnetsrv_ci.c)
|
||||
@@ -79,4 +79,3 @@ add_dependencies(telnetsrv telnetsrv_rrc)
|
||||
set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci telnetsrv_ciUE telnetsrv_bearer telnetsrv_rrc
|
||||
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
|
||||
)
|
||||
|
||||
|
||||
+17
-58
@@ -99,6 +99,11 @@
|
||||
|
||||
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
|
||||
|
||||
static void start_process_slot_tx(void* arg) {
|
||||
notifiedFIFO_elt_t *newTx = arg;
|
||||
pushTpool(&(get_nrUE_params()->Tpool), newTx);
|
||||
}
|
||||
|
||||
static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
|
||||
{
|
||||
const char *begin = output;
|
||||
@@ -486,56 +491,10 @@ void processSlotTX(void *arg)
|
||||
nr_phy_data_tx_t phy_data = {0};
|
||||
bool sl_tx_action = false;
|
||||
|
||||
// Force sequential execution, even if we launch in // for all slots
|
||||
// at least ULstatus variable is a pure race condition that is quickly detected by assert() in the code because one thread sets it
|
||||
// to active, so the other thread try to steal&run the ul work
|
||||
if (rxtxD->stream_status == STREAM_STATUS_SYNCED) {
|
||||
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
|
||||
if (UE->if_inst)
|
||||
UE->if_inst->slot_indication(UE->Mod_id);
|
||||
|
||||
LOG_D(PHY,
|
||||
"SlotTx %d.%d => slot type %d, wait: %d \n",
|
||||
proc->frame_tx,
|
||||
proc->nr_slot_tx,
|
||||
proc->tx_slot_type,
|
||||
rxtxD->tx_wait_for_dlsch);
|
||||
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) {
|
||||
if (rxtxD->tx_wait_for_dlsch)
|
||||
LOG_D(PHY, "enter wait for tx, slot %d, nb events to wait %d; ", proc->nr_slot_tx, rxtxD->tx_wait_for_dlsch);
|
||||
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
|
||||
for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) {
|
||||
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
LOG_D(PHY, "completed wait for tx, slot %d\n", proc->nr_slot_tx);
|
||||
|
||||
/*
|
||||
This herafter code is costing some perfomance for a check that should be useless
|
||||
But, we face today several bugs arround the matching between events in UE->tx_resume_ind_fifo[slot]
|
||||
and the corresponding tx_wait_for_dlsch[slot]
|
||||
The algorithm is we accumlate the actions that should end before processing a tx slot in tx_wait_for_dlsch[slot]
|
||||
later, other threads push events in UE->tx_resume_ind_fifo[slot]
|
||||
so, the tx encoding starts only when related actions are done (mainly DLSCH ACK/NACK to encode PUCCH)
|
||||
if there is a bug that misses to send a event in UE->tx_resume_ind_fifo[slot], the process hangs, we detect the issue
|
||||
if there is a bug that makes a extra event in UE->tx_resume_ind_fifo[slot], and if we drop the hereafter check
|
||||
the system runs with random race conditions, very hard to debug
|
||||
|
||||
Likely we should later remove completly UE->tx_resume_ind_fifo with notifications,
|
||||
instead,
|
||||
we may run in place the processSlotTX() when the conditions are met (when a decreasing tx_wait_for_dlsch[slot] will become 0)
|
||||
It will remove the condition signals (for a thread safe semaphore or counter) and make the system simpler
|
||||
*/
|
||||
notifiedFIFO_elt_t *res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
||||
if (res)
|
||||
LOG_E(NR_PHY,
|
||||
"Internal error: extra event on Tx waiting queue for slot %d, event comes from rx slot %d\n",
|
||||
proc->nr_slot_tx,
|
||||
*(int *)NotifiedFifoData(res));
|
||||
|
||||
if (UE->sl_mode == 2 && proc->tx_slot_type == NR_SIDELINK_SLOT) {
|
||||
// trigger L2 to run ue_sidelink_scheduler thru IF module
|
||||
if (UE->if_inst != NULL && UE->if_inst->sl_indication != NULL) {
|
||||
@@ -584,13 +543,10 @@ void processSlotTX(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
|
||||
int *msgData = (int *)NotifiedFifoData(newElt);
|
||||
int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame
|
||||
: UE->frame_parms.slots_per_frame;
|
||||
int newslot = (proc->nr_slot_tx + 1) % slots_per_frame;
|
||||
*msgData = newslot;
|
||||
pushNotifiedFIFO(UE->tx_resume_ind_fifo + newslot, newElt);
|
||||
int next_slot = (proc->nr_slot_tx + 1) % slots_per_frame;
|
||||
dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]);
|
||||
RU_write(rxtxD, sl_tx_action);
|
||||
}
|
||||
|
||||
@@ -841,7 +797,7 @@ void *UE_thread(void *arg)
|
||||
|
||||
int num_ind_fifo = nb_slot_frame;
|
||||
for(int i = 0; i < num_ind_fifo; i++) {
|
||||
initNotifiedFIFO(UE->tx_resume_ind_fifo + i);
|
||||
dynamic_barrier_init(&UE->process_slot_tx_barriers[i]);
|
||||
}
|
||||
int shiftForNextFrame = 0;
|
||||
int intialSyncOffset = 0;
|
||||
@@ -956,9 +912,7 @@ void *UE_thread(void *arg)
|
||||
// We have resynchronized, maybe after RF loss so we need to purge any existing context
|
||||
memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
|
||||
for (int i = 0; i < num_ind_fifo; i++) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
while ((res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + i)))
|
||||
delNotifiedFIFO_elt(res);
|
||||
dynamic_barrier_reset(&UE->process_slot_tx_barriers[i]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1056,11 +1010,16 @@ void *UE_thread(void *arg)
|
||||
curMsgTx->writeBlockSize = writeBlockSize;
|
||||
curMsgTx->proc.timestamp_tx = writeTimestamp;
|
||||
curMsgTx->UE = UE;
|
||||
curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
|
||||
curMsgTx->stream_status = stream_status;
|
||||
|
||||
int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
|
||||
int slot = curMsgTx->proc.nr_slot_tx;
|
||||
dynamic_barrier_update(&UE->process_slot_tx_barriers[slot],
|
||||
tx_wait_for_dlsch[slot] + sync_to_previous_thread,
|
||||
start_process_slot_tx,
|
||||
newTx);
|
||||
stream_status = STREAM_STATUS_SYNCED;
|
||||
tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
|
||||
pushTpool(&(get_nrUE_params()->Tpool), newTx);
|
||||
tx_wait_for_dlsch[slot] = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
#include "LTE_SystemInformationBlockType2.h"
|
||||
//#include "RadioResourceConfigCommonSIB.h"
|
||||
|
||||
@@ -53,7 +53,7 @@ if(ENABLE_UESCOPE OR ENABLE_ENBSCOPE OR ENABLE_NRSCOPE)
|
||||
target_link_libraries(uescope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
add_library(nrscope MODULE nr_phy_scope.c)
|
||||
target_link_libraries(nrscope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(nrscope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
|
||||
|
||||
# all libraries should be written to root build dir (default creates the same hierarchie under build as existing for sources)
|
||||
set_target_properties(enbscope uescope nrscope
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "common_lib.h"
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
#include "assertions.h"
|
||||
#include "barrier.h"
|
||||
//#include "openair1/SCHED_NR_UE/defs.h"
|
||||
|
||||
#ifdef MEX
|
||||
@@ -74,16 +75,6 @@
|
||||
#define openair_free(y,x) free((y))
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#ifdef NR_UNIT_TEST
|
||||
#define FILE_NAME " "
|
||||
#define LINE_FILE (0)
|
||||
#define NR_TST_PHY_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define FILE_NAME (__FILE__)
|
||||
#define LINE_FILE (__LINE__)
|
||||
#define NR_TST_PHY_PRINTF(...)
|
||||
#endif
|
||||
|
||||
#define PAGE_MASK 0xfffff000
|
||||
#define virt_to_phys(x) (x)
|
||||
#define openair_sched_exit() exit(-1)
|
||||
@@ -530,7 +521,7 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
void *phy_sim_pdsch_dl_ch_estimates_ext;
|
||||
uint8_t *phy_sim_dlsch_b;
|
||||
|
||||
notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
|
||||
dynamic_barrier_t process_slot_tx_barriers[NR_MAX_SLOTS_PER_FRAME];
|
||||
|
||||
// Gain change required for automation RX gain change
|
||||
int adjust_rxgain;
|
||||
|
||||
@@ -31,10 +31,19 @@
|
||||
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "SCHED_NR/phy_frame_config_nr.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#ifdef NR_UNIT_TEST
|
||||
#define FILE_NAME " "
|
||||
#define LINE_FILE (0)
|
||||
#define NR_TST_PHY_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define FILE_NAME (__FILE__)
|
||||
#define LINE_FILE (__LINE__)
|
||||
#define NR_TST_PHY_PRINTF(...)
|
||||
#endif
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : set_tdd_configuration
|
||||
|
||||
@@ -632,18 +632,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function release the Tx working thread for one pending information, like dlsch ACK/NACK
|
||||
static void send_dl_done_to_tx_thread(notifiedFIFO_t *nf, int rx_slot)
|
||||
{
|
||||
if (nf) {
|
||||
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
|
||||
// We put rx slot only for tracing purpose
|
||||
int *msgData = (int *) NotifiedFifoData(newElt);
|
||||
*msgData = rx_slot;
|
||||
pushNotifiedFIFO(nf, newElt);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t compute_csi_rm_unav_res(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config)
|
||||
{
|
||||
uint32_t unav_res = 0;
|
||||
@@ -737,7 +725,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
// don't wait anymore
|
||||
LOG_E(NR_PHY, "Internal error nr_ue_dlsch_procedure() called but no active cw on slot %d, harq %d\n", nr_slot_rx, harq_pid);
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame;
|
||||
send_dl_done_to_tx_thread(ue->tx_resume_ind_fifo + ack_nack_slot, proc->nr_slot_rx);
|
||||
dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -873,7 +861,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
// DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH
|
||||
if (dlsch[0].rnti_type == TYPE_C_RNTI_) {
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame;
|
||||
send_dl_done_to_tx_thread(ue->tx_resume_ind_fifo + ack_nack_slot, proc->nr_slot_rx);
|
||||
dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
|
||||
}
|
||||
|
||||
if (ue->phy_sim_dlsch_b)
|
||||
@@ -1152,9 +1140,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
nr_ue_dlsch_procedures(ue, proc, dlsch, llr, G);
|
||||
else {
|
||||
LOG_E(NR_PHY, "Demodulation impossible, internal error\n");
|
||||
send_dl_done_to_tx_thread(
|
||||
ue->tx_resume_ind_fifo + (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame,
|
||||
proc->nr_slot_rx);
|
||||
int ack_nack_slot = (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame;
|
||||
dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
|
||||
LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user