Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

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