diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 7020e102289161455764f6342577f4095536f1e9..2dd88a582c8013a97afe8619b284fb5d181ce679 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1084,8 +1084,14 @@ int memcpy_dl_config_req(L1_rxtx_proc_t *proc, req->sfn_sf >> 4, req->sfn_sf & 15); return 0; } - dlsch_pdu_indicies_t wanted = {num_dlsch_pdu_indicies, dlsch_pdu_indicies}; - nfapi_tx_req_pdu_list_t *matched = unqueue_matching(&tx_req_pdu_queue, match_dl_config_req, &wanted); + dlsch_pdu_indicies_t wanted = + { + num_dlsch_pdu_indicies, + dlsch_pdu_indicies, + }; + nfapi_tx_req_pdu_list_t *matched = + unqueue_matching(&tx_req_pdu_queue, /*max_depth=*/ 2, + match_dl_config_req, &wanted); if (!matched) { LOG_W(MAC, "Could not unqueue_matching\n"); diff --git a/openair2/PHY_INTERFACE/queue.c b/openair2/PHY_INTERFACE/queue.c index af0fcc6f7cfb34edf00a81076e2e343a8e90b987..94b6598dc34b3b5c09aba3d494778bf597088c15 100644 --- a/openair2/PHY_INTERFACE/queue.c +++ b/openair2/PHY_INTERFACE/queue.c @@ -113,7 +113,7 @@ void *unqueue(queue_t *q) return item; } -void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted) +void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted) { if (pthread_mutex_lock(&q->mutex) != 0) { @@ -125,6 +125,12 @@ void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted) size_t endi = q->write_index; for (size_t i = 0; i < q->num_items; i++) { + if (max_depth == 0) + { + break; + } + --max_depth; + endi = (endi + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE; void *candidate = q->items[endi]; if (matcher(wanted, candidate)) diff --git a/openair2/PHY_INTERFACE/queue.h b/openair2/PHY_INTERFACE/queue.h index 15ad852abe68440f1496b413b24c57f3b200f16e..ab8d44490d81138121ae1da67b2d2f451668a702 100644 --- a/openair2/PHY_INTERFACE/queue.h +++ b/openair2/PHY_INTERFACE/queue.h @@ -55,7 +55,8 @@ void *unqueue(queue_t *q); typedef bool queue_matcher_t(void *wanted, void *candidate); -/* Unqueue the most recently queued item for watch `matcher(wanted, candidate)` +/* Unqueue the most recently queued item for which `matcher(wanted, candidate)` returns true where `candidate` is an item currently on the queue. + Look only at the last `max_depth` items on the queue, at most. Returns the candidate item, or NULL if none matches */ -void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted); +void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted); diff --git a/openair2/PHY_INTERFACE/queue_test.c b/openair2/PHY_INTERFACE/queue_test.c index 020814cb9cf94d7b00c521d64ddb868a0841cc1a..e33a437b43564ae05334c8544272cb2ff9209783 100644 --- a/openair2/PHY_INTERFACE/queue_test.c +++ b/openair2/PHY_INTERFACE/queue_test.c @@ -128,7 +128,7 @@ int main(void) init_queue(&queue); // empty queue - p = unqueue_matching(&queue, matcher, &thing1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); EQUAL(p, NULL); EQUAL(queue.num_items, 0); @@ -136,14 +136,39 @@ int main(void) if (!put_queue(&queue, &thing1)) FAIL; EQUAL(queue.num_items, 1); - p = unqueue_matching(&queue, matcher, &thing2); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing2); EQUAL(p, NULL); EQUAL(queue.num_items, 1); - p = unqueue_matching(&queue, matcher, &thing1); + + p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &thing1); + EQUAL(p, NULL); + EQUAL(queue.num_items, 1); + + p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &thing1); EQUAL(p, &thing1); EQUAL(queue.num_items, 0); + // more max_queue values + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(p, NULL); + p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(p, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(queue.num_items, MAX_QUEUE_SIZE - 1); + p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 2, matcher, &things[0]); + EQUAL(p, NULL); + p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 1, matcher, &things[0]); + EQUAL(p, &things[0]); + EQUAL(queue.num_items, MAX_QUEUE_SIZE - 2); + // fill the queue then remove every other item + init_queue(&queue); for (int i = 0; i < MAX_QUEUE_SIZE; ++i) { if (!put_queue(&queue, &things[i])) @@ -151,15 +176,15 @@ int main(void) FAIL; } } - p = unqueue_matching(&queue, matcher, &thing1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); EQUAL(p, NULL); for (int i = MAX_QUEUE_SIZE - 1; i >= 0; i -= 2) { - p = unqueue_matching(&queue, matcher, &things[i]); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]); EQUAL(p, &things[i]); } EQUAL(queue.num_items, MAX_QUEUE_SIZE / 2); - p = unqueue_matching(&queue, matcher, &thing1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); EQUAL(p, NULL); for (int i = 0; i < MAX_QUEUE_SIZE; i += 2) { @@ -176,15 +201,15 @@ int main(void) FAIL; } } - p = unqueue_matching(&queue, matcher, &thing1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); EQUAL(p, NULL); for (int i = 0; i < MAX_QUEUE_SIZE; i += 3) { - p = unqueue_matching(&queue, matcher, &things[i]); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]); EQUAL(p, &things[i]); } EQUAL(queue.num_items, MAX_QUEUE_SIZE * 2 / 3); - p = unqueue_matching(&queue, matcher, &thing1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); EQUAL(p, NULL); for (int i = 0; i < MAX_QUEUE_SIZE; ++i) {