#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; } #else static inline void print(Printer & this, const char * const text ) {} #endif Printer printer; coroutine Coroutine {}; volatile bool done = false; Coroutine * volatile the_cor = 0p; void store(Coroutine * volatile * target, Coroutine * value) { long long int val = value; volatile long long int * ptr = target; __atomic_store(ptr, &val, __ATOMIC_SEQ_CST); } Coroutine * exchange(Coroutine * volatile * target) { long long int ret; volatile long long int * ptr = target; long long int val = 0; ret = __atomic_exchange_n(ptr, &val, __ATOMIC_SEQ_CST); assert(ret == 0 || *ptr == 0); return (Coroutine *)ret; } void main(Coroutine& this) { for(int i = 0; TEST(i < N); i++) { print(printer, "Coroutine 1"); void publish() { assert(!the_cor); store( &the_cor, &this ); } suspend_then(publish); print(printer, "Coroutine 2"); KICK_WATCHDOG; yield(); } done = true; } thread Thread {}; void main(Thread & this) { Coroutine * mine = 0p; while(!done) { yield(); mine = exchange( &the_cor ); if(!mine) continue; print(printer, "Thread 1"); resume(*mine); print(printer, "Thread 2"); } } int main(int argc, char* argv[]) { processor p[2]; Coroutine c; the_cor = &c; { Thread t[2]; } }