Skip to content

Commit 060a492

Browse files
authored
Provider cycleclock() for 32bit ARM targets (#47358)
Based on https://github.com/google/benchmark/blob/main/src/cycleclock.h
1 parent ee54dd5 commit 060a492

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/julia_internal.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#else
2121
#define sleep(x) Sleep(1000*x)
2222
#endif
23+
#if defined(_CPU_ARM_)
24+
#include <sys/time.h>
25+
#endif
2326

2427
#ifdef __cplusplus
2528
extern "C" {
@@ -216,6 +219,26 @@ static inline uint64_t cycleclock(void) JL_NOTSAFEPOINT
216219
int64_t virtual_timer_value;
217220
__asm__ volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
218221
return virtual_timer_value;
222+
#elif defined(_CPU_ARM_)
223+
// V6 is the earliest arch that has a standard cyclecount
224+
#if (__ARM_ARCH >= 6)
225+
uint32_t pmccntr;
226+
uint32_t pmuseren;
227+
uint32_t pmcntenset;
228+
// Read the user mode perf monitor counter access permissions.
229+
asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren));
230+
if (pmuseren & 1) { // Allows reading perfmon counters for user mode code.
231+
asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset));
232+
if (pmcntenset & 0x80000000ul) { // Is it counting?
233+
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
234+
// The counter is set up to count every 64th cycle
235+
return (int64_t)(pmccntr) * 64; // Should optimize to << 6
236+
}
237+
}
238+
#endif
239+
struct timeval tv;
240+
gettimeofday(&tv, NULL);
241+
return (int64_t)(tv.tv_sec) * 1000000 + tv.tv_usec;
219242
#elif defined(_CPU_PPC64_)
220243
// This returns a time-base, which is not always precisely a cycle-count.
221244
// https://reviews.llvm.org/D78084

0 commit comments

Comments
 (0)