rlc_am_lte: convert mutexes to std::mutex

replace all pthread_mutex with std::mutex and use lock_guard and unique_lock (where needed)
This commit is contained in:
Andre Puschmann 2021-03-09 17:44:27 +01:00
parent 20cbc48f90
commit 16de8668e0
2 changed files with 30 additions and 68 deletions

View File

@ -350,7 +350,7 @@ private:
pdcp_sn_vector_t notify_info_vec; pdcp_sn_vector_t notify_info_vec;
// Mutexes // Mutexes
pthread_mutex_t mutex; std::mutex mutex;
}; };
// Receiver sub-class // Receiver sub-class
@ -412,8 +412,8 @@ private:
uint32_t vr_ms = 0; // Max status tx state. Highest possible value of SN for ACK_SN in status PDU. uint32_t vr_ms = 0; // Max status tx state. Highest possible value of SN for ACK_SN in status PDU.
uint32_t vr_h = 0; // Highest rx state. SN following PDU with highest SN among rxed PDUs. uint32_t vr_h = 0; // Highest rx state. SN following PDU with highest SN among rxed PDUs.
// Mutexes // Mutex to protect members
pthread_mutex_t mutex; std::mutex mutex;
// Rx windows // Rx windows
rlc_ringbuffer_t<rlc_amd_rx_pdu_t> rx_window; rlc_ringbuffer_t<rlc_amd_rx_pdu_t> rx_window;

View File

