From 48036ace1952535318d510a5639114601d5f3eb9 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 16 Dec 2017 17:51:58 +0100 Subject: [PATCH] Add new test. --- m-prioqueue.h | 41 ++++++++++++++++++++ tests/test-mworker.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 tests/test-mworker.c diff --git a/m-prioqueue.h b/m-prioqueue.h index b3271713..e89447c7 100644 --- a/m-prioqueue.h +++ b/m-prioqueue.h @@ -207,4 +207,45 @@ } \ +#include "m-i-list.h" + +/* Based on Bucket queue */ +#define PRIOQUEUE_I_BUCKET_DEF(name, type, MAXPRIO, oplist, prioqueue_t) \ + typedef type M_C(name, _type_t); \ + \ + typedef struct M_C(name, _s) { \ + struct ilist_head_s list; \ + struct ilist_head_s prio[MAXPRIO]; \ + } prioqueue_t[1]; \ + \ + static void \ + M_C(name, _init)(prioqueue_t q) \ + { \ + q->list.next = &q->list; \ + q->list.prev = &q->list; \ + for(int i = 0; i < MAXPRIO; i++) { \ + q->prio[i].next = &q->list; \ + q->prio[i].prev = &q->list; \ + } \ + } \ + \ + static inline bool M_C(name, _i_empty_p)(struct ilist_head_s list) \ + { \ + return list->name.next == &list->name; \ + } \ + \ + static void \ + M_C(name, _push_front)(prioqueue_t q, type *obj) \ + { \ + unsigned int priority = M_GET_HASH oplist (*obj); \ + assert (priority < MAXPRIO); \ + struct ilist_head_s *list = q->prio[i]; \ + assert (obj != NULL); \ + struct ilist_head_s *next = list->name.next; \ + list->name.next = &obj->name; \ + obj->name.next = next; \ + obj->name.prev = &list->name; \ + next->prev = &obj->name; \ + } \ + #endif diff --git a/tests/test-mworker.c b/tests/test-mworker.c new file mode 100644 index 00000000..2d465c3a --- /dev/null +++ b/tests/test-mworker.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, Patrick Pelissier + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include "m-worker.h" + +/* Compute Fibonacci number using thread systems. */ +static worker_t w_g; +static int fib(int n); +struct fib2_s { + int x, n; +}; +static void subfunc_1 (void *data) { + struct fib2_s *f = data; + f->x = fib (f->n ); +} +static int fib(int n) +{ + if (n < 2) + return n; + + struct fib2_s f; + worker_block_t b; + + worker_start(b); + f.n = n - 2; + worker_spawn (w_g, b, subfunc_1, &f); + int y = fib (n-1); + worker_sync(b); + return f.x + y; +} + +static void test1(void) +{ + worker_init(w_g, 0, 0, NULL); + int result = fib(39); + assert (result == 63245986); + worker_clear(w_g); +} + +#if defined(__GNUC__) +static int fib2(int n) +{ + if (n < 2) + return n; + + worker_block_t b; + int y1, y2; + worker_start(b); + WORKER_SPAWN(w_g, b, (n), { y2 = fib2(n-2); }, (y2)); + y1 = fib (n-1); + worker_sync(b); + return y1 + y2; +} + +static void test2(void) +{ + worker_init(w_g, 0, 0, NULL); + int result = fib2(39); + assert (result == 63245986); + worker_clear(w_g); +} +#else +static void test2(void) {} +#endif + +int main(void) +{ + test1(); + test2(); +}