MAC creates N threads for TTI processing

master
ismagom 10 years ago
parent 3039de17f9
commit f296a7a168

@ -48,6 +48,7 @@ class tti_sync
tti_sync(uint32_t modulus_) tti_sync(uint32_t modulus_)
{ {
modulus = modulus_; modulus = modulus_;
increment = 1;
init_counters(0); init_counters(0);
} }
virtual void increase() = 0; virtual void increase() = 0;
@ -56,16 +57,19 @@ class tti_sync
virtual void set_producer_cntr(uint32_t) = 0; virtual void set_producer_cntr(uint32_t) = 0;
uint32_t get_producer_cntr() { return producer_cntr; } uint32_t get_producer_cntr() { return producer_cntr; }
uint32_t get_consumer_cntr() { return consumer_cntr; } uint32_t get_consumer_cntr() { return consumer_cntr; }
void set_increment(uint32_t increment_) {
increment = increment_;
}
protected: protected:
void increase_producer() { producer_cntr = (producer_cntr + 1)%modulus; } void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; }
void increase_consumer() { consumer_cntr = (consumer_cntr + 1)%modulus; } void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; }
bool wait_condition() { return producer_cntr == consumer_cntr; } bool wait_condition() { return producer_cntr == consumer_cntr; }
void init_counters(uint32_t val) void init_counters(uint32_t val)
{ {
consumer_cntr = val; consumer_cntr = val;
producer_cntr = val; producer_cntr = val;
} }
uint32_t increment;
uint32_t modulus; uint32_t modulus;
uint32_t producer_cntr; uint32_t producer_cntr;
uint32_t consumer_cntr; uint32_t consumer_cntr;

@ -44,7 +44,7 @@ namespace ue {
class tti_sync_cv : public tti_sync class tti_sync_cv : public tti_sync
{ {
public: public:
tti_sync_cv(uint32_t modulus); tti_sync_cv(uint32_t modulus = 10240);
~tti_sync_cv(); ~tti_sync_cv();
void increase(); void increase();
uint32_t wait(); uint32_t wait();

@ -30,6 +30,7 @@
#include "srsapps/common/log.h" #include "srsapps/common/log.h"
#include "srsapps/common/tti_sync.h" #include "srsapps/common/tti_sync.h"
#include "srsapps/common/tti_sync_cv.h"
#include "srsapps/ue/phy/phy.h" #include "srsapps/ue/phy/phy.h"
#include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/mac_params.h"
#include "srsapps/ue/mac/dl_harq.h" #include "srsapps/ue/mac/dl_harq.h"
@ -102,11 +103,30 @@ public:
NOF_MAC_TIMERS NOF_MAC_TIMERS
} mac_timers_t; } 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: 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 // Interaction with PHY
tti_sync *ttisync; tti_sync *ttisync;
phy *phy_h; phy *phy_h;
log *log_h; log *log_h;
/* Logical channel (lch) IO */ /* Logical channel (lch) IO */

@ -40,6 +40,8 @@
namespace srslte { namespace srslte {
namespace ue { namespace ue {
bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
{ {
started = false; started = false;
@ -59,6 +61,13 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
is_first_of_burst = true; is_first_of_burst = true;
reset(); reset();
for (int i=0;i<NOF_TTI_THREADS;i++) {
tti_threads_sync[i].set_increment(NOF_TTI_THREADS);
if (!tti_threads[i].init(this, &tti_threads_sync[i])) {
return false;
}
}
if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 5)) { if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 5)) {
started = true; started = true;
} }
@ -70,6 +79,9 @@ void mac::stop()
{ {
started = false; started = false;
pthread_join(mac_thread, NULL); pthread_join(mac_thread, NULL);
for (int i=0;i<NOF_TTI_THREADS;i++) {
tti_threads[i].stop();
}
} }
int mac::get_tti() int mac::get_tti()
@ -188,6 +200,10 @@ void mac::main_radio_loop() {
for (int i=0;i<1000;i++) { for (int i=0;i<1000;i++) {
tti = ttisync->wait(); tti = ttisync->wait();
} }
for (int i=0;i<NOF_TTI_THREADS;i++) {
tti_threads_sync[i].set_producer_cntr(tti+i);
tti_threads_sync[i].resync();
}
is_synchronized = true; is_synchronized = true;
} else { } else {
Error("Starting PHY receiver\n"); Error("Starting PHY receiver\n");
@ -233,61 +249,11 @@ void mac::main_radio_loop() {
ra_procedure.step(tti); ra_procedure.step(tti);
//phr_procedure.step(tti); //phr_procedure.step(tti);
// Receive PCH, if requested
receive_pch(tti);
// Process DL grants always
process_dl_grants(tti);
// Send pending HARQ ACK, if any, and contention resolution is resolved
if (dl_harq.is_ack_pending_resolution()) {
ra_procedure.step(tti);
if (ra_procedure.is_successful() || ra_procedure.is_response_error()) {
Info("Sending pending ACK for contention resolution PHY TTI: %d\n", phy_h->get_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(); timers_db.step_all();
// Check if there is pending CCCH SDU in Multiplexing Unit // Trigger execution of corresponding TTI processor thread
if (mux_unit.is_pending_ccch_sdu()) { tti_threads_sync[tti%NOF_TTI_THREADS].increase();
// 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);
}
}
}
}
} }
} }

Loading…
Cancel
Save