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_)
{
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;

@ -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();

@ -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 */

@ -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;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)) {
started = true;
}
return started;
}
@ -70,6 +79,9 @@ void mac::stop()
{
started = false;
pthread_join(mac_thread, NULL);
for (int i=0;i<NOF_TTI_THREADS;i++) {
tti_threads[i].stop();
}
}
int mac::get_tti()
@ -188,6 +200,10 @@ void mac::main_radio_loop() {
for (int i=0;i<1000;i++) {
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;
} else {
Error("Starting PHY receiver\n");
@ -232,62 +248,12 @@ void mac::main_radio_loop() {
ra_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();
// 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);
}
}
}
}
}
}

Loading…
Cancel
Save