#include #include #include #include #include #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 = 30_000ul; #else static const unsigned long N = 500ul; static volatile Time prev; static Duration preempt_durations[6] = { 0 }; #endif extern void __cfaabi_check_preemption(); static volatile int counter = 0; thread worker_t { int value; unsigned long long spin; }; void ?{}( worker_t & this, int value ) { this.value = value; this.spin = 0; } void main(worker_t & this) { while(TEST(counter < N)) { if(this.spin > 50_000_000_000) abort | "Worker" | this.value | "has been spinning too long! (" | this.spin | ")"; __cfaabi_check_preemption(); if( (counter % 7) == this.value ) { __cfaabi_check_preemption(); #if !defined(TEST_LONG) Time now = timeHiRes(); Duration diff = now - prev; prev = now; #endif int next = __atomic_add_fetch( &counter, 1, __ATOMIC_SEQ_CST ); __cfaabi_check_preemption(); if( (next % 100) == 0 ) { #if !defined(TEST_LONG) unsigned idx = next / 100; if (idx >= 6) abort | "Idx from next is invalid: " | idx | "vs" | next; preempt_durations[idx] = diff; if(diff > 12`s) serr | "Duration suspiciously large:" | diff; #endif printf("%d\n", (int)next); } __cfaabi_check_preemption(); this.spin = 0; } __cfaabi_check_preemption(); KICK_WATCHDOG; this.spin++; } } int main(int argc, char* argv[]) { processor p; { prev = timeHiRes(); worker_t w0 = 0; worker_t w1 = 1; worker_t w2 = 2; worker_t w3 = 3; worker_t w4 = 4; worker_t w5 = 5; worker_t w6 = 6; } }