@ -210,12 +210,10 @@ rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) :
poll_retx_timer(parent_->timers->get_unique_timer()), poll_retx_timer(parent_->timers->get_unique_timer()),
status_prohibit_timer(parent_->timers->get_unique_timer()) status_prohibit_timer(parent_->timers->get_unique_timer())
{ {
pthread_mutex_init(&mutex, NULL);
} }
rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx() rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx()
{ {
pthread_mutex_destroy(&mutex);
} }
void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback)
@ -262,7 +260,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop()
{ {
empty_queue(); empty_queue();
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
tx_enabled = false; tx_enabled = false;
@ -290,13 +288,11 @@ void rlc_am_lte::rlc_am_lte_tx::stop()
// Drop all SDU info in queue // Drop all SDU info in queue
undelivered_sdu_info_queue.clear(); undelivered_sdu_info_queue.clear();
pthread_mutex_unlock(&mutex);
} }
void rlc_am_lte::rlc_am_lte_tx::empty_queue() void rlc_am_lte::rlc_am_lte_tx::empty_queue()
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
// deallocate all SDUs in transmit queue // deallocate all SDUs in transmit queue
while (tx_sdu_queue.size() > 0) { while (tx_sdu_queue.size() > 0) {
@ -305,8 +301,6 @@ void rlc_am_lte::rlc_am_lte_tx::empty_queue()
// deallocate SDU that is currently processed // deallocate SDU that is currently processed
tx_sdu.reset(); tx_sdu.reset();
pthread_mutex_unlock(&mutex);
} }
void rlc_am_lte::rlc_am_lte_tx::reestablish() void rlc_am_lte::rlc_am_lte_tx::reestablish()
@ -350,7 +344,7 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn)
uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
uint32_t n_bytes = 0; uint32_t n_bytes = 0;
uint32_t n_sdus = 0; uint32_t n_sdus = 0;
@ -409,22 +403,19 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes); logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes);
} }
pthread_mutex_unlock(&mutex);
return n_bytes; return n_bytes;
} }
int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
if (!tx_enabled) { if (!tx_enabled) {
pthread_mutex_unlock(&mutex);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (sdu.get() == nullptr) { if (sdu.get() == nullptr) {
logger.warning("NULL SDU pointer in write_sdu()"); logger.warning("NULL SDU pointer in write_sdu()");
pthread_mutex_unlock(&mutex);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -445,7 +436,6 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
RB_NAME, RB_NAME,
ret.error()->N_bytes, ret.error()->N_bytes,
tx_sdu_queue.size()); tx_sdu_queue.size());
pthread_mutex_unlock(&mutex);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -455,12 +445,10 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) { if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) {
logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn); logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn);
pthread_mutex_unlock(&mutex);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn); undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn);
pthread_mutex_unlock(&mutex);
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -479,12 +467,10 @@ bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full()
int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
int pdu_size = 0;
if (not tx_enabled) { if (not tx_enabled) {
goto unlock_and_exit; return 0;
} }
logger.debug("MAC opportunity - %d bytes", nof_bytes); logger.debug("MAC opportunity - %d bytes", nof_bytes);
@ -492,13 +478,12 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
if (not tx_enabled) { if (not tx_enabled) {
logger.debug("RLC entity not active. Not generating PDU."); logger.debug("RLC entity not active. Not generating PDU.");
goto unlock_and_exit; return 0;
} }
// Tx STATUS if requested // Tx STATUS if requested
if (do_status() && not status_prohibit_timer.is_running()) { if (do_status() && not status_prohibit_timer.is_running()) {
pdu_size = build_status_pdu(payload, nof_bytes); return build_status_pdu(payload, nof_bytes);
goto unlock_and_exit;
} }
// Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU // Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU
@ -508,23 +493,19 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
// RETX if required // RETX if required
if (not retx_queue.empty()) { if (not retx_queue.empty()) {
pdu_size = build_retx_pdu(payload, nof_bytes); int32_t pdu_size = build_retx_pdu(payload, nof_bytes);
if (pdu_size > 0) { if (pdu_size > 0) {
goto unlock_and_exit; return pdu_size;
} }
} }
// Build a PDU from SDUs // Build a PDU from SDUs
pdu_size = build_data_pdu(payload, nof_bytes); return build_data_pdu(payload, nof_bytes);
unlock_and_exit:
pthread_mutex_unlock(&mutex);
return pdu_size;
} }
void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id)
{ {
pthread_mutex_lock(&mutex); std::unique_lock<std::mutex> lock(mutex);
if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) { if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) {
logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration()); logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration());
// Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if // Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if
@ -534,7 +515,8 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id)
retransmit_pdu(); retransmit_pdu();
} }
} }
pthread_mutex_unlock(&mutex);
lock.unlock();
if (bsr_callback) { if (bsr_callback) {
bsr_callback(parent->lcid, get_buffer_state(), 0); bsr_callback(parent->lcid, get_buffer_state(), 0);
@ -1091,7 +1073,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
return; return;
} }
pthread_mutex_lock(&mutex); std::unique_lock<std::mutex> lock(mutex);
logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME); logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME);
@ -1196,7 +1178,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
debug_state(); debug_state();
pthread_mutex_unlock(&mutex); lock.unlock();
// Notify PDCP without holding Tx mutex // Notify PDCP without holding Tx mutex
if (not notify_info_vec.empty()) { if (not notify_info_vec.empty()) {
@ -1335,13 +1317,10 @@ rlc_am_lte::rlc_am_lte_rx::rlc_am_lte_rx(rlc_am_lte* parent_) :
pool(byte_buffer_pool::get_instance()), pool(byte_buffer_pool::get_instance()),
logger(parent_->logger), logger(parent_->logger),
reordering_timer(parent_->timers->get_unique_timer()) reordering_timer(parent_->timers->get_unique_timer())
{ {}
pthread_mutex_init(&mutex, NULL);
}
rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx() rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx()
{ {
pthread_mutex_destroy(&mutex);
} }
bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_) bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_)
@ -1370,7 +1349,7 @@ void rlc_am_lte::rlc_am_lte_rx::reestablish()
void rlc_am_lte::rlc_am_lte_rx::stop() void rlc_am_lte::rlc_am_lte_rx::stop()
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
if (parent->timers != nullptr && reordering_timer.is_valid()) { if (parent->timers != nullptr && reordering_timer.is_valid()) {
reordering_timer.stop(); reordering_timer.stop();
@ -1392,8 +1371,6 @@ void rlc_am_lte::rlc_am_lte_rx::stop()
// Drop all messages in RX window // Drop all messages in RX window
rx_window.clear(); rx_window.clear();
pthread_mutex_unlock(&mutex);
} }
/** Called from stack thread when MAC has received a new RLC PDU /** Called from stack thread when MAC has received a new RLC PDU
@ -1756,10 +1733,9 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus()
void rlc_am_lte::rlc_am_lte_rx::reset_status() void rlc_am_lte::rlc_am_lte_rx::reset_status()
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
do_status = false; do_status = false;
poll_received = false; poll_received = false;
pthread_mutex_unlock(&mutex);
} }
bool rlc_am_lte::rlc_am_lte_rx::get_do_status() bool rlc_am_lte::rlc_am_lte_rx::get_do_status()
@ -1772,19 +1748,16 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b
if (nof_bytes < 1) { if (nof_bytes < 1) {
return; return;
} }
pthread_mutex_lock(&mutex);
if (rlc_am_is_control_pdu(payload)) { if (rlc_am_is_control_pdu(payload)) {
// unlock mutex and pass to Tx subclass
pthread_mutex_unlock(&mutex);
parent->tx.handle_control_pdu(payload, nof_bytes); parent->tx.handle_control_pdu(payload, nof_bytes);
} else { } else {
std::lock_guard<std::mutex> lock(mutex);
rlc_amd_pdu_header_t header = {}; rlc_amd_pdu_header_t header = {};
uint32_t payload_len = nof_bytes; uint32_t payload_len = nof_bytes;
rlc_am_read_data_pdu_header(&payload, &payload_len, &header); rlc_am_read_data_pdu_header(&payload, &payload_len, &header);
if (payload_len > nof_bytes) { if (payload_len > nof_bytes) {
logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len); logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len);
pthread_mutex_unlock(&mutex);
return; return;
} }
if (header.rf) { if (header.rf) {
@ -1792,26 +1765,19 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b
} else { } else {
handle_data_pdu(payload, payload_len, header); handle_data_pdu(payload, payload_len, header);
} }
pthread_mutex_unlock(&mutex);
} }
} }
uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes() uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes()
{ {
uint32_t buff_size = 0; std::lock_guard<std::mutex> lock(mutex);
pthread_mutex_lock(&mutex); return rx_window.get_buffered_bytes();
buff_size = rx_window.get_buffered_bytes();
pthread_mutex_unlock(&mutex);
return buff_size;
} }
uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms() uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms()
{ {
uint32_t latency = 0; std::lock_guard<std::mutex> lock(mutex);
pthread_mutex_lock(&mutex); return sdu_rx_latency_ms.value();
latency = sdu_rx_latency_ms.value();
pthread_mutex_unlock(&mutex);
return latency;
} }
/** /**
@ -1821,7 +1787,7 @@ uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms()
*/ */
void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id)
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) { if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) {
logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms); logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms);
@ -1842,13 +1808,12 @@ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id)
debug_state(); debug_state();
} }
pthread_mutex_unlock(&mutex);
} }
// Called from Tx object to pack status PDU that doesn't exceed a given size // Called from Tx object to pack status PDU that doesn't exceed a given size
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size) int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size)
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
status->N_nack = 0; status->N_nack = 0;
status->ack_sn = vr_r; // start with lower edge of the rx window status->ack_sn = vr_r; // start with lower edge of the rx window
@ -1880,7 +1845,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui
rlc_am_packed_length(status), rlc_am_packed_length(status),
max_pdu_size, max_pdu_size,
status->N_nack); status->N_nack);
pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
break; break;
@ -1888,14 +1852,13 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui
i = (i + 1) % MOD; i = (i + 1) % MOD;
} }
pthread_mutex_unlock(&mutex);
return rlc_am_packed_length(status); return rlc_am_packed_length(status);
} }
// Called from Tx object to obtain length of the full status PDU // Called from Tx object to obtain length of the full status PDU
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length() int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length()
{ {
pthread_mutex_lock(&mutex); std::lock_guard<std::mutex> lock(mutex);
rlc_status_pdu_t status = {}; rlc_status_pdu_t status = {};
status.ack_sn = vr_ms; status.ack_sn = vr_ms;
uint32_t i = vr_r; uint32_t i = vr_r;
@ -1905,7 +1868,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length()
} }
i = (i + 1) % MOD; i = (i + 1) % MOD;
} }
pthread_mutex_unlock(&mutex);
return rlc_am_packed_length(&status); return rlc_am_packed_length(&status);
} }