#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 monitor Printer {}; #if !defined(TEST_FOREVER) static inline void print(Printer & mutex this, const char * const text ) { sout | text; } static inline void print(Printer & mutex this, const char * const text, int i ) { sout | text | i; } #else static inline void print(Printer & this, const char * const text ) {} static inline void print(Printer & this, const char * const text, int i ) {} #endif Printer printer; 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(printer, "Coroutine 1", i); void publish() { assert(!the_cor); store( this ); } suspend_then(publish); assert(!the_cor); print(printer, "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(printer, "Thread 1"); resume(*mine); print(printer, "Thread 2"); } } 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]; } }