49 lines
1.3 KiB
C
49 lines
1.3 KiB
C
// 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 <stdint.h>
|
|
|
|
#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;
|
|
}
|