#include #include #include #include uintptr printtest(Coro *c, uintptr d) { printf("--> Recieved %lu\n", d); d = coro·yield(c, d+10); printf("--> Now %lu\n", d); return d; } uintptr sequence(Coro *c, uintptr start) { int d = start; for (;;) { coro·yield(c, d++); } return d; } struct PrimeMsg { Coro *seq; int p; }; uintptr filter(Coro *c, uintptr data) { int x, p; Coro *seq; struct PrimeMsg *msg; // Need to copy relevant variables onto the local stack // Data is volatile. msg = (struct PrimeMsg*)data; seq = msg->seq; p = msg->p; for (;;) { x = coro·yield(seq, x); if (x % p != 0) { x = coro·yield(c, x); } } return 0; } error test·coro() { int i; Coro *c[4]; uintptr d; printf("Starting singleton test\n"); for (i = 0; i < arrlen(c); i++) { c[i] = coro·make(0, &printtest); } /* Singleton test */ d = 0; for (i = 0; i < 10; i++) { d = coro·yield(c[0], d); } printf("Starting triplet test\n"); /* Triplet test */ for (i = 0; i < 10; i++) { d = coro·yield(c[1], d); d = coro·yield(c[2], d+100); d = coro·yield(c[3], d+200); } for (i = 0; i < arrlen(c); i++) { coro·free(c[i]); } /* Prime sieve */ printf("Starting prime test\n"); uintptr num; Coro *cur, *seq[50]; num = 2; seq[0] = coro·make(4096, &sequence); cur = *seq; num = coro·yield(cur, num); for (i = 1; i < arrlen(seq); i++) { seq[i] = coro·make(4096, &filter); struct PrimeMsg msg = { .seq = cur, .p = num, }; cur = seq[i]; num = coro·yield(cur, (uintptr)&msg); printf("--> prime number %lu\n", num); } return 0; } int less(void* a, void* b) { int ai, bi; ai = *(int*)a; bi = *(int*)b; return ai - bi; } error test·sort() { clock_t t; int i, test[10000]; for (i = 0; i < arrlen(test); i++) { test[i] = rand(); } t = clock(); sort·ints(arrlen(test), test); t = clock() - t; printf("inlined code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC); for (i = 0; i < arrlen(test); i++) { test[i] = rand(); } t = clock(); qsort(test, arrlen(test), sizeof(int), &less); t = clock() - t; printf("std qsort code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC); /* for (i = 1; i < arrlen(test); i++) { if (test[i] >= test[i-1]) { printf("%d is less that %d\n", test[i], test[i-1]); } else { printf("ERROR: %d is NOT less that %d\n", test[i], test[i-1]); } } */ return 0; } #define HASH(str) hash_string(str) #define EQUAL(str, str2) (str == str2) typedef struct Map { MAP_STRUCT_BODY(byte*, float) } Map; Map* makemap(mem·Allocator heap, void* h) { MAP_MAKE(Map); } void mapfree(Map *map) { MAP_FREE(map); } void mapreset(Map *map) { MAP_RESET(map); } double mapget(Map *map, byte *key) { MAP_GET(map, key, HASH, EQUAL); } static error mapresize(Map *map, int n) { MAP_GROW(map, byte*, float, n, HASH); } static int mapput(Map *map, byte *key, float val, error *err) { MAP_PUT(map, key, val, HASH, EQUAL, mapresize, err); } #undef HASH #undef EQUAL error main() { error err; #if 0 if (err = test·coro(), err) { errorf("test fail: coroutine"); } #endif if (err = test·sort(), err) { errorf("test fail: coroutine"); } }