diff options
author | Harald Welte <laforge@gnumonks.org> | 2019-08-06 19:56:16 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2021-01-06 00:22:13 +0100 |
commit | e4cd267ab18f2d9d66351cce5b5a1aa8cc893c51 (patch) | |
tree | 55051be67c00075cca55bc06b597f3c02a5ea414 /tests | |
parent | 463dca0b9c57f080e8c3c96ad86deca3a6c48424 (diff) |
Add inter-thread queue
This adds an inter-thread queue "it_q" to libosmocore. With it_q,
one can perform thread-safe enqueing of messages to another thread,
who will receive the related messages triggered via an eventfd
handled in the usual libosmocore select loop abstraction.
Change-Id: Ie7d0c5fec715a2a577fae014b0b8a0e9c38418ef
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rw-r--r-- | tests/it_q/it_q_test.c | 119 | ||||
-rw-r--r-- | tests/it_q/it_q_test.ok | 15 | ||||
-rw-r--r-- | tests/testsuite.at | 6 |
4 files changed, 145 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index f769603f..e0220bd8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,6 +41,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \ gad/gad_test \ bsslap/bsslap_test \ bssmap_le/bssmap_le_test \ + it_q/it_q_test \ $(NULL) if ENABLE_MSGFILE @@ -304,6 +305,9 @@ bsslap_bsslap_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la bssmap_le_bssmap_le_test_SOURCES = bssmap_le/bssmap_le_test.c bssmap_le_bssmap_le_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la +it_q_it_q_test_SOURCES = it_q/it_q_test.c +it_q_it_q_test_LDADD = $(LDADD) + # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac :;{ \ @@ -389,6 +393,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ gad/gad_test.ok \ bsslap/bsslap_test.ok \ bssmap_le/bssmap_le_test.ok \ + it_q/it_q_test.ok \ $(NULL) if ENABLE_LIBSCTP diff --git a/tests/it_q/it_q_test.c b/tests/it_q/it_q_test.c new file mode 100644 index 00000000..0d754524 --- /dev/null +++ b/tests/it_q/it_q_test.c @@ -0,0 +1,119 @@ +#include <stdio.h> +#include <errno.h> + +#include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/it_q.h> + +struct it_q_test1 { + struct llist_head list; + int *foo; +}; + +struct it_q_test2 { + int foo; + struct llist_head list; +}; + +#define ENTER_TC printf("\n== Entering test case %s\n", __func__) + +static void tc_alloc(void) +{ + struct osmo_it_q *q1, *q2; + + ENTER_TC; + + printf("allocating q1\n"); + q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); + OSMO_ASSERT(q1); + + /* ensure that no duplicate allocation for the */ + printf("attempting duplicate allocation of qa\n"); + q2 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); + OSMO_ASSERT(!q2); + + /* ensure that same name can be re-created after destroying old one */ + osmo_it_q_destroy(q1); + printf("re-allocating q1\n"); + q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL); + OSMO_ASSERT(q1); + + osmo_it_q_destroy(q1); +} + +static void tc_queue_length(void) +{ + struct osmo_it_q *q1; + unsigned int qlen = 3; + struct it_q_test1 *item; + int i, rc; + + ENTER_TC; + + printf("allocating q1\n"); + q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, NULL, NULL); + OSMO_ASSERT(q1); + + printf("adding queue entries up to the limit\n"); + for (i = 0; i < qlen; i++) { + item = talloc_zero(OTC_GLOBAL, struct it_q_test1); + rc = osmo_it_q_enqueue(q1, item, list); + OSMO_ASSERT(rc == 0); + } + printf("attempting to add more than the limit\n"); + item = talloc_zero(OTC_GLOBAL, struct it_q_test1); + rc = osmo_it_q_enqueue(q1, item, list); + OSMO_ASSERT(rc == -ENOSPC); + + osmo_it_q_destroy(q1); +} + +static int g_read_cb_count; + +static void q_read_cb(struct osmo_it_q *q, struct llist_head *item) +{ + struct it_q_test1 *it = container_of(item, struct it_q_test1, list); + *it->foo += 1; + talloc_free(item); +} + +static void tc_eventfd(void) +{ + struct osmo_it_q *q1; + unsigned int qlen = 30; + struct it_q_test1 *item; + int i, rc; + + ENTER_TC; + + printf("allocating q1\n"); + q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, q_read_cb, NULL); + OSMO_ASSERT(q1); + osmo_fd_register(&q1->event_ofd); + + /* ensure read-cb isn't called unless we enqueue something */ + osmo_select_main(1); + OSMO_ASSERT(g_read_cb_count == 0); + + /* ensure read-cb is called for each enqueued msg once */ + printf("adding %u queue entries up to the limit\n", qlen); + for (i = 0; i < qlen; i++) { + item = talloc_zero(OTC_GLOBAL, struct it_q_test1); + item->foo = &g_read_cb_count; + rc = osmo_it_q_enqueue(q1, item, list); + OSMO_ASSERT(rc == 0); + } + + osmo_select_main(1); + printf("%u entries were dequeued\n", qlen); + OSMO_ASSERT(g_read_cb_count == qlen); + + osmo_it_q_destroy(q1); +} + +int main(int argc, char **argv) +{ + tc_alloc(); + tc_queue_length(); + tc_eventfd(); +} diff --git a/tests/it_q/it_q_test.ok b/tests/it_q/it_q_test.ok new file mode 100644 index 00000000..7f102c61 --- /dev/null +++ b/tests/it_q/it_q_test.ok @@ -0,0 +1,15 @@ + +== Entering test case tc_alloc +allocating q1 +attempting duplicate allocation of qa +re-allocating q1 + +== Entering test case tc_queue_length +allocating q1 +adding queue entries up to the limit +attempting to add more than the limit + +== Entering test case tc_eventfd +allocating q1 +adding 30 queue entries up to the limit +30 entries were dequeued diff --git a/tests/testsuite.at b/tests/testsuite.at index ad93e164..75ce0393 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -427,3 +427,9 @@ AT_KEYWORDS([bssmap_le]) cat $abs_srcdir/bssmap_le/bssmap_le_test.ok > expout AT_CHECK([$abs_top_builddir/tests/bssmap_le/bssmap_le_test], [0], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([it_q]) +AT_KEYWORDS([it_q]) +cat $abs_srcdir/it_q/it_q_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/it_q/it_q_test], [0], [expout], [ignore]) +AT_CLEANUP |