am,amtest,mpe: support atomic_add and barrier
This commit is contained in:
parent
bd46d7d472
commit
43cad0ab42
|
@ -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;");
|
||||||
}
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue