Skip to content

Commit ebb6f13

Browse files
committed
Updated the adaptation of the following locks under the RISCV architecture(lh_swap_mutex,lh_cas_rw_lock,lh_cas_lockref,lh_incdec_refcount), as well as the support of the entire test framework for the RISCV architecture
1 parent 1830928 commit ebb6f13

File tree

10 files changed

+439
-2
lines changed

10 files changed

+439
-2
lines changed

benchmarks/lockhammer/include/atomics.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ static inline unsigned long fetchadd64_acquire_release (unsigned long *ptr, unsi
129129
: [tmp] "=&r" (tmp), [old] "=&r" (old), [newval] "=&r" (newval), [ptr] "+Q" (*ptr)
130130
: [val] "r" (addend)
131131
: "memory");
132+
#elif defined(__riscv) && !defined(USE_BUILTIN)
133+
asm volatile("amoadd.d.aqrl %[old], %[val], %[ptr]"
134+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
135+
: [val] "r" (addend)
136+
: "memory");
132137
#else
133138
old = __atomic_fetch_add(ptr, addend, __ATOMIC_ACQ_REL);
134139
#endif
@@ -162,6 +167,11 @@ static inline unsigned long fetchadd64_acquire (unsigned long *ptr, unsigned lon
162167
: [tmp] "=&r" (tmp), [old] "=&r" (old), [newval] "=&r" (newval), [ptr] "+Q" (*ptr)
163168
: [val] "r" (addend)
164169
: "memory");
170+
#elif defined(__riscv) && !defined(USE_BUILTIN)
171+
asm volatile("amoadd.d.aq %[old], %[val], %[ptr]"
172+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
173+
: [val] "r" (addend)
174+
: "memory");
165175
#else
166176
old = __atomic_fetch_add(ptr, addend, __ATOMIC_ACQUIRE);
167177
#endif
@@ -196,6 +206,11 @@ static inline unsigned long fetchadd64_release (unsigned long *ptr, unsigned lon
196206
: [tmp] "=&r" (tmp), [old] "=&r" (old), [newval] "=&r" (newval), [ptr] "+Q" (*ptr)
197207
: [val] "r" (addend)
198208
: "memory");
209+
#elif defined(__riscv) && !defined(USE_BUILTIN)
210+
asm volatile("amoadd.d.rl %[old], %[val], %[ptr]"
211+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
212+
: [val] "r" (addend)
213+
: "memory");
199214
#else
200215
old = __atomic_fetch_add(ptr, addend, __ATOMIC_RELEASE);
201216
#endif
@@ -229,6 +244,11 @@ static inline unsigned long fetchadd64 (unsigned long *ptr, unsigned long addend
229244
: [tmp] "=&r" (tmp), [old] "=&r" (old), [newval] "=&r" (newval), [ptr] "+Q" (*ptr)
230245
: [val] "r" (addend)
231246
: "memory");
247+
#elif defined(__riscv) && !defined(USE_BUILTIN)
248+
asm volatile("amoadd.d %[old], %[val], %[ptr]"
249+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
250+
: [val] "r" (addend)
251+
: "memory");
232252
#else
233253
old = __atomic_fetch_add(ptr, addend, __ATOMIC_RELAXED);
234254
#endif
@@ -265,6 +285,12 @@ static inline unsigned long fetchsub64 (unsigned long *ptr, unsigned long addend
265285
: [tmp] "=&r" (tmp), [old] "=&r" (old), [newval] "=&r" (newval), [ptr] "+Q" (*ptr)
266286
: [val] "r" (addend)
267287
: "memory");
288+
#elif defined(__riscv) && !defined(USE_BUILTIN)
289+
addend = (unsigned long) (-(long) addend);
290+
asm volatile("amoadd.d %[old], %[val], %[ptr]"
291+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
292+
: [val] "r" (addend)
293+
: "memory");
268294
#else
269295
old = __atomic_fetch_sub(ptr, addend, __ATOMIC_RELAXED);
270296
#endif
@@ -296,6 +322,11 @@ static inline unsigned long swap64 (unsigned long *ptr, unsigned long val) {
296322
: [tmp] "=&r" (tmp), [old] "=&r" (old), [ptr] "+Q" (*ptr)
297323
: [val] "r" (val)
298324
: "memory");
325+
#elif defined(__riscv) && !defined(USE_BUILTIN)
326+
asm volatile("amoswap.d.aqrl %[old], %[val], %[ptr]"
327+
: [old] "=&r" (old), [ptr] "+A" (*(ptr))
328+
: [val] "r" (val)
329+
: "memory");
299330
#else
300331
old = __atomic_exchange_n(ptr, val, __ATOMIC_ACQ_REL);
301332
#endif
@@ -330,6 +361,22 @@ static inline unsigned long cas64 (unsigned long *ptr, unsigned long newval, uns
330361
: [tmp] "=&r" (tmp), [old] "=&r" (old), [ptr] "+Q" (*ptr)
331362
: [exp] "r" (expected), [val] "r" (newval)
332363
: "memory");
364+
#elif defined(__riscv) && !defined(USE_BUILTIN) && !defined(__riscv_zacas)
365+
unsigned long tmp;
366+
367+
asm volatile ( "1: lr.d %[old], %[ptr]\n"
368+
" bne %[old], %[exp], 2f\n"
369+
" sc.d %[tmp], %[val], %[ptr]\n"
370+
" bnez %[tmp], 1b\n"
371+
"2:"
372+
: [old] "=&r" (old), [tmp] "=&r" (tmp), [ptr] "+A" (*(ptr))
373+
: [exp] "r" (expected), [val] "r" (newval)
374+
: "memory");
375+
#elif defined(__riscv) && !defined(USE_BUILTIN) && defined(__riscv_zacas)
376+
asm volatile("amocas.d %[exp], %[val], %[ptr]"
377+
: [exp] "=&r" (old), [ptr] "+A" (*(ptr))
378+
: "r[exp]" (expected), [val] "r" (newval)
379+
: "memory");
333380
#else
334381
old = expected;
335382
__atomic_compare_exchange_n(ptr, &old, expected, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
@@ -365,6 +412,22 @@ static inline unsigned long cas64_acquire (unsigned long *ptr, unsigned long val
365412
: [tmp] "=&r" (tmp), [old] "=&r" (old), [ptr] "+Q" (*ptr)
366413
: [exp] "r" (exp), [val] "r" (val)
367414
: "memory");
415+
#elif defined(__riscv) && !defined(USE_BUILTIN) && !defined(__riscv_zacas)
416+
unsigned long tmp;
417+
418+
asm volatile ( "1: lr.d.aq %[old], %[ptr]\n"
419+
" bne %[old], %[exp], 2f\n"
420+
" sc.d %[tmp], %[newval], %[ptr]\n"
421+
" bnez %[tmp], 1b\n"
422+
"2:"
423+
: [old] "=&r" (old), [tmp] "=&r" (tmp), [ptr] "+A" (*(ptr))
424+
: [exp] "r" (exp), [newval] "r" (val)
425+
: "memory");
426+
#elif defined(__riscv) && !defined(USE_BUILTIN) && defined(__riscv_zacas)
427+
asm volatile("amocas.d %[exp], %[val], %[ptr]"
428+
: [exp] "=&r" (old), [ptr] "+A" (*(ptr))
429+
: "r[exp]" (exp), [val] "r" (val)
430+
: "memory");
368431
#else
369432
old = exp;
370433
__atomic_compare_exchange_n(ptr, &old, val, true, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
@@ -400,6 +463,22 @@ static inline unsigned long cas64_release (unsigned long *ptr, unsigned long val
400463
: [tmp] "=&r" (tmp), [old] "=&r" (old), [ptr] "+Q" (*ptr)
401464
: [exp] "r" (exp), [val] "r" (val)
402465
: "memory");
466+
#elif defined(__riscv) && !defined(USE_BUILTIN) && !defined(__riscv_zacas)
467+
unsigned long tmp;
468+
469+
asm volatile ( "1: lr.d %[old], %[ptr]\n"
470+
" bne %[old], %[exp], 2f\n"
471+
" sc.d.rl %[tmp], %[val], %[ptr]\n"
472+
" bnez %[tmp], 1b\n"
473+
"2:"
474+
: [old] "=&r" (old), [tmp] "=&r" (tmp), [ptr] "+A" (*(ptr))
475+
: [exp] "r" (exp), [val] "r" (val)
476+
: "memory");
477+
#elif defined(__riscv) && !defined(USE_BUILTIN) && defined(__riscv_zacas)
478+
asm volatile("amocas.d.rl %[exp], %[val], %[ptr]"
479+
: [exp] "=&r" (old), [ptr] "+A" (*(ptr))
480+
: "r[exp]" (exp), [val] "r" (val)
481+
: "memory");
403482
#else
404483
old = exp;
405484
__atomic_compare_exchange_n(ptr, &old, val, true, __ATOMIC_RELEASE, __ATOMIC_RELAXED); // XXX: is relaxed for failure OK?
@@ -435,6 +514,22 @@ static inline unsigned long cas64_acquire_release (unsigned long *ptr, unsigned
435514
: [tmp] "=&r" (tmp), [old] "=&r" (old), [ptr] "+Q" (*ptr)
436515
: [exp] "r" (exp), [val] "r" (val)
437516
: "memory");
517+
#elif defined(__riscv) && !defined(USE_BUILTIN) && !defined(__riscv_zacas)
518+
unsigned long tmp;
519+
520+
asm volatile ( "1: lr.d.aq %[old], %[ptr]\n"
521+
" bne %[old], %[exp], 2f\n"
522+
" sc.d.rl %[tmp], %[val], %[ptr]\n"
523+
" bnez %[tmp], 1b\n"
524+
"2:"
525+
: [old] "=&r" (old), [tmp] "=&r" (tmp), [ptr] "+A" (*(ptr))
526+
: [exp] "r" (exp), [val] "r" (val)
527+
: "memory");
528+
#elif defined(__riscv) && !defined(USE_BUILTIN) && defined(__riscv_zacas)
529+
asm volatile("amocas.d.aqrl %[exp], %[val], %[ptr]"
530+
: [exp] "=&r" (old), [ptr] "+A" (*(ptr))
531+
: "r[exp]" (exp), [val] "r" (val)
532+
: "memory");
438533
#else
439534
old = exp;
440535
__atomic_compare_exchange_n(ptr, &old, val, true, __ATOMIC_ACQ_REL,

benchmarks/lockhammer/include/cpu_relax.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,18 @@ static inline void __cpu_relax(void) {
6363
#endif
6464
#endif // __x86_64__
6565

66+
#ifdef __riscv
67+
#if defined(RELAX_IS_EMPTY)
68+
asm volatile ("" : : : "memory");
69+
#elif defined(RELAX_IS_NOP)
70+
asm volatile ("nop" : : : "memory");
71+
#elif defined(RELAX_IS_NOTHING)
72+
73+
#endif
74+
#endif // __riscv
75+
6676
}
6777
}
68-
6978
#endif // CPU_RELAX_H
7079

7180
/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */

benchmarks/lockhammer/include/perf_timer.h

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,32 @@ get_raw_counter(void) {
200200
#endif
201201

202202

203+
#ifdef __riscv
204+
static inline uint64_t __attribute__((always_inline))
205+
get_raw_counter(void) {
206+
uint64_t t;
207+
asm volatile(
208+
"fence.i\n"
209+
"fence r, r\n"
210+
"rdtime %0"
211+
: "=r"(t) : :);
212+
return t;
213+
}
214+
#endif
215+
203216
static inline void __attribute__((always_inline))
204217
timer_reset_counter()
205218
{
206219
#ifdef __aarch64__
207220
__asm__ __volatile__ ("isb; mrs %0, cntvct_el0" : "=r" (prev_tsc));
208221
#elif __x86_64__
209222
prev_tsc = rdtscp();
223+
#elif __riscv
224+
asm volatile(
225+
"fence.i\,"
226+
"fence r, r\n"
227+
"rdtime %0"
228+
: "=r"(prev_tsc) : :);
210229
#endif
211230
}
212231

@@ -221,7 +240,14 @@ timer_get_counter()
221240
__asm__ __volatile__ ("isb; mrs %0, cntvct_el0" : "=r" (counter_value));
222241
#elif __x86_64__
223242
uint64_t counter_value = rdtscp(); // assume constant_tsc
224-
#endif
243+
#elif __riscv
244+
uint64_t counter_value;
245+
asm volatile(
246+
"fence.i\n"
247+
"fence r, r\n"
248+
"rdtime %0"
249+
: "=r"(counter_value) : :);
250+
#endif
225251
return counter_value;
226252
}
227253

@@ -236,6 +262,14 @@ timer_get_counter_start()
236262
__asm__ __volatile__ ("dsb ish; isb; mrs %0, cntvct_el0" : "=r" (counter_value));
237263
#elif __x86_64__
238264
uint64_t counter_value = rdtscp_start(); // assume constant_tsc
265+
#elif __riscv
266+
uint64_t counter_value;
267+
asm volatile(
268+
"fence rw, rw\n"
269+
"fence.i\n"
270+
"fence r,r\n"
271+
"rdtime %0"
272+
: "=r"(counter_value) : :);
239273
#endif
240274
return counter_value;
241275
}
@@ -252,6 +286,15 @@ timer_get_counter_end()
252286
__asm__ __volatile__ ("isb; mrs %0, cntvct_el0; isb" : "=r" (counter_value));
253287
#elif __x86_64__
254288
uint64_t counter_value = rdtscp_end(); // assume constant_tsc
289+
#elif __riscv
290+
uint64_t counter_value;
291+
asm volatile(
292+
"fence.i\n"
293+
"fence r, r\n"
294+
"rdtime %0\n"
295+
"fence.i\n"
296+
"fence r, r"
297+
: "=r"(counter_value) : :);
255298
#endif
256299
return counter_value;
257300
}
@@ -286,6 +329,10 @@ timer_get_timer_freq(void)
286329

287330
const struct timeval measurement_duration = { .tv_sec = 0, .tv_usec = 100000 };
288331

332+
hwtimer_frequency = estimate_hwclock_freq(1, 0, measurement_duration);
333+
#elif __riscv
334+
const struct timeval measurement_duration = { .tv_sec = 0, .tv_usec = 100000 };
335+
289336
hwtimer_frequency = estimate_hwclock_freq(1, 0, measurement_duration);
290337
#else
291338
#error "ERROR: timer_get_timer_freq() is not implemented for this system!"

benchmarks/lockhammer/src/args.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ static size_t get_ctr_erg_bytes(void) {
129129
return ERG_words * 4;
130130
#elif defined(__x86_64__)
131131
return 64;
132+
#elif defined(__riscv)
133+
return 64;
132134
#else
133135
#error neither __aarch64__ nor __x86_64__ are defined in get_ctr_erg_bytes()
134136
#endif

benchmarks/lockhammer/src/measure.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ void NOINLINE blackhole(unsigned long iters) {
203203
#endif
204204
#elif __x86_64__
205205
asm volatile (".p2align 4; 1: add $-1, %0; jne 1b" : "+r" (iters) );
206+
#elif __riscv
207+
asm volatile (
208+
".p2align 4; 1: addi %0, %0, -1; bnez %0, 1b" :"+r" (iters) : "0" (iters));
206209
#endif
207210
}
208211

ext/jvm/jvm_objectmonitor.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ inline static void OrderAccess_fence(void) {
278278
}
279279
#endif
280280

281+
#ifdef __riscv
282+
inline static void OrderAccess_fence(void) {
283+
__asm__ volatile ("fence rw,rw" : : : "memory");
284+
}
285+
#endif
286+
281287
inline static void storeload(void) {
282288
OrderAccess_fence();
283289
}
@@ -301,6 +307,17 @@ inline static int int_xchg(int exchange_value, volatile int* dest) {
301307
FULL_MEM_BARRIER;
302308
return res;
303309
}
310+
#elif defined(__riscv)
311+
inline static int int_xchg(int exchange_value, volatile int* dest) {
312+
int result;
313+
__asm__ __volatile__ (
314+
"amoswap.w.aqrl %0, %1, (%2)"
315+
: "=r" (result)
316+
: "r" (exchange_value), "r" (dest)
317+
: "memory"
318+
);
319+
return result;
320+
}
304321
#endif
305322

306323
/*
@@ -636,6 +653,8 @@ static inline int SpinPause(void) {
636653
return 0;
637654
#elif __x86_64__
638655
return 1;
656+
#elif __riscv
657+
return 2;
639658
#else
640659
#error "unsupported instruction set architecture"
641660
#endif

0 commit comments

Comments
 (0)