Development mbed library for MAX32630FTHR

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*
switches 0:5c4d7b2438d3 2 * Testing framework for the events library
switches 0:5c4d7b2438d3 3 *
switches 0:5c4d7b2438d3 4 * Copyright (c) 2016 Christopher Haster
switches 0:5c4d7b2438d3 5 *
switches 0:5c4d7b2438d3 6 * Licensed under the Apache License, Version 2.0 (the "License");
switches 0:5c4d7b2438d3 7 * you may not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 8 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 9 *
switches 0:5c4d7b2438d3 10 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 11 *
switches 0:5c4d7b2438d3 12 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 13 * distributed under the License is distributed on an "AS IS" BASIS,
switches 0:5c4d7b2438d3 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 15 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 16 * limitations under the License.
switches 0:5c4d7b2438d3 17 */
switches 0:5c4d7b2438d3 18 #include "equeue.h"
switches 0:5c4d7b2438d3 19 #include <unistd.h>
switches 0:5c4d7b2438d3 20 #include <stdio.h>
switches 0:5c4d7b2438d3 21 #include <setjmp.h>
switches 0:5c4d7b2438d3 22 #include <stdint.h>
switches 0:5c4d7b2438d3 23 #include <stdlib.h>
switches 0:5c4d7b2438d3 24 #include <pthread.h>
switches 0:5c4d7b2438d3 25
switches 0:5c4d7b2438d3 26
switches 0:5c4d7b2438d3 27 // Testing setup
switches 0:5c4d7b2438d3 28 static jmp_buf test_buf;
switches 0:5c4d7b2438d3 29 static int test_line;
switches 0:5c4d7b2438d3 30 static int test_failure;
switches 0:5c4d7b2438d3 31
switches 0:5c4d7b2438d3 32 #define test_assert(test) ({ \
switches 0:5c4d7b2438d3 33 if (!(test)) { \
switches 0:5c4d7b2438d3 34 test_line = __LINE__; \
switches 0:5c4d7b2438d3 35 longjmp(test_buf, 1); \
switches 0:5c4d7b2438d3 36 } \
switches 0:5c4d7b2438d3 37 })
switches 0:5c4d7b2438d3 38
switches 0:5c4d7b2438d3 39 #define test_run(func, ...) ({ \
switches 0:5c4d7b2438d3 40 printf("%s: ...", #func); \
switches 0:5c4d7b2438d3 41 fflush(stdout); \
switches 0:5c4d7b2438d3 42 \
switches 0:5c4d7b2438d3 43 if (!setjmp(test_buf)) { \
switches 0:5c4d7b2438d3 44 func(__VA_ARGS__); \
switches 0:5c4d7b2438d3 45 printf("\r%s: \e[32mpassed\e[0m\n", #func); \
switches 0:5c4d7b2438d3 46 } else { \
switches 0:5c4d7b2438d3 47 printf("\r%s: \e[31mfailed\e[0m at line %d\n", #func, test_line); \
switches 0:5c4d7b2438d3 48 test_failure = true; \
switches 0:5c4d7b2438d3 49 } \
switches 0:5c4d7b2438d3 50 })
switches 0:5c4d7b2438d3 51
switches 0:5c4d7b2438d3 52
switches 0:5c4d7b2438d3 53 // Test functions
switches 0:5c4d7b2438d3 54 void pass_func(void *eh) {
switches 0:5c4d7b2438d3 55 }
switches 0:5c4d7b2438d3 56
switches 0:5c4d7b2438d3 57 void simple_func(void *p) {
switches 0:5c4d7b2438d3 58 (*(int *)p)++;
switches 0:5c4d7b2438d3 59 }
switches 0:5c4d7b2438d3 60
switches 0:5c4d7b2438d3 61 void sloth_func(void *p) {
switches 0:5c4d7b2438d3 62 usleep(10000);
switches 0:5c4d7b2438d3 63 (*(int *)p)++;
switches 0:5c4d7b2438d3 64 }
switches 0:5c4d7b2438d3 65
switches 0:5c4d7b2438d3 66 struct indirect {
switches 0:5c4d7b2438d3 67 int *touched;
switches 0:5c4d7b2438d3 68 uint8_t buffer[7];
switches 0:5c4d7b2438d3 69 };
switches 0:5c4d7b2438d3 70
switches 0:5c4d7b2438d3 71 void indirect_func(void *p) {
switches 0:5c4d7b2438d3 72 struct indirect *i = (struct indirect*)p;
switches 0:5c4d7b2438d3 73 (*i->touched)++;
switches 0:5c4d7b2438d3 74 }
switches 0:5c4d7b2438d3 75
switches 0:5c4d7b2438d3 76 struct timing {
switches 0:5c4d7b2438d3 77 unsigned tick;
switches 0:5c4d7b2438d3 78 unsigned delay;
switches 0:5c4d7b2438d3 79 };
switches 0:5c4d7b2438d3 80
switches 0:5c4d7b2438d3 81 void timing_func(void *p) {
switches 0:5c4d7b2438d3 82 struct timing *timing = (struct timing*)p;
switches 0:5c4d7b2438d3 83 unsigned tick = equeue_tick();
switches 0:5c4d7b2438d3 84
switches 0:5c4d7b2438d3 85 unsigned t1 = timing->delay;
switches 0:5c4d7b2438d3 86 unsigned t2 = tick - timing->tick;
switches 0:5c4d7b2438d3 87 test_assert(t1 > t2 - 10 && t1 < t2 + 10);
switches 0:5c4d7b2438d3 88
switches 0:5c4d7b2438d3 89 timing->tick = tick;
switches 0:5c4d7b2438d3 90 }
switches 0:5c4d7b2438d3 91
switches 0:5c4d7b2438d3 92 struct fragment {
switches 0:5c4d7b2438d3 93 equeue_t *q;
switches 0:5c4d7b2438d3 94 size_t size;
switches 0:5c4d7b2438d3 95 struct timing timing;
switches 0:5c4d7b2438d3 96 };
switches 0:5c4d7b2438d3 97
switches 0:5c4d7b2438d3 98 void fragment_func(void *p) {
switches 0:5c4d7b2438d3 99 struct fragment *fragment = (struct fragment*)p;
switches 0:5c4d7b2438d3 100 timing_func(&fragment->timing);
switches 0:5c4d7b2438d3 101
switches 0:5c4d7b2438d3 102 struct fragment *nfragment = equeue_alloc(fragment->q, fragment->size);
switches 0:5c4d7b2438d3 103 test_assert(nfragment);
switches 0:5c4d7b2438d3 104
switches 0:5c4d7b2438d3 105 *nfragment = *fragment;
switches 0:5c4d7b2438d3 106 equeue_event_delay(nfragment, fragment->timing.delay);
switches 0:5c4d7b2438d3 107
switches 0:5c4d7b2438d3 108 int id = equeue_post(nfragment->q, fragment_func, nfragment);
switches 0:5c4d7b2438d3 109 test_assert(id);
switches 0:5c4d7b2438d3 110 }
switches 0:5c4d7b2438d3 111
switches 0:5c4d7b2438d3 112 struct cancel {
switches 0:5c4d7b2438d3 113 equeue_t *q;
switches 0:5c4d7b2438d3 114 int id;
switches 0:5c4d7b2438d3 115 };
switches 0:5c4d7b2438d3 116
switches 0:5c4d7b2438d3 117 void cancel_func(void *p) {
switches 0:5c4d7b2438d3 118 struct cancel *cancel = (struct cancel *)p;
switches 0:5c4d7b2438d3 119 equeue_cancel(cancel->q, cancel->id);
switches 0:5c4d7b2438d3 120 }
switches 0:5c4d7b2438d3 121
switches 0:5c4d7b2438d3 122 struct nest {
switches 0:5c4d7b2438d3 123 equeue_t *q;
switches 0:5c4d7b2438d3 124 void (*cb)(void *);
switches 0:5c4d7b2438d3 125 void *data;
switches 0:5c4d7b2438d3 126 };
switches 0:5c4d7b2438d3 127
switches 0:5c4d7b2438d3 128 void nest_func(void *p) {
switches 0:5c4d7b2438d3 129 struct nest *nest = (struct nest *)p;
switches 0:5c4d7b2438d3 130 equeue_call(nest->q, nest->cb, nest->data);
switches 0:5c4d7b2438d3 131
switches 0:5c4d7b2438d3 132 usleep(10000);
switches 0:5c4d7b2438d3 133 }
switches 0:5c4d7b2438d3 134
switches 0:5c4d7b2438d3 135
switches 0:5c4d7b2438d3 136 // Simple call tests
switches 0:5c4d7b2438d3 137 void simple_call_test(void) {
switches 0:5c4d7b2438d3 138 equeue_t q;
switches 0:5c4d7b2438d3 139 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 140 test_assert(!err);
switches 0:5c4d7b2438d3 141
switches 0:5c4d7b2438d3 142 bool touched = false;
switches 0:5c4d7b2438d3 143 equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 144 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 145 test_assert(touched);
switches 0:5c4d7b2438d3 146
switches 0:5c4d7b2438d3 147 equeue_destroy(&q);
switches 0:5c4d7b2438d3 148 }
switches 0:5c4d7b2438d3 149
switches 0:5c4d7b2438d3 150 void simple_call_in_test(void) {
switches 0:5c4d7b2438d3 151 equeue_t q;
switches 0:5c4d7b2438d3 152 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 153 test_assert(!err);
switches 0:5c4d7b2438d3 154
switches 0:5c4d7b2438d3 155 bool touched = false;
switches 0:5c4d7b2438d3 156 int id = equeue_call_in(&q, 10, simple_func, &touched);
switches 0:5c4d7b2438d3 157 test_assert(id);
switches 0:5c4d7b2438d3 158
switches 0:5c4d7b2438d3 159 equeue_dispatch(&q, 15);
switches 0:5c4d7b2438d3 160 test_assert(touched);
switches 0:5c4d7b2438d3 161
switches 0:5c4d7b2438d3 162 equeue_destroy(&q);
switches 0:5c4d7b2438d3 163 }
switches 0:5c4d7b2438d3 164
switches 0:5c4d7b2438d3 165 void simple_call_every_test(void) {
switches 0:5c4d7b2438d3 166 equeue_t q;
switches 0:5c4d7b2438d3 167 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 168 test_assert(!err);
switches 0:5c4d7b2438d3 169
switches 0:5c4d7b2438d3 170 bool touched = false;
switches 0:5c4d7b2438d3 171 int id = equeue_call_every(&q, 10, simple_func, &touched);
switches 0:5c4d7b2438d3 172 test_assert(id);
switches 0:5c4d7b2438d3 173
switches 0:5c4d7b2438d3 174 equeue_dispatch(&q, 15);
switches 0:5c4d7b2438d3 175 test_assert(touched);
switches 0:5c4d7b2438d3 176
switches 0:5c4d7b2438d3 177 equeue_destroy(&q);
switches 0:5c4d7b2438d3 178 }
switches 0:5c4d7b2438d3 179
switches 0:5c4d7b2438d3 180 void simple_post_test(void) {
switches 0:5c4d7b2438d3 181 equeue_t q;
switches 0:5c4d7b2438d3 182 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 183 test_assert(!err);
switches 0:5c4d7b2438d3 184
switches 0:5c4d7b2438d3 185 int touched = false;
switches 0:5c4d7b2438d3 186 struct indirect *i = equeue_alloc(&q, sizeof(struct indirect));
switches 0:5c4d7b2438d3 187 test_assert(i);
switches 0:5c4d7b2438d3 188
switches 0:5c4d7b2438d3 189 i->touched = &touched;
switches 0:5c4d7b2438d3 190 int id = equeue_post(&q, indirect_func, i);
switches 0:5c4d7b2438d3 191 test_assert(id);
switches 0:5c4d7b2438d3 192
switches 0:5c4d7b2438d3 193 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 194 test_assert(*i->touched);
switches 0:5c4d7b2438d3 195
switches 0:5c4d7b2438d3 196 equeue_destroy(&q);
switches 0:5c4d7b2438d3 197 }
switches 0:5c4d7b2438d3 198
switches 0:5c4d7b2438d3 199 // Misc tests
switches 0:5c4d7b2438d3 200 void destructor_test(void) {
switches 0:5c4d7b2438d3 201 equeue_t q;
switches 0:5c4d7b2438d3 202 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 203 test_assert(!err);
switches 0:5c4d7b2438d3 204
switches 0:5c4d7b2438d3 205 int touched;
switches 0:5c4d7b2438d3 206 struct indirect *e;
switches 0:5c4d7b2438d3 207 int ids[3];
switches 0:5c4d7b2438d3 208
switches 0:5c4d7b2438d3 209 touched = 0;
switches 0:5c4d7b2438d3 210 for (int i = 0; i < 3; i++) {
switches 0:5c4d7b2438d3 211 e = equeue_alloc(&q, sizeof(struct indirect));
switches 0:5c4d7b2438d3 212 test_assert(e);
switches 0:5c4d7b2438d3 213
switches 0:5c4d7b2438d3 214 e->touched = &touched;
switches 0:5c4d7b2438d3 215 equeue_event_dtor(e, indirect_func);
switches 0:5c4d7b2438d3 216 int id = equeue_post(&q, pass_func, e);
switches 0:5c4d7b2438d3 217 test_assert(id);
switches 0:5c4d7b2438d3 218 }
switches 0:5c4d7b2438d3 219
switches 0:5c4d7b2438d3 220 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 221 test_assert(touched == 3);
switches 0:5c4d7b2438d3 222
switches 0:5c4d7b2438d3 223 touched = 0;
switches 0:5c4d7b2438d3 224 for (int i = 0; i < 3; i++) {
switches 0:5c4d7b2438d3 225 e = equeue_alloc(&q, sizeof(struct indirect));
switches 0:5c4d7b2438d3 226 test_assert(e);
switches 0:5c4d7b2438d3 227
switches 0:5c4d7b2438d3 228 e->touched = &touched;
switches 0:5c4d7b2438d3 229 equeue_event_dtor(e, indirect_func);
switches 0:5c4d7b2438d3 230 ids[i] = equeue_post(&q, pass_func, e);
switches 0:5c4d7b2438d3 231 test_assert(ids[i]);
switches 0:5c4d7b2438d3 232 }
switches 0:5c4d7b2438d3 233
switches 0:5c4d7b2438d3 234 for (int i = 0; i < 3; i++) {
switches 0:5c4d7b2438d3 235 equeue_cancel(&q, ids[i]);
switches 0:5c4d7b2438d3 236 }
switches 0:5c4d7b2438d3 237
switches 0:5c4d7b2438d3 238 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 239 test_assert(touched == 3);
switches 0:5c4d7b2438d3 240
switches 0:5c4d7b2438d3 241 touched = 0;
switches 0:5c4d7b2438d3 242 for (int i = 0; i < 3; i++) {
switches 0:5c4d7b2438d3 243 e = equeue_alloc(&q, sizeof(struct indirect));
switches 0:5c4d7b2438d3 244 test_assert(e);
switches 0:5c4d7b2438d3 245
switches 0:5c4d7b2438d3 246 e->touched = &touched;
switches 0:5c4d7b2438d3 247 equeue_event_dtor(e, indirect_func);
switches 0:5c4d7b2438d3 248 int id = equeue_post(&q, pass_func, e);
switches 0:5c4d7b2438d3 249 test_assert(id);
switches 0:5c4d7b2438d3 250 }
switches 0:5c4d7b2438d3 251
switches 0:5c4d7b2438d3 252 equeue_destroy(&q);
switches 0:5c4d7b2438d3 253 test_assert(touched == 3);
switches 0:5c4d7b2438d3 254 }
switches 0:5c4d7b2438d3 255
switches 0:5c4d7b2438d3 256 void allocation_failure_test(void) {
switches 0:5c4d7b2438d3 257 equeue_t q;
switches 0:5c4d7b2438d3 258 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 259 test_assert(!err);
switches 0:5c4d7b2438d3 260
switches 0:5c4d7b2438d3 261 void *p = equeue_alloc(&q, 4096);
switches 0:5c4d7b2438d3 262 test_assert(!p);
switches 0:5c4d7b2438d3 263
switches 0:5c4d7b2438d3 264 for (int i = 0; i < 100; i++) {
switches 0:5c4d7b2438d3 265 p = equeue_alloc(&q, 0);
switches 0:5c4d7b2438d3 266 }
switches 0:5c4d7b2438d3 267 test_assert(!p);
switches 0:5c4d7b2438d3 268
switches 0:5c4d7b2438d3 269 equeue_destroy(&q);
switches 0:5c4d7b2438d3 270 }
switches 0:5c4d7b2438d3 271
switches 0:5c4d7b2438d3 272 void cancel_test(int N) {
switches 0:5c4d7b2438d3 273 equeue_t q;
switches 0:5c4d7b2438d3 274 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 275 test_assert(!err);
switches 0:5c4d7b2438d3 276
switches 0:5c4d7b2438d3 277 bool touched = false;
switches 0:5c4d7b2438d3 278 int *ids = malloc(N*sizeof(int));
switches 0:5c4d7b2438d3 279
switches 0:5c4d7b2438d3 280 for (int i = 0; i < N; i++) {
switches 0:5c4d7b2438d3 281 ids[i] = equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 282 }
switches 0:5c4d7b2438d3 283
switches 0:5c4d7b2438d3 284 for (int i = N-1; i >= 0; i--) {
switches 0:5c4d7b2438d3 285 equeue_cancel(&q, ids[i]);
switches 0:5c4d7b2438d3 286 }
switches 0:5c4d7b2438d3 287
switches 0:5c4d7b2438d3 288 free(ids);
switches 0:5c4d7b2438d3 289
switches 0:5c4d7b2438d3 290 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 291 test_assert(!touched);
switches 0:5c4d7b2438d3 292
switches 0:5c4d7b2438d3 293 equeue_destroy(&q);
switches 0:5c4d7b2438d3 294 }
switches 0:5c4d7b2438d3 295
switches 0:5c4d7b2438d3 296 void cancel_inflight_test(void) {
switches 0:5c4d7b2438d3 297 equeue_t q;
switches 0:5c4d7b2438d3 298 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 299 test_assert(!err);
switches 0:5c4d7b2438d3 300
switches 0:5c4d7b2438d3 301 bool touched = false;
switches 0:5c4d7b2438d3 302
switches 0:5c4d7b2438d3 303 int id = equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 304 equeue_cancel(&q, id);
switches 0:5c4d7b2438d3 305
switches 0:5c4d7b2438d3 306 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 307 test_assert(!touched);
switches 0:5c4d7b2438d3 308
switches 0:5c4d7b2438d3 309 id = equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 310 equeue_cancel(&q, id);
switches 0:5c4d7b2438d3 311
switches 0:5c4d7b2438d3 312 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 313 test_assert(!touched);
switches 0:5c4d7b2438d3 314
switches 0:5c4d7b2438d3 315 struct cancel *cancel = equeue_alloc(&q, sizeof(struct cancel));
switches 0:5c4d7b2438d3 316 test_assert(cancel);
switches 0:5c4d7b2438d3 317 cancel->q = &q;
switches 0:5c4d7b2438d3 318 cancel->id = 0;
switches 0:5c4d7b2438d3 319
switches 0:5c4d7b2438d3 320 id = equeue_post(&q, cancel_func, cancel);
switches 0:5c4d7b2438d3 321 test_assert(id);
switches 0:5c4d7b2438d3 322
switches 0:5c4d7b2438d3 323 cancel->id = equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 324
switches 0:5c4d7b2438d3 325 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 326 test_assert(!touched);
switches 0:5c4d7b2438d3 327
switches 0:5c4d7b2438d3 328 equeue_destroy(&q);
switches 0:5c4d7b2438d3 329 }
switches 0:5c4d7b2438d3 330
switches 0:5c4d7b2438d3 331 void cancel_unnecessarily_test(void) {
switches 0:5c4d7b2438d3 332 equeue_t q;
switches 0:5c4d7b2438d3 333 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 334 test_assert(!err);
switches 0:5c4d7b2438d3 335
switches 0:5c4d7b2438d3 336 int id = equeue_call(&q, pass_func, 0);
switches 0:5c4d7b2438d3 337 for (int i = 0; i < 5; i++) {
switches 0:5c4d7b2438d3 338 equeue_cancel(&q, id);
switches 0:5c4d7b2438d3 339 }
switches 0:5c4d7b2438d3 340
switches 0:5c4d7b2438d3 341 id = equeue_call(&q, pass_func, 0);
switches 0:5c4d7b2438d3 342 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 343 for (int i = 0; i < 5; i++) {
switches 0:5c4d7b2438d3 344 equeue_cancel(&q, id);
switches 0:5c4d7b2438d3 345 }
switches 0:5c4d7b2438d3 346
switches 0:5c4d7b2438d3 347 bool touched = false;
switches 0:5c4d7b2438d3 348 equeue_call(&q, simple_func, &touched);
switches 0:5c4d7b2438d3 349 for (int i = 0; i < 5; i++) {
switches 0:5c4d7b2438d3 350 equeue_cancel(&q, id);
switches 0:5c4d7b2438d3 351 }
switches 0:5c4d7b2438d3 352
switches 0:5c4d7b2438d3 353 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 354 test_assert(touched);
switches 0:5c4d7b2438d3 355
switches 0:5c4d7b2438d3 356 equeue_destroy(&q);
switches 0:5c4d7b2438d3 357 }
switches 0:5c4d7b2438d3 358
switches 0:5c4d7b2438d3 359 void loop_protect_test(void) {
switches 0:5c4d7b2438d3 360 equeue_t q;
switches 0:5c4d7b2438d3 361 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 362 test_assert(!err);
switches 0:5c4d7b2438d3 363
switches 0:5c4d7b2438d3 364 bool touched = false;
switches 0:5c4d7b2438d3 365 equeue_call_every(&q, 0, simple_func, &touched);
switches 0:5c4d7b2438d3 366
switches 0:5c4d7b2438d3 367 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 368 test_assert(touched);
switches 0:5c4d7b2438d3 369
switches 0:5c4d7b2438d3 370 touched = false;
switches 0:5c4d7b2438d3 371 equeue_call_every(&q, 1, simple_func, &touched);
switches 0:5c4d7b2438d3 372
switches 0:5c4d7b2438d3 373 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 374 test_assert(touched);
switches 0:5c4d7b2438d3 375
switches 0:5c4d7b2438d3 376 equeue_destroy(&q);
switches 0:5c4d7b2438d3 377 }
switches 0:5c4d7b2438d3 378
switches 0:5c4d7b2438d3 379 void break_test(void) {
switches 0:5c4d7b2438d3 380 equeue_t q;
switches 0:5c4d7b2438d3 381 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 382 test_assert(!err);
switches 0:5c4d7b2438d3 383
switches 0:5c4d7b2438d3 384 bool touched = false;
switches 0:5c4d7b2438d3 385 equeue_call_every(&q, 0, simple_func, &touched);
switches 0:5c4d7b2438d3 386
switches 0:5c4d7b2438d3 387 equeue_break(&q);
switches 0:5c4d7b2438d3 388 equeue_dispatch(&q, -1);
switches 0:5c4d7b2438d3 389 test_assert(touched);
switches 0:5c4d7b2438d3 390
switches 0:5c4d7b2438d3 391 equeue_destroy(&q);
switches 0:5c4d7b2438d3 392 }
switches 0:5c4d7b2438d3 393
switches 0:5c4d7b2438d3 394 void period_test(void) {
switches 0:5c4d7b2438d3 395 equeue_t q;
switches 0:5c4d7b2438d3 396 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 397 test_assert(!err);
switches 0:5c4d7b2438d3 398
switches 0:5c4d7b2438d3 399 int count = 0;
switches 0:5c4d7b2438d3 400 equeue_call_every(&q, 10, simple_func, &count);
switches 0:5c4d7b2438d3 401
switches 0:5c4d7b2438d3 402 equeue_dispatch(&q, 55);
switches 0:5c4d7b2438d3 403 test_assert(count == 5);
switches 0:5c4d7b2438d3 404
switches 0:5c4d7b2438d3 405 equeue_destroy(&q);
switches 0:5c4d7b2438d3 406 }
switches 0:5c4d7b2438d3 407
switches 0:5c4d7b2438d3 408 void nested_test(void) {
switches 0:5c4d7b2438d3 409 equeue_t q;
switches 0:5c4d7b2438d3 410 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 411 test_assert(!err);
switches 0:5c4d7b2438d3 412
switches 0:5c4d7b2438d3 413 int touched = 0;
switches 0:5c4d7b2438d3 414 struct nest *nest = equeue_alloc(&q, sizeof(struct nest));
switches 0:5c4d7b2438d3 415 test_assert(nest);
switches 0:5c4d7b2438d3 416 nest->q = &q;
switches 0:5c4d7b2438d3 417 nest->cb = simple_func;
switches 0:5c4d7b2438d3 418 nest->data = &touched;
switches 0:5c4d7b2438d3 419
switches 0:5c4d7b2438d3 420 int id = equeue_post(&q, nest_func, nest);
switches 0:5c4d7b2438d3 421 test_assert(id);
switches 0:5c4d7b2438d3 422
switches 0:5c4d7b2438d3 423 equeue_dispatch(&q, 5);
switches 0:5c4d7b2438d3 424 test_assert(touched == 0);
switches 0:5c4d7b2438d3 425
switches 0:5c4d7b2438d3 426 equeue_dispatch(&q, 5);
switches 0:5c4d7b2438d3 427 test_assert(touched == 1);
switches 0:5c4d7b2438d3 428
switches 0:5c4d7b2438d3 429 touched = 0;
switches 0:5c4d7b2438d3 430 nest = equeue_alloc(&q, sizeof(struct nest));
switches 0:5c4d7b2438d3 431 test_assert(nest);
switches 0:5c4d7b2438d3 432 nest->q = &q;
switches 0:5c4d7b2438d3 433 nest->cb = simple_func;
switches 0:5c4d7b2438d3 434 nest->data = &touched;
switches 0:5c4d7b2438d3 435
switches 0:5c4d7b2438d3 436 id = equeue_post(&q, nest_func, nest);
switches 0:5c4d7b2438d3 437 test_assert(id);
switches 0:5c4d7b2438d3 438
switches 0:5c4d7b2438d3 439 equeue_dispatch(&q, 20);
switches 0:5c4d7b2438d3 440 test_assert(touched == 1);
switches 0:5c4d7b2438d3 441
switches 0:5c4d7b2438d3 442 equeue_destroy(&q);
switches 0:5c4d7b2438d3 443 }
switches 0:5c4d7b2438d3 444
switches 0:5c4d7b2438d3 445 void sloth_test(void) {
switches 0:5c4d7b2438d3 446 equeue_t q;
switches 0:5c4d7b2438d3 447 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 448 test_assert(!err);
switches 0:5c4d7b2438d3 449
switches 0:5c4d7b2438d3 450 int touched = 0;
switches 0:5c4d7b2438d3 451 int id = equeue_call(&q, sloth_func, &touched);
switches 0:5c4d7b2438d3 452 test_assert(id);
switches 0:5c4d7b2438d3 453
switches 0:5c4d7b2438d3 454 id = equeue_call_in(&q, 5, simple_func, &touched);
switches 0:5c4d7b2438d3 455 test_assert(id);
switches 0:5c4d7b2438d3 456
switches 0:5c4d7b2438d3 457 id = equeue_call_in(&q, 15, simple_func, &touched);
switches 0:5c4d7b2438d3 458 test_assert(id);
switches 0:5c4d7b2438d3 459
switches 0:5c4d7b2438d3 460 equeue_dispatch(&q, 20);
switches 0:5c4d7b2438d3 461 test_assert(touched == 3);
switches 0:5c4d7b2438d3 462
switches 0:5c4d7b2438d3 463 equeue_destroy(&q);
switches 0:5c4d7b2438d3 464 }
switches 0:5c4d7b2438d3 465
switches 0:5c4d7b2438d3 466 void *multithread_thread(void *p) {
switches 0:5c4d7b2438d3 467 equeue_t *q = (equeue_t *)p;
switches 0:5c4d7b2438d3 468 equeue_dispatch(q, -1);
switches 0:5c4d7b2438d3 469 return 0;
switches 0:5c4d7b2438d3 470 }
switches 0:5c4d7b2438d3 471
switches 0:5c4d7b2438d3 472 void multithread_test(void) {
switches 0:5c4d7b2438d3 473 equeue_t q;
switches 0:5c4d7b2438d3 474 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 475 test_assert(!err);
switches 0:5c4d7b2438d3 476
switches 0:5c4d7b2438d3 477 int touched = 0;
switches 0:5c4d7b2438d3 478 equeue_call_every(&q, 1, simple_func, &touched);
switches 0:5c4d7b2438d3 479
switches 0:5c4d7b2438d3 480 pthread_t thread;
switches 0:5c4d7b2438d3 481 err = pthread_create(&thread, 0, multithread_thread, &q);
switches 0:5c4d7b2438d3 482 test_assert(!err);
switches 0:5c4d7b2438d3 483
switches 0:5c4d7b2438d3 484 usleep(10000);
switches 0:5c4d7b2438d3 485 equeue_break(&q);
switches 0:5c4d7b2438d3 486 err = pthread_join(thread, 0);
switches 0:5c4d7b2438d3 487 test_assert(!err);
switches 0:5c4d7b2438d3 488
switches 0:5c4d7b2438d3 489 test_assert(touched);
switches 0:5c4d7b2438d3 490
switches 0:5c4d7b2438d3 491 equeue_destroy(&q);
switches 0:5c4d7b2438d3 492 }
switches 0:5c4d7b2438d3 493
switches 0:5c4d7b2438d3 494 void background_func(void *p, int ms) {
switches 0:5c4d7b2438d3 495 *(unsigned *)p = ms;
switches 0:5c4d7b2438d3 496 }
switches 0:5c4d7b2438d3 497
switches 0:5c4d7b2438d3 498 void background_test(void) {
switches 0:5c4d7b2438d3 499 equeue_t q;
switches 0:5c4d7b2438d3 500 int err = equeue_create(&q, 2048);
switches 0:5c4d7b2438d3 501 test_assert(!err);
switches 0:5c4d7b2438d3 502
switches 0:5c4d7b2438d3 503 int id = equeue_call_in(&q, 20, pass_func, 0);
switches 0:5c4d7b2438d3 504 test_assert(id);
switches 0:5c4d7b2438d3 505
switches 0:5c4d7b2438d3 506 unsigned ms;
switches 0:5c4d7b2438d3 507 equeue_background(&q, background_func, &ms);
switches 0:5c4d7b2438d3 508 test_assert(ms == 20);
switches 0:5c4d7b2438d3 509
switches 0:5c4d7b2438d3 510 id = equeue_call_in(&q, 10, pass_func, 0);
switches 0:5c4d7b2438d3 511 test_assert(id);
switches 0:5c4d7b2438d3 512 test_assert(ms == 10);
switches 0:5c4d7b2438d3 513
switches 0:5c4d7b2438d3 514 id = equeue_call(&q, pass_func, 0);
switches 0:5c4d7b2438d3 515 test_assert(id);
switches 0:5c4d7b2438d3 516 test_assert(ms == 0);
switches 0:5c4d7b2438d3 517
switches 0:5c4d7b2438d3 518 equeue_dispatch(&q, 0);
switches 0:5c4d7b2438d3 519 test_assert(ms == 10);
switches 0:5c4d7b2438d3 520
switches 0:5c4d7b2438d3 521 equeue_destroy(&q);
switches 0:5c4d7b2438d3 522 test_assert(ms == -1);
switches 0:5c4d7b2438d3 523 }
switches 0:5c4d7b2438d3 524
switches 0:5c4d7b2438d3 525 void chain_test(void) {
switches 0:5c4d7b2438d3 526 equeue_t q1;
switches 0:5c4d7b2438d3 527 int err = equeue_create(&q1, 2048);
switches 0:5c4d7b2438d3 528 test_assert(!err);
switches 0:5c4d7b2438d3 529
switches 0:5c4d7b2438d3 530 equeue_t q2;
switches 0:5c4d7b2438d3 531 err = equeue_create(&q2, 2048);
switches 0:5c4d7b2438d3 532 test_assert(!err);
switches 0:5c4d7b2438d3 533
switches 0:5c4d7b2438d3 534 equeue_chain(&q2, &q1);
switches 0:5c4d7b2438d3 535
switches 0:5c4d7b2438d3 536 int touched = 0;
switches 0:5c4d7b2438d3 537
switches 0:5c4d7b2438d3 538 int id1 = equeue_call_in(&q1, 20, simple_func, &touched);
switches 0:5c4d7b2438d3 539 int id2 = equeue_call_in(&q2, 20, simple_func, &touched);
switches 0:5c4d7b2438d3 540 test_assert(id1 && id2);
switches 0:5c4d7b2438d3 541
switches 0:5c4d7b2438d3 542 id1 = equeue_call(&q1, simple_func, &touched);
switches 0:5c4d7b2438d3 543 id2 = equeue_call(&q2, simple_func, &touched);
switches 0:5c4d7b2438d3 544 test_assert(id1 && id2);
switches 0:5c4d7b2438d3 545
switches 0:5c4d7b2438d3 546 id1 = equeue_call_in(&q1, 5, simple_func, &touched);
switches 0:5c4d7b2438d3 547 id2 = equeue_call_in(&q2, 5, simple_func, &touched);
switches 0:5c4d7b2438d3 548 test_assert(id1 && id2);
switches 0:5c4d7b2438d3 549
switches 0:5c4d7b2438d3 550 equeue_cancel(&q1, id1);
switches 0:5c4d7b2438d3 551 equeue_cancel(&q2, id2);
switches 0:5c4d7b2438d3 552
switches 0:5c4d7b2438d3 553 id1 = equeue_call_in(&q1, 10, simple_func, &touched);
switches 0:5c4d7b2438d3 554 id2 = equeue_call_in(&q2, 10, simple_func, &touched);
switches 0:5c4d7b2438d3 555 test_assert(id1 && id2);
switches 0:5c4d7b2438d3 556
switches 0:5c4d7b2438d3 557 equeue_dispatch(&q1, 30);
switches 0:5c4d7b2438d3 558
switches 0:5c4d7b2438d3 559 test_assert(touched == 6);
switches 0:5c4d7b2438d3 560 }
switches 0:5c4d7b2438d3 561
switches 0:5c4d7b2438d3 562 // Barrage tests
switches 0:5c4d7b2438d3 563 void simple_barrage_test(int N) {
switches 0:5c4d7b2438d3 564 equeue_t q;
switches 0:5c4d7b2438d3 565 int err = equeue_create(&q, N*(EQUEUE_EVENT_SIZE+sizeof(struct timing)));
switches 0:5c4d7b2438d3 566 test_assert(!err);
switches 0:5c4d7b2438d3 567
switches 0:5c4d7b2438d3 568 for (int i = 0; i < N; i++) {
switches 0:5c4d7b2438d3 569 struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
switches 0:5c4d7b2438d3 570 test_assert(timing);
switches 0:5c4d7b2438d3 571
switches 0:5c4d7b2438d3 572 timing->tick = equeue_tick();
switches 0:5c4d7b2438d3 573 timing->delay = (i+1)*100;
switches 0:5c4d7b2438d3 574 equeue_event_delay(timing, timing->delay);
switches 0:5c4d7b2438d3 575 equeue_event_period(timing, timing->delay);
switches 0:5c4d7b2438d3 576
switches 0:5c4d7b2438d3 577 int id = equeue_post(&q, timing_func, timing);
switches 0:5c4d7b2438d3 578 test_assert(id);
switches 0:5c4d7b2438d3 579 }
switches 0:5c4d7b2438d3 580
switches 0:5c4d7b2438d3 581 equeue_dispatch(&q, N*100);
switches 0:5c4d7b2438d3 582
switches 0:5c4d7b2438d3 583 equeue_destroy(&q);
switches 0:5c4d7b2438d3 584 }
switches 0:5c4d7b2438d3 585
switches 0:5c4d7b2438d3 586 void fragmenting_barrage_test(int N) {
switches 0:5c4d7b2438d3 587 equeue_t q;
switches 0:5c4d7b2438d3 588 int err = equeue_create(&q,
switches 0:5c4d7b2438d3 589 2*N*(EQUEUE_EVENT_SIZE+sizeof(struct fragment)+N*sizeof(int)));
switches 0:5c4d7b2438d3 590 test_assert(!err);
switches 0:5c4d7b2438d3 591
switches 0:5c4d7b2438d3 592 for (int i = 0; i < N; i++) {
switches 0:5c4d7b2438d3 593 size_t size = sizeof(struct fragment) + i*sizeof(int);
switches 0:5c4d7b2438d3 594 struct fragment *fragment = equeue_alloc(&q, size);
switches 0:5c4d7b2438d3 595 test_assert(fragment);
switches 0:5c4d7b2438d3 596
switches 0:5c4d7b2438d3 597 fragment->q = &q;
switches 0:5c4d7b2438d3 598 fragment->size = size;
switches 0:5c4d7b2438d3 599 fragment->timing.tick = equeue_tick();
switches 0:5c4d7b2438d3 600 fragment->timing.delay = (i+1)*100;
switches 0:5c4d7b2438d3 601 equeue_event_delay(fragment, fragment->timing.delay);
switches 0:5c4d7b2438d3 602
switches 0:5c4d7b2438d3 603 int id = equeue_post(&q, fragment_func, fragment);
switches 0:5c4d7b2438d3 604 test_assert(id);
switches 0:5c4d7b2438d3 605 }
switches 0:5c4d7b2438d3 606
switches 0:5c4d7b2438d3 607 equeue_dispatch(&q, N*100);
switches 0:5c4d7b2438d3 608
switches 0:5c4d7b2438d3 609 equeue_destroy(&q);
switches 0:5c4d7b2438d3 610 }
switches 0:5c4d7b2438d3 611
switches 0:5c4d7b2438d3 612 struct ethread {
switches 0:5c4d7b2438d3 613 pthread_t thread;
switches 0:5c4d7b2438d3 614 equeue_t *q;
switches 0:5c4d7b2438d3 615 int ms;
switches 0:5c4d7b2438d3 616 };
switches 0:5c4d7b2438d3 617
switches 0:5c4d7b2438d3 618 static void *ethread_dispatch(void *p) {
switches 0:5c4d7b2438d3 619 struct ethread *t = (struct ethread*)p;
switches 0:5c4d7b2438d3 620 equeue_dispatch(t->q, t->ms);
switches 0:5c4d7b2438d3 621 return 0;
switches 0:5c4d7b2438d3 622 }
switches 0:5c4d7b2438d3 623
switches 0:5c4d7b2438d3 624 void multithreaded_barrage_test(int N) {
switches 0:5c4d7b2438d3 625 equeue_t q;
switches 0:5c4d7b2438d3 626 int err = equeue_create(&q, N*(EQUEUE_EVENT_SIZE+sizeof(struct timing)));
switches 0:5c4d7b2438d3 627 test_assert(!err);
switches 0:5c4d7b2438d3 628
switches 0:5c4d7b2438d3 629 struct ethread t;
switches 0:5c4d7b2438d3 630 t.q = &q;
switches 0:5c4d7b2438d3 631 t.ms = N*100;
switches 0:5c4d7b2438d3 632 err = pthread_create(&t.thread, 0, ethread_dispatch, &t);
switches 0:5c4d7b2438d3 633 test_assert(!err);
switches 0:5c4d7b2438d3 634
switches 0:5c4d7b2438d3 635 for (int i = 0; i < N; i++) {
switches 0:5c4d7b2438d3 636 struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
switches 0:5c4d7b2438d3 637 test_assert(timing);
switches 0:5c4d7b2438d3 638
switches 0:5c4d7b2438d3 639 timing->tick = equeue_tick();
switches 0:5c4d7b2438d3 640 timing->delay = (i+1)*100;
switches 0:5c4d7b2438d3 641 equeue_event_delay(timing, timing->delay);
switches 0:5c4d7b2438d3 642 equeue_event_period(timing, timing->delay);
switches 0:5c4d7b2438d3 643
switches 0:5c4d7b2438d3 644 int id = equeue_post(&q, timing_func, timing);
switches 0:5c4d7b2438d3 645 test_assert(id);
switches 0:5c4d7b2438d3 646 }
switches 0:5c4d7b2438d3 647
switches 0:5c4d7b2438d3 648 err = pthread_join(t.thread, 0);
switches 0:5c4d7b2438d3 649 test_assert(!err);
switches 0:5c4d7b2438d3 650
switches 0:5c4d7b2438d3 651 equeue_destroy(&q);
switches 0:5c4d7b2438d3 652 }
switches 0:5c4d7b2438d3 653
switches 0:5c4d7b2438d3 654
switches 0:5c4d7b2438d3 655 int main() {
switches 0:5c4d7b2438d3 656 printf("beginning tests...\n");
switches 0:5c4d7b2438d3 657
switches 0:5c4d7b2438d3 658 test_run(simple_call_test);
switches 0:5c4d7b2438d3 659 test_run(simple_call_in_test);
switches 0:5c4d7b2438d3 660 test_run(simple_call_every_test);
switches 0:5c4d7b2438d3 661 test_run(simple_post_test);
switches 0:5c4d7b2438d3 662 test_run(destructor_test);
switches 0:5c4d7b2438d3 663 test_run(allocation_failure_test);
switches 0:5c4d7b2438d3 664 test_run(cancel_test, 20);
switches 0:5c4d7b2438d3 665 test_run(cancel_inflight_test);
switches 0:5c4d7b2438d3 666 test_run(cancel_unnecessarily_test);
switches 0:5c4d7b2438d3 667 test_run(loop_protect_test);
switches 0:5c4d7b2438d3 668 test_run(break_test);
switches 0:5c4d7b2438d3 669 test_run(period_test);
switches 0:5c4d7b2438d3 670 test_run(nested_test);
switches 0:5c4d7b2438d3 671 test_run(sloth_test);
switches 0:5c4d7b2438d3 672 test_run(background_test);
switches 0:5c4d7b2438d3 673 test_run(chain_test);
switches 0:5c4d7b2438d3 674 test_run(multithread_test);
switches 0:5c4d7b2438d3 675 test_run(simple_barrage_test, 20);
switches 0:5c4d7b2438d3 676 test_run(fragmenting_barrage_test, 20);
switches 0:5c4d7b2438d3 677 test_run(multithreaded_barrage_test, 20);
switches 0:5c4d7b2438d3 678
switches 0:5c4d7b2438d3 679 printf("done!\n");
switches 0:5c4d7b2438d3 680 return test_failure;
switches 0:5c4d7b2438d3 681 }