From 654cffe39f9882f338192d8b4cc37832906f8059 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 11 Sep 2024 22:08:53 +0200 Subject: [PATCH] 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. --- CMakeLists.txt | 27 ++++---- common/utils/barrier/barrier.c | 10 +++ common/utils/barrier/barrier.h | 4 ++ common/utils/nr/CMakeLists.txt | 2 +- common/utils/telnetsrv/CMakeLists.txt | 3 +- executables/nr-ue.c | 75 +++++---------------- openair1/PHY/INIT/phy_init.h | 1 - openair1/PHY/TOOLS/CMakeLists.txt | 2 +- openair1/PHY/defs_nr_UE.h | 13 +--- openair1/SCHED_NR/phy_frame_config_nr.c | 11 ++- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 21 ++---- 11 files changed, 64 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index edd9c18657..f4047bebd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ####################################### diff --git a/common/utils/barrier/barrier.c b/common/utils/barrier/barrier.c index 88c7d0f318..574d6be4a3 100644 --- a/common/utils/barrier/barrier.c +++ b/common/utils/barrier/barrier.c @@ -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); diff --git a/common/utils/barrier/barrier.h b/common/utils/barrier/barrier.h index 33abfcb46c..e27b56e766 100644 --- a/common/utils/barrier/barrier.h +++ b/common/utils/barrier/barrier.h @@ -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); diff --git a/common/utils/nr/CMakeLists.txt b/common/utils/nr/CMakeLists.txt index 979958d877..c99b9a06a7 100644 --- a/common/utils/nr/CMakeLists.txt +++ b/common/utils/nr/CMakeLists.txt @@ -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() diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt index 959812d73a..a7da081f09 100644 --- a/common/utils/telnetsrv/CMakeLists.txt +++ b/common/utils/telnetsrv/CMakeLists.txt @@ -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 ../../.. ) - diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a7661b0c06..f18505dc64 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -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; diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index daf6eafa42..6b278f899f 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -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" diff --git a/openair1/PHY/TOOLS/CMakeLists.txt b/openair1/PHY/TOOLS/CMakeLists.txt index ada3d8c863..574899f3e7 100644 --- a/openair1/PHY/TOOLS/CMakeLists.txt +++ b/openair1/PHY/TOOLS/CMakeLists.txt @@ -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 diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 7178faefd1..5e46e2899a 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -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; diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 250dcc2f95..da7cc26e1a 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -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 diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index a737b5246e..ef2ea2ccf8 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -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); }