// Concurrency test, program B of a pair (see gnoConcurA.c). B announces its // flag, spins waiting for A's, then does real work. Both markers set means the // two SEPARATE programs genuinely time-sliced under GNO's preemptive scheduler. // // 0x025042 0001 flagB: B is alive // 0x025046 BBBB B saw A's flag (rendezvous) AND sumTo(100)==5050; else DEAD #include #define M(a) (*(volatile uint16_t *)(a)) #define FLAG_A 0x025040UL #define FLAG_B 0x025042UL #define RES_B 0x025046UL #define LIMIT 100000000UL static uint16_t sumTo(uint16_t n) { uint16_t acc; uint16_t i; acc = 0; for (i = 1; i <= n; i++) { acc = acc + i; } return acc; } int main(void) { unsigned long spin; uint16_t saw; M(RES_B) = 0xDEAD; M(FLAG_B) = 0x0001; // announce B saw = 0; for (spin = 0; spin < LIMIT; spin++) { if (M(FLAG_A) == 0x0001) { saw = 1; break; } } if (saw == 1 && sumTo(100) == 5050) { M(RES_B) = 0xBBBB; // rendezvous + real work OK } M(0x02504AUL) = 0xE0BB; // B reached end (distinguishes timeout from crash) for (volatile unsigned long j = 0; j < 300000UL; j++) { } return 0; }