From 428d13a07be3a1780f7b414068db2870eddbd18f Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Thu, 4 May 2023 20:05:32 +0800 Subject: [PATCH] sorted_queue.[hc]: sorted_queue_pop and sorted_queue_pop_all --- src/sorted_queue.c | 41 ++++++++++++++++++++++++++++++----- src/sorted_queue.h | 19 +++++++++++----- src/tests/test_sorted_queue.c | 38 +++++++++++++++++++++++++------- 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/src/sorted_queue.c b/src/sorted_queue.c index 481e482..33476b6 100644 --- a/src/sorted_queue.c +++ b/src/sorted_queue.c @@ -70,17 +70,48 @@ void sorted_queue_push_ex(struct sorted_queue *sq, void *data, bool *notify) } fc_list_add_after(dlink, current); *notify = false; - - if (count >= 10) { - logInfo("================== compare count: %d ==========", count); - } } } PTHREAD_MUTEX_UNLOCK(&sq->lcp.lock); } -void sorted_queue_pop_ex(struct sorted_queue *sq, void *less_equal, +void *sorted_queue_pop_ex(struct sorted_queue *sq, + void *less_equal, const bool blocked) +{ + void *data; + struct fc_list_head *current; + + PTHREAD_MUTEX_LOCK(&sq->lcp.lock); + do { + if (fc_list_empty(&sq->head)) { + if (!blocked) { + data = NULL; + break; + } + + pthread_cond_wait(&sq->lcp.cond, + &sq->lcp.lock); + if (fc_list_empty(&sq->head)) { + data = NULL; + break; + } + } + + current = sq->head.next; + data = FC_SORTED_QUEUE_DATA_PTR(sq, current); + if (sq->compare_func(data, less_equal) <= 0) { + fc_list_del_init(current); + } else { + data = NULL; + } + } while (0); + PTHREAD_MUTEX_UNLOCK(&sq->lcp.lock); + + return data; +} + +void sorted_queue_pop_all_ex(struct sorted_queue *sq, void *less_equal, struct fc_list_head *head, const bool blocked) { struct fc_list_head *current; diff --git a/src/sorted_queue.h b/src/sorted_queue.h index c878b13..29a487f 100644 --- a/src/sorted_queue.h +++ b/src/sorted_queue.h @@ -78,14 +78,23 @@ static inline void sorted_queue_push_silence( sorted_queue_push_ex(sq, data, ¬ify); } -void sorted_queue_pop_ex(struct sorted_queue *sq, void *less_equal, +void *sorted_queue_pop_ex(struct sorted_queue *sq, + void *less_equal, const bool blocked); + +#define sorted_queue_pop(sq, less_equal) \ + sorted_queue_pop_ex(sq, less_equal, true) + +#define sorted_queue_try_pop(sq, less_equal) \ + sorted_queue_pop_ex(sq, less_equal, false) + +void sorted_queue_pop_all_ex(struct sorted_queue *sq, void *less_equal, struct fc_list_head *head, const bool blocked); -#define sorted_queue_pop(sq, less_equal, head) \ - sorted_queue_pop_ex(sq, less_equal, head, true) +#define sorted_queue_pop_all(sq, less_equal, head) \ + sorted_queue_pop_all_ex(sq, less_equal, head, true) -#define sorted_queue_try_pop(sq, less_equal, head) \ - sorted_queue_pop_ex(sq, less_equal, head, false) +#define sorted_queue_try_pop_all(sq, less_equal, head) \ + sorted_queue_pop_all_ex(sq, less_equal, head, false) static inline bool sorted_queue_empty(struct sorted_queue *sq) { diff --git a/src/tests/test_sorted_queue.c b/src/tests/test_sorted_queue.c index ae63509..c4eba9c 100644 --- a/src/tests/test_sorted_queue.c +++ b/src/tests/test_sorted_queue.c @@ -72,13 +72,12 @@ static void test1() struct fc_list_head head; set_rand_numbers(1); - for (i=0; in) { + fprintf(stderr, "i: %d != value: %d\n", i, number->n); + break; + } + } + + assert(sorted_queue_try_pop(&sq, &less_equal) == NULL); +} + int main(int argc, char *argv[]) { int result; @@ -160,9 +182,9 @@ int main(int argc, char *argv[]) test1(); test2(); + test3(); end_time = get_current_time_ms(); printf("pass OK, time used: %"PRId64" ms\n", end_time - start_time); return 0; } -