|
|
|
@ -68,7 +68,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 5)) {
|
|
|
|
|
if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 0)) {
|
|
|
|
|
started = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -108,21 +108,49 @@ void mac::start_trace()
|
|
|
|
|
|
|
|
|
|
void mac::write_trace(std::string filename)
|
|
|
|
|
{
|
|
|
|
|
tr_start_time.writeToBinary(filename + ".start");
|
|
|
|
|
tr_end_time.writeToBinary(filename + ".end");
|
|
|
|
|
tr_exec_total.writeToBinary(filename + ".total");
|
|
|
|
|
tr_exec_dl.writeToBinary(filename + ".dl");
|
|
|
|
|
tr_exec_ul.writeToBinary(filename + ".ul");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mac::tr_log_start(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
if (tr_enabled) {
|
|
|
|
|
tr_start_time.push_cur_time_us(tti);
|
|
|
|
|
gettimeofday(&tr_time_total[1], NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mac::tr_log_end(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
if (tr_enabled) {
|
|
|
|
|
tr_end_time.push_cur_time_us(tti);
|
|
|
|
|
/* compute total execution time */
|
|
|
|
|
gettimeofday(&tr_time_total[2], NULL);
|
|
|
|
|
get_time_interval(tr_time_total);
|
|
|
|
|
tr_exec_total.push(tti, tr_time_total[0].tv_usec);
|
|
|
|
|
|
|
|
|
|
/* ul execution time is from the call to tr_log_ul */
|
|
|
|
|
memcpy(&tr_time_ul[2], &tr_time_total[2], sizeof(struct timeval));
|
|
|
|
|
get_time_interval(tr_time_ul);
|
|
|
|
|
tr_exec_ul.push(tti, tr_time_ul[0].tv_usec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mac::tr_log_ul(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
if (tr_enabled) {
|
|
|
|
|
/* DL execution time is from the call to tr_log_dl to the call to tr_log_ul */
|
|
|
|
|
gettimeofday(&tr_time_dl[2], NULL);
|
|
|
|
|
get_time_interval(tr_time_dl);
|
|
|
|
|
tr_exec_dl.push(tti, tr_time_dl[0].tv_usec);
|
|
|
|
|
|
|
|
|
|
memcpy(&tr_time_ul[1], &tr_time_dl[2], sizeof(struct timeval));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mac::tr_log_dl(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
if (tr_enabled) {
|
|
|
|
|
gettimeofday(&tr_time_dl[1], NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -220,7 +248,6 @@ void mac::main_radio_loop() {
|
|
|
|
|
}
|
|
|
|
|
if (is_synchronized) {
|
|
|
|
|
/* Warning: Here order of invocation of procedures is important!! */
|
|
|
|
|
tr_log_end(tti);
|
|
|
|
|
tti = ttisync->wait();
|
|
|
|
|
tr_log_start(tti);
|
|
|
|
|
log_h->step(tti);
|
|
|
|
@ -252,7 +279,8 @@ void mac::main_radio_loop() {
|
|
|
|
|
timers_db.step_all();
|
|
|
|
|
|
|
|
|
|
// Trigger execution of corresponding TTI processor thread
|
|
|
|
|
tti_threads_sync[tti%NOF_TTI_THREADS].increase();
|
|
|
|
|
//tti_threads_sync[tti%NOF_TTI_THREADS].increase();
|
|
|
|
|
tti_threads[0].run_tti(tti);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -598,7 +626,7 @@ bool mac::tti_thread::init(mac* parent_, tti_sync_cv *sync_)
|
|
|
|
|
log_h = parent->log_h;
|
|
|
|
|
sync = sync_;
|
|
|
|
|
|
|
|
|
|
started = threads_new_rt(&thread, tti_thread_runner, this);
|
|
|
|
|
//started = threads_new_rt(&thread, tti_thread_runner, this);
|
|
|
|
|
return started;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -614,68 +642,69 @@ void mac::tti_thread::run()
|
|
|
|
|
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);
|
|
|
|
|
run_tti(tti);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate scheduling request if we have to
|
|
|
|
|
if (parent->phy_h->sr_is_ready_to_send(tti+4)) {
|
|
|
|
|
ul_buffer->generate_sr();
|
|
|
|
|
}
|
|
|
|
|
void mac::tti_thread::run_tti(uint32_t tti) {
|
|
|
|
|
// Receive PCH, if requested
|
|
|
|
|
parent->receive_pch(tti);
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Process DL grants always
|
|
|
|
|
parent->process_dl_grants(tti);
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
// 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->send_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|