|
20 | 20 | #else
|
21 | 21 | #define sleep(x) Sleep(1000*x)
|
22 | 22 | #endif
|
| 23 | +#if defined(_CPU_ARM_) |
| 24 | +#include <sys/time.h> |
| 25 | +#endif |
23 | 26 |
|
24 | 27 | #ifdef __cplusplus
|
25 | 28 | extern "C" {
|
@@ -216,6 +219,26 @@ static inline uint64_t cycleclock(void) JL_NOTSAFEPOINT
|
216 | 219 | int64_t virtual_timer_value;
|
217 | 220 | __asm__ volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
218 | 221 | 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; |
219 | 242 | #elif defined(_CPU_PPC64_)
|
220 | 243 | // This returns a time-base, which is not always precisely a cycle-count.
|
221 | 244 | // https://reviews.llvm.org/D78084
|
|
0 commit comments