Harald Welte | e4cd267 | 2019-08-06 19:56:16 +0200 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <errno.h> |
| 3 | |
| 4 | #include <osmocom/core/talloc.h> |
| 5 | #include <osmocom/core/utils.h> |
| 6 | #include <osmocom/core/it_q.h> |
| 7 | |
| 8 | struct it_q_test1 { |
| 9 | struct llist_head list; |
| 10 | int *foo; |
| 11 | }; |
| 12 | |
| 13 | struct it_q_test2 { |
| 14 | int foo; |
| 15 | struct llist_head list; |
| 16 | }; |
| 17 | |
| 18 | #define ENTER_TC printf("\n== Entering test case %s\n", __func__) |
| 19 | |
| 20 | static void tc_alloc(void) |
| 21 | { |
| 22 | struct osmo_it_q *q1, *q2; |
| 23 | |
| 24 | ENTER_TC; |
| 25 | |
| 26 | printf("allocating q1\n"); |
| 27 | q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); |
| 28 | OSMO_ASSERT(q1); |
| 29 | |
| 30 | /* ensure that no duplicate allocation for the */ |
| 31 | printf("attempting duplicate allocation of qa\n"); |
| 32 | q2 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); |
| 33 | OSMO_ASSERT(!q2); |
| 34 | |
| 35 | /* ensure that same name can be re-created after destroying old one */ |
| 36 | osmo_it_q_destroy(q1); |
| 37 | printf("re-allocating q1\n"); |
| 38 | q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); |
| 39 | OSMO_ASSERT(q1); |
| 40 | |
| 41 | osmo_it_q_destroy(q1); |
| 42 | } |
| 43 | |
| 44 | static void tc_queue_length(void) |
| 45 | { |
| 46 | struct osmo_it_q *q1; |
| 47 | unsigned int qlen = 3; |
| 48 | struct it_q_test1 *item; |
| 49 | int i, rc; |
| 50 | |
| 51 | ENTER_TC; |
| 52 | |
| 53 | printf("allocating q1\n"); |
| 54 | q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, NULL, NULL); |
| 55 | OSMO_ASSERT(q1); |
| 56 | |
| 57 | printf("adding queue entries up to the limit\n"); |
| 58 | for (i = 0; i < qlen; i++) { |
| 59 | item = talloc_zero(OTC_GLOBAL, struct it_q_test1); |
| 60 | rc = osmo_it_q_enqueue(q1, item, list); |
| 61 | OSMO_ASSERT(rc == 0); |
| 62 | } |
| 63 | printf("attempting to add more than the limit\n"); |
| 64 | item = talloc_zero(OTC_GLOBAL, struct it_q_test1); |
| 65 | rc = osmo_it_q_enqueue(q1, item, list); |
| 66 | OSMO_ASSERT(rc == -ENOSPC); |
| 67 | |
| 68 | osmo_it_q_destroy(q1); |
| 69 | } |
| 70 | |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 71 | static void tc_enqueue_dequeue(void) |
| 72 | { |
| 73 | const unsigned int qlen = 12; |
| 74 | struct it_q_test1 *item; |
| 75 | struct osmo_it_q *q1; |
| 76 | int rc; |
| 77 | |
| 78 | ENTER_TC; |
| 79 | |
| 80 | printf("allocating q1\n"); |
| 81 | q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 12, NULL, NULL); |
| 82 | OSMO_ASSERT(q1); |
| 83 | |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 84 | printf("try dequeueing from an empty queue\n"); |
| 85 | osmo_it_q_dequeue(q1, &item, list); |
| 86 | OSMO_ASSERT(item == NULL); |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 87 | |
| 88 | printf("adding queue entries up to the limit\n"); |
| 89 | for (unsigned int i = 0; i < qlen; i++) { |
| 90 | item = talloc_zero(OTC_GLOBAL, struct it_q_test1); |
| 91 | rc = osmo_it_q_enqueue(q1, item, list); |
| 92 | OSMO_ASSERT(rc == 0); |
| 93 | } |
| 94 | |
| 95 | printf("removing queue entries up to the limit\n"); |
| 96 | for (unsigned int i = 0; i < qlen; i++) { |
| 97 | osmo_it_q_dequeue(q1, &item, list); |
| 98 | OSMO_ASSERT(item != NULL); |
| 99 | talloc_free(item); |
| 100 | } |
| 101 | |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 102 | printf("try dequeueing from an empty queue\n"); |
| 103 | osmo_it_q_dequeue(q1, &item, list); |
| 104 | OSMO_ASSERT(item == NULL); |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 105 | |
| 106 | osmo_it_q_destroy(q1); |
| 107 | } |
| 108 | |
Harald Welte | e4cd267 | 2019-08-06 19:56:16 +0200 | [diff] [blame] | 109 | static int g_read_cb_count; |
| 110 | |
| 111 | static void q_read_cb(struct osmo_it_q *q, struct llist_head *item) |
| 112 | { |
| 113 | struct it_q_test1 *it = container_of(item, struct it_q_test1, list); |
| 114 | *it->foo += 1; |
| 115 | talloc_free(item); |
| 116 | } |
| 117 | |
| 118 | static void tc_eventfd(void) |
| 119 | { |
| 120 | struct osmo_it_q *q1; |
| 121 | unsigned int qlen = 30; |
| 122 | struct it_q_test1 *item; |
| 123 | int i, rc; |
| 124 | |
| 125 | ENTER_TC; |
| 126 | |
| 127 | printf("allocating q1\n"); |
| 128 | q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, q_read_cb, NULL); |
| 129 | OSMO_ASSERT(q1); |
| 130 | osmo_fd_register(&q1->event_ofd); |
| 131 | |
| 132 | /* ensure read-cb isn't called unless we enqueue something */ |
| 133 | osmo_select_main(1); |
| 134 | OSMO_ASSERT(g_read_cb_count == 0); |
| 135 | |
| 136 | /* ensure read-cb is called for each enqueued msg once */ |
| 137 | printf("adding %u queue entries up to the limit\n", qlen); |
| 138 | for (i = 0; i < qlen; i++) { |
| 139 | item = talloc_zero(OTC_GLOBAL, struct it_q_test1); |
| 140 | item->foo = &g_read_cb_count; |
| 141 | rc = osmo_it_q_enqueue(q1, item, list); |
| 142 | OSMO_ASSERT(rc == 0); |
| 143 | } |
| 144 | |
| 145 | osmo_select_main(1); |
| 146 | printf("%u entries were dequeued\n", qlen); |
| 147 | OSMO_ASSERT(g_read_cb_count == qlen); |
| 148 | |
| 149 | osmo_it_q_destroy(q1); |
| 150 | } |
| 151 | |
| 152 | int main(int argc, char **argv) |
| 153 | { |
| 154 | tc_alloc(); |
| 155 | tc_queue_length(); |
Vadim Yanitskiy | 09c8bfc | 2023-12-09 03:43:45 +0700 | [diff] [blame] | 156 | tc_enqueue_dequeue(); |
Harald Welte | e4cd267 | 2019-08-06 19:56:16 +0200 | [diff] [blame] | 157 | tc_eventfd(); |
Oliver Smith | 55934c4 | 2021-01-21 11:57:48 +0100 | [diff] [blame] | 158 | return 0; |
Harald Welte | e4cd267 | 2019-08-06 19:56:16 +0200 | [diff] [blame] | 159 | } |