Commit f5989abd authored by Robert Schmidt's avatar Robert Schmidt

Use spsc_q for SRS processing

Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for SRS jobs,
clarifying the design, and making it thread-safe.
Signed-off-by: default avatarRobert Schmidt <robert.schmidt@openairinterface.org>
parent a5696562
......@@ -419,15 +419,13 @@ void init_nr_transport(PHY_VARS_gNB *gNB)
buffer_ul_slots = (nb_ul_slots_period < slot_ahead) ? nb_ul_slots_period : slot_ahead;
gNB->max_nb_pusch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
gNB->max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot
int max_nb_pucch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
gNB->pucch_queue = spsc_q_alloc(max_nb_pucch, sizeof(NR_gNB_PUCCH_job_t));
gNB->pusch_queue = spsc_q_alloc(gNB->max_nb_pusch, sizeof(NR_gNB_PUSCH_job_t));
gNB->srs = (NR_gNB_SRS_t *)malloc16(gNB->max_nb_srs * sizeof(NR_gNB_SRS_t));
for (int i = 0; i < gNB->max_nb_srs; i++)
gNB->srs[i].active = 0;
int max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot
gNB->srs_queue = spsc_q_alloc(max_nb_srs, sizeof(NR_gNB_SRS_job_t));
gNB->ulsch = (NR_gNB_ULSCH_t *)malloc16(gNB->max_nb_pusch * sizeof(NR_gNB_ULSCH_t));
for (int i = 0; i < gNB->max_nb_pusch; i++) {
......@@ -446,7 +444,7 @@ void reset_nr_transport(PHY_VARS_gNB *gNB)
spsc_q_free(&gNB->pucch_queue);
spsc_q_free(&gNB->pusch_queue);
free(gNB->srs);
spsc_q_free(&gNB->srs_queue);
for (int i = 0; i < gNB->max_nb_pusch; i++)
free_gNB_ulsch(&gNB->ulsch[i], fp->N_RB_UL);
......
......@@ -209,7 +209,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
uint8_t N_ap,
uint8_t N_symb_SRS,
uint16_t ofdm_symbol_size,
const NR_gNB_SRS_t *srs,
const NR_gNB_SRS_job_t *srs,
int *srs_est,
int8_t *snr,
c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS],
......
......@@ -29,31 +29,21 @@
void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu)
{
bool found = false;
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (srs->active == false) {
found = true;
srs->frame = frame;
srs->slot = slot;
srs->active = true;
srs->beam_nb = 0;
if (gNB->common_vars.beam_id) {
const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position;
int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols);
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
srs->beam_nb = beam_index_allocation(gNB->enable_analog_das,
fapi_beam_idx,
&gNB->common_vars,
slot,
gNB->frame_parms.symbols_per_slot,
bitmap);
}
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
break;
}
NR_gNB_SRS_job_t srs = {.frame = frame, .slot = slot, .srs_pdu = *srs_pdu};
if (gNB->common_vars.beam_id) {
const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position;
int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols);
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
srs.beam_nb = beam_index_allocation(gNB->enable_analog_das,
fapi_beam_idx,
&gNB->common_vars,
slot,
gNB->frame_parms.symbols_per_slot,
bitmap);
}
AssertFatal(found, "SRS list is full\n");
bool found = spsc_q_put(&gNB->srs_queue, &srs, sizeof(srs));
if (!found)
LOG_W(NR_PHY, "SRS list is full: dropping SRS UE %04x\n", srs_pdu->rnti);
}
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
......
......@@ -208,7 +208,6 @@ typedef struct {
} NR_gNB_PUCCH_job_t;
typedef struct {
bool active;
// identifier for concurrent beams
int beam_nb;
/// Frame where current SRS pdu was received
......@@ -217,7 +216,7 @@ typedef struct {
uint32_t slot;
/// ULSCH PDU
nfapi_nr_srs_pdu_t srs_pdu;
} NR_gNB_SRS_t;
} NR_gNB_SRS_job_t;
typedef struct {
/// \brief Pointers (dynamic) to the received data in the frequency domain.
......@@ -375,7 +374,6 @@ typedef struct PHY_VARS_gNB_s {
nfapi_nr_ul_tti_request_t UL_tti_req;
int max_nb_srs;
int max_nb_pdsch;
int max_nb_pusch;
......@@ -387,7 +385,7 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_PUSCH *pusch_vars;
spsc_q_t pucch_queue;
spsc_q_t pusch_queue;
NR_gNB_SRS_t *srs;
spsc_q_t srs_queue;
NR_gNB_ULSCH_t *ulsch;
NR_gNB_PHY_STATS_t phy_stats[MAX_MOBILES_PER_GNB];
t_nrPolar_params **polarParams;
......
......@@ -536,7 +536,9 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB,
const NR_gNB_PUCCH_job_t *pucch,
int n_pucch,
const NR_gNB_PUSCH_job_t *pusch,
int n_pusch)
int n_pusch,
const NR_gNB_SRS_job_t *srs,
int n_srs)
{
for (int symbol = 0; symbol < 14; symbol++) {
for (int m = 0; m < 9; m++) {
......@@ -581,11 +583,8 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB,
}
}
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (!(srs && srs->active && srs->frame == now.f && srs->slot == now.s))
continue;
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
for (int i = 0; i < n_srs; i++) {
const nfapi_nr_srs_pdu_t *srs_pdu = &srs[i].srs_pdu;
const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position;
for (int symbol = 0; symbol < (1 << srs_pdu->num_symbols); symbol++) {
for (int rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start + srs_pdu->bwp_size); rb++) {
......@@ -703,7 +702,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
uint8_t N_ap,
uint8_t N_symb_SRS,
uint16_t ofdm_symbol_size,
const NR_gNB_SRS_t *srs,
const NR_gNB_SRS_job_t *srs,
int *srs_est,
int8_t *snr,
c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS],
......@@ -875,7 +874,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
return nr_srs_info;
}
static void handle_srs(fsn_t now, PHY_VARS_gNB *gNB, const NR_gNB_SRS_t *srs, nfapi_nr_srs_indication_pdu_t *srs_indication)
static void handle_srs(fsn_t now, PHY_VARS_gNB *gNB, const NR_gNB_SRS_job_t *srs, nfapi_nr_srs_indication_pdu_t *srs_indication)
{
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
......@@ -1137,6 +1136,25 @@ static bool get_current_pusch(const void *data, void *user)
return fsn_equal(t, *now);
}
static bool drop_old_srs(const void *data, void *user)
{
const NR_gNB_SRS_job_t *srs = data;
const fsn_t *now = user;
const fsn_t t = {srs->frame, srs->slot, now->mu};
bool drop = fsn_in_the_past(t, *now);
if (drop)
LOG_E(NR_PHY, "%4d.%2d SRS job for UE %04x is in the past (%4d.%2d)\n", now->f, now->s, srs->srs_pdu.rnti, t.f, t.s);
return drop;
}
static bool get_current_srs(const void *data, void *user)
{
const NR_gNB_SRS_job_t *srs = data;
const fsn_t *now = user;
const fsn_t t = {srs->frame, srs->slot, now->mu};
return fsn_equal(t, *now);
}
static int find_nr_ulsch_idx(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
{
AssertFatal(gNB != NULL, "gNB is null\n");
......@@ -1201,6 +1219,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
NR_gNB_PUSCH_job_t pusch[MAX_UL_PDUS_PER_SLOT];
int n_pusch_jobs = spsc_q_get_while(&gNB->pusch_queue, get_current_pusch, &now, pusch, sizeof(*pusch), MAX_UL_PDUS_PER_SLOT);
spsc_q_drop_while(&gNB->srs_queue, drop_old_srs, &now);
NR_gNB_SRS_job_t srs[MAX_NUM_NR_SRS_PDUS];
int n_srs = spsc_q_get_while(&gNB->srs_queue, get_current_srs, &now, srs, sizeof(*srs), MAX_NUM_NR_SRS_PDUS);
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
{
// Mask of occupied RBs, per symbol and PRB
......@@ -1208,7 +1230,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
nfapi_nr_max_num_of_symbol_per_slot_t *slot_conf = NULL;
if (frame_parms->frame_type == TDD)
slot_conf = gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list;
fill_ul_rb_mask(gNB, now, rb_mask_ul, slot_conf, pucch, n_pucch, pusch, n_pusch_jobs);
fill_ul_rb_mask(gNB, now, rb_mask_ul, slot_conf, pucch, n_pucch, pusch, n_pusch_jobs, srs, n_srs);
int first_symb = 0, num_symb = 0;
if (frame_parms->frame_type == TDD)
......@@ -1273,22 +1295,13 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
if (gNB->max_nb_pusch == 1)
stop_meas(&gNB->ulsch_decoding_stats);
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (!(srs && srs->active && srs->frame == frame_rx && srs->slot == slot_rx))
continue;
LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i);
UL_INFO->srs_ind.sfn = frame_rx;
UL_INFO->srs_ind.slot = slot_rx;
UL_INFO->srs_ind.pdu_list = UL_INFO->srs_pdu_list;
UL_INFO->srs_ind.number_of_pdus = n_srs;
for (int i = 0; i < n_srs; ++i) {
start_meas(&gNB->rx_srs_stats);
UL_INFO->srs_ind.sfn = frame_rx;
UL_INFO->srs_ind.slot = slot_rx;
UL_INFO->srs_ind.pdu_list = UL_INFO->srs_pdu_list;
nfapi_nr_srs_indication_pdu_t *srs_indication = UL_INFO->srs_pdu_list + UL_INFO->srs_ind.number_of_pdus++;
handle_srs(now, gNB, srs, srs_indication);
srs->active = false;
handle_srs(now, gNB, &srs[i], &UL_INFO->srs_ind.pdu_list[i]);
stop_meas(&gNB->rx_srs_stats);
}
......
......@@ -435,11 +435,7 @@ int main(int argc, char *argv[])
.beamforming.num_prgs = m_SRS[srs_pdu.config_index],
.beamforming.prg_size = 1};
gNB->srs->srs_pdu = srs_pdu;
gNB->srs->active = true;
gNB->srs->beam_nb = 0;
gNB->srs->frame = frame;
gNB->srs->slot = slot;
NR_gNB_SRS_job_t srs_job = {.frame = frame, .slot = slot, .srs_pdu = srs_pdu};
// Configure SRS parameters at UE
fapi_nr_ul_config_srs_pdu srs_config_pdu = {.rnti = srs_pdu.rnti,
......@@ -559,10 +555,9 @@ int main(int argc, char *argv[])
//----------- UE RX SRS procedures ---------------------
start_meas(&gNB->rx_srs_stats);
NR_gNB_SRS_t *srs = &gNB->srs[0];
uint8_t N_symb_SRS = 1 << srs->srs_pdu.num_symbols;
uint8_t N_ap = 1 << srs->srs_pdu.num_ant_ports;
int16_t snr_per_rb[srs->srs_pdu.bwp_size];
uint8_t N_symb_SRS = 1 << srs_pdu.num_symbols;
uint8_t N_ap = 1 << srs_pdu.num_ant_ports;
int16_t snr_per_rb[srs_pdu.bwp_size];
uint16_t timing_advance_offset;
int16_t timing_advance_offset_nsec[n_rx];
int srs_est;
......@@ -576,7 +571,7 @@ int main(int argc, char *argv[])
N_ap,
N_symb_SRS,
ofdm_symbol_size,
srs,
&srs_job,
&srs_est,
&snr,
srs_estimated_channel_freq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment