am,amtest,mpe: support atomic_add and barrier

This commit is contained in:
wangkaifan 2022-04-22 21:04:15 +08:00
parent bd46d7d472
commit 43cad0ab42
3 changed files with 35 additions and 3 deletions

View File

@ -5,6 +5,7 @@ int __am_ncpu = 1; // One core by default
void _mpe_setncpu(char arg) { void _mpe_setncpu(char arg) {
__am_ncpu = arg ? atoi(&arg) : 1; __am_ncpu = arg ? atoi(&arg) : 1;
assert(0 < __am_ncpu && __am_ncpu <= MAX_CPU); assert(0 < __am_ncpu && __am_ncpu <= MAX_CPU);
return;
} }
void _mpe_wakeup(int cpu) { void _mpe_wakeup(int cpu) {
@ -47,5 +48,29 @@ intptr_t _atomic_xchg(volatile intptr_t *addr, intptr_t newval) {
} }
intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder) { intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder) {
return 0; intptr_t result;
asm volatile(
"amoadd.d %0, %1, (%2);"
: "=r"(result)
: "r"(adder), "r"(addr)
);
return result;
}
void barrier() {
static volatile intptr_t sense = 0;
static volatile intptr_t count = 0;
static __thread intptr_t threadsense;
asm volatile("fence;");
threadsense = !threadsense;
if (_atomic_add(&count, 1) == _ncpu()-1) {
count = 0;
sense = threadsense;
}
else while(sense != threadsense)
;
asm volatile("fence;");
} }

View File

@ -17,6 +17,7 @@ extern "C" {
void _mpe_setncpu(char arg); void _mpe_setncpu(char arg);
void _mpe_wakeup(int cpu); void _mpe_wakeup(int cpu);
intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder); intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder);
void barrier();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,7 +4,8 @@
* Two build mp test, try `make ARCH=riscv64-xs-dual mainargs='m2'` * Two build mp test, try `make ARCH=riscv64-xs-dual mainargs='m2'`
*/ */
static volatile intptr_t sum; static volatile intptr_t sum = 0;
static volatile intptr_t atomic_sum = 0;
static volatile intptr_t print_lock = 0; static volatile intptr_t print_lock = 0;
void __am_uartlite_putchar(char ch); void __am_uartlite_putchar(char ch);
@ -14,11 +15,16 @@ void mp_print() {
while (_atomic_xchg(&print_lock, 1) == 1); while (_atomic_xchg(&print_lock, 1) == 1);
printf("My CPU ID is %d, nrCPU is %d\n", _cpu(), _ncpu()); printf("My CPU ID is %d, nrCPU is %d\n", _cpu(), _ncpu());
_atomic_xchg(&print_lock, 0); _atomic_xchg(&print_lock, 0);
_atomic_add(&sum, 1); for (int i = 0; i < 100; i++) {
sum++;
_atomic_add(&atomic_sum, 1);
}
} }
void finalize() { void finalize() {
barrier();
while (_atomic_xchg(&print_lock, 1) == 1); while (_atomic_xchg(&print_lock, 1) == 1);
printf("sum = %d atomic_sum = %d\n", sum, atomic_sum);
printf("Finalize CPU ID: %d\n", _cpu()); printf("Finalize CPU ID: %d\n", _cpu());
_atomic_xchg(&print_lock, 0); _atomic_xchg(&print_lock, 0);
while(1); while(1);