#include #include #include #include #include #include #include #define __kick_rate 150000ul #include "long_tests.hfa" #ifndef PREEMPTION_RATE #define PREEMPTION_RATE 10`ms #endif Duration default_preemption() { return PREEMPTION_RATE; } #ifdef TEST_LONG static const unsigned long N = 600_000ul; #else static const unsigned long N = 1_000ul; #endif #if !defined(TEST_FOREVER) static inline void print(const char * const text ) { write( STDERR_FILENO, text, strlen(text) ); } #else static inline void print(Printer & this, const char * const text ) {} #endif coroutine Coroutine {}; volatile bool done = false; Coroutine * volatile the_cor = 0p; void store(Coroutine & cor) { __atomic_store_n(&the_cor, &cor, __ATOMIC_SEQ_CST); } Coroutine * take(void) { Coroutine * val = 0p; Coroutine * ret = __atomic_exchange_n(&the_cor, val, __ATOMIC_SEQ_CST); assert(!ret || !the_cor); return ret; } void main(Coroutine& this) { suspend(); for(int i = 0; TEST(i < N); i++) { print("C - Suspending"); void publish() { print("C - Publishing"); assert(!the_cor); store( this ); } suspend_then(publish); assert(!the_cor); print("Coroutine 2"); KICK_WATCHDOG; yield(); } done = true; suspend(); } thread Thread {}; void main(Thread & this) { Coroutine * mine = 0p; while(!done) { yield(); mine = take(); if(!mine) continue; print("T - took"); resume(*mine); print("T - back"); } } int main(int argc, char* argv[]) { processor p[2]; Coroutine c; resume(c); // Prime the coroutine to avoid one of the threads being its starter the_cor = &c; { Thread t[2]; } }