| [8e5e945] | 1 | #include <clock.hfa>
 | 
|---|
| [c0f881b] | 2 | #include <fstream.hfa>
 | 
|---|
| [096a2ff] | 3 | #include <kernel.hfa>
 | 
|---|
| [73abe95] | 4 | #include <thread.hfa>
 | 
|---|
 | 5 | #include <time.hfa>
 | 
|---|
| [11dbfe1] | 6 | 
 | 
|---|
| [dc8511c] | 7 | #include "long_tests.hfa"
 | 
|---|
| [7bdcac1] | 8 | 
 | 
|---|
| [11dbfe1] | 9 | #ifndef PREEMPTION_RATE
 | 
|---|
| [8ad6533] | 10 | #define PREEMPTION_RATE 10`ms
 | 
|---|
| [11dbfe1] | 11 | #endif
 | 
|---|
 | 12 | 
 | 
|---|
| [8ad6533] | 13 | Duration default_preemption() {
 | 
|---|
| [11dbfe1] | 14 |         return PREEMPTION_RATE;
 | 
|---|
 | 15 | }
 | 
|---|
 | 16 | 
 | 
|---|
| [7bdcac1] | 17 | #ifdef TEST_LONG
 | 
|---|
| [b2fe1c9] | 18 | static const unsigned long N = 30_000ul;
 | 
|---|
 | 19 | #else
 | 
|---|
 | 20 | static const unsigned long N = 500ul;
 | 
|---|
 | 21 | #endif
 | 
|---|
 | 22 | 
 | 
|---|
| [b68fc85] | 23 | extern void __cfaabi_check_preemption();
 | 
|---|
 | 24 | 
 | 
|---|
| [7b2c8c3c] | 25 | static struct {
 | 
|---|
 | 26 |         volatile int counter;
 | 
|---|
 | 27 |         volatile Time prev;
 | 
|---|
 | 28 |         Duration durations[6];
 | 
|---|
 | 29 | } globals;
 | 
|---|
| [11dbfe1] | 30 | 
 | 
|---|
| [0322865c] | 31 | thread worker_t {
 | 
|---|
| [11dbfe1] | 32 |         int value;
 | 
|---|
| [8e5e945] | 33 |         unsigned long long spin;
 | 
|---|
| [11dbfe1] | 34 | };
 | 
|---|
 | 35 | 
 | 
|---|
| [2afec66] | 36 | void ?{}( worker_t & this, int value ) {
 | 
|---|
 | 37 |         this.value = value;
 | 
|---|
| [1612315] | 38 |         this.spin = 0;
 | 
|---|
| [11dbfe1] | 39 | }
 | 
|---|
 | 40 | 
 | 
|---|
| [83a071f9] | 41 | void main(worker_t & this) {
 | 
|---|
| [7b2c8c3c] | 42 |         while(TEST(globals.counter < N)) {
 | 
|---|
| [8e5e945] | 43 |                 if(this.spin > 50_000_000_000) abort | "Worker" | this.value | "has been spinning too long! (" | this.spin | ")";
 | 
|---|
| [b68fc85] | 44 |                 __cfaabi_check_preemption();
 | 
|---|
| [7b2c8c3c] | 45 |                 if( (globals.counter % 7) == this.value ) {
 | 
|---|
| [b68fc85] | 46 |                         __cfaabi_check_preemption();
 | 
|---|
| [8e5e945] | 47 |                         #if !defined(TEST_LONG)
 | 
|---|
 | 48 |                                 Time now = timeHiRes();
 | 
|---|
| [7b2c8c3c] | 49 |                                 Duration diff = now - globals.prev;
 | 
|---|
 | 50 |                                 globals.prev = now;
 | 
|---|
| [8e5e945] | 51 |                         #endif
 | 
|---|
| [7b2c8c3c] | 52 |                         int next = __atomic_add_fetch( &globals.counter, 1, __ATOMIC_SEQ_CST );
 | 
|---|
| [b68fc85] | 53 |                         __cfaabi_check_preemption();
 | 
|---|
| [8e5e945] | 54 |                         if( (next % 100) == 0 ) {
 | 
|---|
 | 55 |                                 #if !defined(TEST_LONG)
 | 
|---|
 | 56 |                                         unsigned idx = next / 100;
 | 
|---|
 | 57 |                                         if (idx >= 6) abort | "Idx from next is invalid: " | idx | "vs" | next;
 | 
|---|
| [7b2c8c3c] | 58 |                                         globals.durations[idx] = diff;
 | 
|---|
| [8e5e945] | 59 |                                         if(diff > 12`s) serr | "Duration suspiciously large:" | diff;
 | 
|---|
 | 60 |                                 #endif
 | 
|---|
 | 61 |                                 printf("%d\n", (int)next);
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 |                         }
 | 
|---|
| [b68fc85] | 64 |                         __cfaabi_check_preemption();
 | 
|---|
| [b200492] | 65 |                         this.spin = 0;
 | 
|---|
| [11dbfe1] | 66 |                 }
 | 
|---|
| [b68fc85] | 67 |                 __cfaabi_check_preemption();
 | 
|---|
| [7bdcac1] | 68 |                 KICK_WATCHDOG;
 | 
|---|
| [1612315] | 69 |                 this.spin++;
 | 
|---|
| [11dbfe1] | 70 |         }
 | 
|---|
 | 71 | }
 | 
|---|
 | 72 | 
 | 
|---|
 | 73 | int main(int argc, char* argv[]) {
 | 
|---|
 | 74 |         processor p;
 | 
|---|
| [7b2c8c3c] | 75 |         globals.counter = 0;
 | 
|---|
 | 76 |         globals.durations[0] = 0;
 | 
|---|
 | 77 |         globals.durations[1] = 0;
 | 
|---|
 | 78 |         globals.durations[2] = 0;
 | 
|---|
 | 79 |         globals.durations[3] = 0;
 | 
|---|
 | 80 |         globals.durations[4] = 0;
 | 
|---|
 | 81 |         globals.durations[5] = 0;
 | 
|---|
| [11dbfe1] | 82 |         {
 | 
|---|
| [7b2c8c3c] | 83 |                 globals.prev = timeHiRes();
 | 
|---|
| [0322865c] | 84 |                 worker_t w0 = 0;
 | 
|---|
 | 85 |                 worker_t w1 = 1;
 | 
|---|
 | 86 |                 worker_t w2 = 2;
 | 
|---|
 | 87 |                 worker_t w3 = 3;
 | 
|---|
 | 88 |                 worker_t w4 = 4;
 | 
|---|
 | 89 |                 worker_t w5 = 5;
 | 
|---|
 | 90 |                 worker_t w6 = 6;
 | 
|---|
| [11dbfe1] | 91 |         }
 | 
|---|
| [2afec66] | 92 | }
 | 
|---|