Commit ade37fea authored by Michael Cook's avatar Michael Cook Committed by Michael Cook

unqueue_matching: Add max_depth argument

Look only at the last `max_depth` items on the queue, at most.
parent 67e19096
...@@ -1084,8 +1084,14 @@ int memcpy_dl_config_req(L1_rxtx_proc_t *proc, ...@@ -1084,8 +1084,14 @@ int memcpy_dl_config_req(L1_rxtx_proc_t *proc,
req->sfn_sf >> 4, req->sfn_sf & 15); req->sfn_sf >> 4, req->sfn_sf & 15);
return 0; return 0;
} }
dlsch_pdu_indicies_t wanted = {num_dlsch_pdu_indicies, dlsch_pdu_indicies}; dlsch_pdu_indicies_t wanted =
nfapi_tx_req_pdu_list_t *matched = unqueue_matching(&tx_req_pdu_queue, match_dl_config_req, &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) if (!matched)
{ {
LOG_W(MAC, "Could not unqueue_matching\n"); LOG_W(MAC, "Could not unqueue_matching\n");
......
...@@ -113,7 +113,7 @@ void *unqueue(queue_t *q) ...@@ -113,7 +113,7 @@ void *unqueue(queue_t *q)
return item; 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) if (pthread_mutex_lock(&q->mutex) != 0)
{ {
...@@ -125,6 +125,12 @@ void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted) ...@@ -125,6 +125,12 @@ void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted)
size_t endi = q->write_index; size_t endi = q->write_index;
for (size_t i = 0; i < q->num_items; i++) 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; endi = (endi + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE;
void *candidate = q->items[endi]; void *candidate = q->items[endi];
if (matcher(wanted, candidate)) if (matcher(wanted, candidate))
......
...@@ -55,7 +55,8 @@ void *unqueue(queue_t *q); ...@@ -55,7 +55,8 @@ void *unqueue(queue_t *q);
typedef bool queue_matcher_t(void *wanted, void *candidate); 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. 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 */ 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);
...@@ -128,7 +128,7 @@ int main(void) ...@@ -128,7 +128,7 @@ int main(void)
init_queue(&queue); init_queue(&queue);
// empty queue // empty queue
p = unqueue_matching(&queue, matcher, &thing1); p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
EQUAL(p, NULL); EQUAL(p, NULL);
EQUAL(queue.num_items, 0); EQUAL(queue.num_items, 0);
...@@ -136,14 +136,39 @@ int main(void) ...@@ -136,14 +136,39 @@ int main(void)
if (!put_queue(&queue, &thing1)) if (!put_queue(&queue, &thing1))
FAIL; FAIL;
EQUAL(queue.num_items, 1); EQUAL(queue.num_items, 1);
p = unqueue_matching(&queue, matcher, &thing2); p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing2);
EQUAL(p, NULL); EQUAL(p, NULL);
EQUAL(queue.num_items, 1); 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(p, &thing1);
EQUAL(queue.num_items, 0); 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 // fill the queue then remove every other item
init_queue(&queue);
for (int i = 0; i < MAX_QUEUE_SIZE; ++i) for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
{ {
if (!put_queue(&queue, &things[i])) if (!put_queue(&queue, &things[i]))
...@@ -151,15 +176,15 @@ int main(void) ...@@ -151,15 +176,15 @@ int main(void)
FAIL; FAIL;
} }
} }
p = unqueue_matching(&queue, matcher, &thing1); p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
EQUAL(p, NULL); EQUAL(p, NULL);
for (int i = MAX_QUEUE_SIZE - 1; i >= 0; i -= 2) 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(p, &things[i]);
} }
EQUAL(queue.num_items, MAX_QUEUE_SIZE / 2); 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); EQUAL(p, NULL);
for (int i = 0; i < MAX_QUEUE_SIZE; i += 2) for (int i = 0; i < MAX_QUEUE_SIZE; i += 2)
{ {
...@@ -176,15 +201,15 @@ int main(void) ...@@ -176,15 +201,15 @@ int main(void)
FAIL; FAIL;
} }
} }
p = unqueue_matching(&queue, matcher, &thing1); p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
EQUAL(p, NULL); EQUAL(p, NULL);
for (int i = 0; i < MAX_QUEUE_SIZE; i += 3) 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(p, &things[i]);
} }
EQUAL(queue.num_items, MAX_QUEUE_SIZE * 2 / 3); 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); EQUAL(p, NULL);
for (int i = 0; i < MAX_QUEUE_SIZE; ++i) for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment