From f296a7a168b093d1739b1ec258f21f3d9433e45d Mon Sep 17 00:00:00 2001 From: ismagom Date: Thu, 18 Jun 2015 22:58:43 +0200 Subject: [PATCH] MAC creates N threads for TTI processing --- .../common/include/srsapps/common/tti_sync.h | 10 +- .../include/srsapps/common/tti_sync_cv.h | 2 +- srsapps/ue/mac/include/srsapps/ue/mac/mac.h | 22 ++- srsapps/ue/mac/src/mac.cc | 167 ++++++++++++------ 4 files changed, 141 insertions(+), 60 deletions(-) diff --git a/srsapps/common/include/srsapps/common/tti_sync.h b/srsapps/common/include/srsapps/common/tti_sync.h index 6779e76c8..7a45939ea 100644 --- a/srsapps/common/include/srsapps/common/tti_sync.h +++ b/srsapps/common/include/srsapps/common/tti_sync.h @@ -48,6 +48,7 @@ class tti_sync tti_sync(uint32_t modulus_) { modulus = modulus_; + increment = 1; init_counters(0); } virtual void increase() = 0; @@ -56,16 +57,19 @@ class tti_sync virtual void set_producer_cntr(uint32_t) = 0; uint32_t get_producer_cntr() { return producer_cntr; } uint32_t get_consumer_cntr() { return consumer_cntr; } - + void set_increment(uint32_t increment_) { + increment = increment_; + } protected: - void increase_producer() { producer_cntr = (producer_cntr + 1)%modulus; } - void increase_consumer() { consumer_cntr = (consumer_cntr + 1)%modulus; } + void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; } + void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; } bool wait_condition() { return producer_cntr == consumer_cntr; } void init_counters(uint32_t val) { consumer_cntr = val; producer_cntr = val; } + uint32_t increment; uint32_t modulus; uint32_t producer_cntr; uint32_t consumer_cntr; diff --git a/srsapps/common/include/srsapps/common/tti_sync_cv.h b/srsapps/common/include/srsapps/common/tti_sync_cv.h index fea9a6db7..a4026f42e 100644 --- a/srsapps/common/include/srsapps/common/tti_sync_cv.h +++ b/srsapps/common/include/srsapps/common/tti_sync_cv.h @@ -44,7 +44,7 @@ namespace ue { class tti_sync_cv : public tti_sync { public: - tti_sync_cv(uint32_t modulus); + tti_sync_cv(uint32_t modulus = 10240); ~tti_sync_cv(); void increase(); uint32_t wait(); diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h index e6b3c8f83..57a610cc6 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h @@ -30,6 +30,7 @@ #include "srsapps/common/log.h" #include "srsapps/common/tti_sync.h" +#include "srsapps/common/tti_sync_cv.h" #include "srsapps/ue/phy/phy.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/dl_harq.h" @@ -101,12 +102,31 @@ public: BSR_TIMER_RETX, NOF_MAC_TIMERS } mac_timers_t; + + class tti_thread { + public: + bool init(mac *parent, tti_sync_cv *ttysync); + void run(); + void stop(); + private: + bool started; + log *log_h; + mac *parent; + tti_sync_cv *sync; + pthread_t thread; + }; private: + + + // TTI processing threads + static const int NOF_TTI_THREADS = 2; + tti_thread tti_threads[NOF_TTI_THREADS]; + tti_sync_cv tti_threads_sync[NOF_TTI_THREADS]; + // Interaction with PHY tti_sync *ttisync; phy *phy_h; - log *log_h; /* Logical channel (lch) IO */ diff --git a/srsapps/ue/mac/src/mac.cc b/srsapps/ue/mac/src/mac.cc index c5bef4cca..e1e15a63b 100644 --- a/srsapps/ue/mac/src/mac.cc +++ b/srsapps/ue/mac/src/mac.cc @@ -40,6 +40,8 @@ namespace srslte { namespace ue { + + bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) { started = false; @@ -59,10 +61,17 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) is_first_of_burst = true; reset(); + for (int i=0;iwait(); } + for (int i=0;iget_current_tti()); - dl_harq.send_pending_ack_contention_resolution(); - } - } - - // Process UL grants if RA procedure is done and we have pending data or in contention resolution - if (ra_procedure.is_contention_resolution() || ra_procedure.is_successful()) { - process_ul_grants(tti); - } - ul_buffer *ul_buffer = phy_h->get_ul_buffer(tti+4); - - // Generate scheduling request if we have to - if (phy_h->sr_is_ready_to_send(tti+4)) { - ul_buffer->generate_sr(); - } - - // The UL buffer is released when successfully transmitted. - if (ul_buffer->is_released()) { - ul_buffer->ready(); - is_first_of_burst = false; - } else if (ul_buffer->uci_ready() || ul_buffer->srs_is_ready_to_send()) { - // If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal - ul_buffer->generate_data(); - ul_buffer->ready(); - is_first_of_burst = false; - } else { - if (!is_first_of_burst) { - ul_buffer->set_end_of_burst(); - is_first_of_burst = true; - } - } - + timers_db.step_all(); + + // Trigger execution of corresponding TTI processor thread + tti_threads_sync[tti%NOF_TTI_THREADS].increase(); - // Check if there is pending CCCH SDU in Multiplexing Unit - if (mux_unit.is_pending_ccch_sdu()) { - // Start RA procedure - if (!ra_procedure.in_progress() && !ra_procedure.is_successful()) { - ra_procedure.start_rlc_order(); - } - } - if (ra_procedure.is_successful() && phy_rnti != params_db.get_param(mac_params::RNTI_C) && params_db.get_param(mac_params::RNTI_C) > 0) { - phy_rnti = params_db.get_param(mac_params::RNTI_C); - set_phy_crnti(phy_rnti); - } } } } @@ -620,5 +586,96 @@ void mac::setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_t } +void* tti_thread_runner(void *arg) { + mac::tti_thread* x = (mac::tti_thread*) arg; + x->run(); + return NULL; +} + +bool mac::tti_thread::init(mac* parent_, tti_sync_cv *sync_) +{ + parent = parent_; + log_h = parent->log_h; + sync_ = sync; + + started = threads_new_rt(&thread, tti_thread_runner, this); + return started; +} + +void mac::tti_thread::stop() +{ + started = false; + pthread_join(thread, NULL); +} + +void mac::tti_thread::run() +{ + while(started) { + uint32_t tti = sync->wait(); + + if (parent->is_synchronized) { + // Receive PCH, if requested + parent->receive_pch(tti); + + // Process DL grants always + parent->process_dl_grants(tti); + + // Send pending HARQ ACK, if any, and contention resolution is resolved + if (parent->dl_harq.is_ack_pending_resolution()) { + parent->ra_procedure.step(tti); + if (parent->ra_procedure.is_successful() || parent->ra_procedure.is_response_error()) { + Info("Sending pending ACK for contention resolution PHY TTI: %d\n", parent->phy_h->get_current_tti()); + parent->dl_harq.send_pending_ack_contention_resolution(); + } + } + + // Process UL grants if RA procedure is done or in contention resolution + if (parent->ra_procedure.is_contention_resolution() || parent->ra_procedure.is_successful()) { + parent->process_ul_grants(tti); + } + + // If ACK/SR was pending but there was no PUSCH transmission, transmit now through PUCCH + ul_buffer *ul_buffer = parent->phy_h->get_ul_buffer(tti+4); + + // Generate scheduling request if we have to + if (parent->phy_h->sr_is_ready_to_send(tti+4)) { + ul_buffer->generate_sr(); + } + + // The UL buffer is released when successfully transmitted. + if (ul_buffer->is_released()) { + ul_buffer->ready(); + parent->is_first_of_burst = false; + } else if (ul_buffer->uci_ready() || ul_buffer->srs_is_ready_to_send()) { + // If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal + ul_buffer->generate_data(); + ul_buffer->ready(); + parent->is_first_of_burst = false; + } else { + if (!parent->is_first_of_burst) { + ul_buffer->set_end_of_burst(); + parent->is_first_of_burst = true; + } + } + + // Check if there is pending CCCH SDU in Multiplexing Unit + if (parent->mux_unit.is_pending_ccch_sdu()) { + // Start RA procedure + if (!parent->ra_procedure.in_progress() && !parent->ra_procedure.is_successful()) { + parent->ra_procedure.start_rlc_order(); + } + } + if (parent->ra_procedure.is_successful() && parent->phy_rnti != parent->params_db.get_param(mac_params::RNTI_C) && + parent->params_db.get_param(mac_params::RNTI_C) > 0) + { + parent->phy_rnti = parent->params_db.get_param(mac_params::RNTI_C); + parent->set_phy_crnti(parent->phy_rnti); + } + } + } +} + + + } }