Forgot to add this file.
[riscv-tests.git] / debug / programs / multicore.c
1 #include <stdint.h>
2
3 typedef struct {
4 int counter;
5 } atomic_t;
6
7 static inline int atomic_xchg(atomic_t *v, int n)
8 {
9 register int c;
10
11 __asm__ __volatile__ (
12 "amoswap.w.aqrl %0, %2, %1"
13 : "=r" (c), "+A" (v->counter)
14 : "r" (n));
15 return c;
16 }
17
18 #define csr_read(csr) \
19 ({ \
20 register unsigned long __v; \
21 __asm__ __volatile__ ("csrr %0, " #csr \
22 : "=r" (__v)); \
23 __v; \
24 })
25
26 static inline void mb(void)
27 {
28 __asm__ __volatile__ ("fence");
29 }
30
31 void get_lock(atomic_t *lock)
32 {
33 while (atomic_xchg(lock, 1) == 1)
34 ;
35 mb();
36 }
37
38 void put_lock(atomic_t *lock)
39 {
40 mb();
41 atomic_xchg(lock, 0);
42 }
43
44 static atomic_t buf_lock = { .counter = 0 };
45 static char buf[32];
46 static int buf_initialized;
47 static unsigned hart_count[2];
48
49 static const char case_bit = 'a' - 'A';
50 volatile int initialized;
51
52 int main()
53 {
54 uint32_t hartid = csr_read(mhartid);
55 hart_count[hartid] = 0;
56
57 while (1) {
58 get_lock(&buf_lock);
59 hart_count[hartid]++;
60
61 if (!buf_initialized) {
62 for (unsigned i = 0; i < sizeof(buf); i++) {
63 buf[i] = 'A' + (i % 26);
64 }
65 buf_initialized = 1;
66 }
67
68 char first = buf[0];
69 int offset = (first & ~0x20) - 'A';
70 for (unsigned i = 0; i < sizeof(buf); i++) {
71 while (buf[i] != (first - offset + ((offset + i) % 26)))
72 ;
73
74 if (hartid & 1)
75 buf[i] = 'A' + ((i + hartid + hart_count[hartid]) % 26);
76 else
77 buf[i] = 'a' + ((i + hartid + hart_count[hartid]) % 26);
78 }
79 put_lock(&buf_lock);
80 }
81 }