65816-llvm-mos/demos/gnoConcurB.c
2026-07-07 21:11:28 -05:00

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;
}