diff options
author | Luís Marques <luismarques@lowrisc.org> | 2019-10-22 17:56:54 +0100 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2019-10-22 09:56:53 -0700 |
commit | 99d6d0a93f9c83b63343a00693d5085e3949fe1a (patch) | |
tree | 2be05e20bf3956c1578bd32055c6195117087b85 /pk | |
parent | 78e61baf432bd2d796c5b1e0498af363967322f4 (diff) | |
download | pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.zip pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.tar.gz pk-99d6d0a93f9c83b63343a00693d5085e3949fe1a.tar.bz2 |
Make performance counters always 64 bits wide (#178)
This prevents the counters from easily overflowing for a 32-bit pk.
Diffstat (limited to 'pk')
-rw-r--r-- | pk/boot.h | 6 | ||||
-rw-r--r-- | pk/pk.c | 6 | ||||
-rw-r--r-- | pk/pk.h | 58 | ||||
-rw-r--r-- | pk/syscall.c | 25 |
4 files changed, 77 insertions, 18 deletions
@@ -20,9 +20,9 @@ typedef struct { size_t brk_max; size_t mmap_max; size_t stack_top; - size_t time0; - size_t cycle0; - size_t instret0; + uint64_t time0; + uint64_t cycle0; + uint64_t instret0; } elf_info; extern elf_info current; @@ -132,9 +132,9 @@ static void run_loaded_program(size_t argc, char** argv, uintptr_t kstack_top) STACK_INIT(uintptr_t); if (current.cycle0) { // start timer if so requested - current.time0 = rdtime(); - current.cycle0 = rdcycle(); - current.instret0 = rdinstret(); + current.time0 = rdtime64(); + current.cycle0 = rdcycle64(); + current.instret0 = rdinstret64(); } trapframe_t tf; @@ -41,6 +41,64 @@ static inline int insn_len(long insn) return (insn & 0x3) < 0x3 ? 2 : 4; } +#if __riscv_xlen == 32 + +static inline uint64_t rdtime64() +{ + uint32_t time; + uint32_t timeh1; + uint32_t timeh2; + + do + { + timeh1 = read_csr(timeh); + time = read_csr(time); + timeh2 = read_csr(timeh); + } while(timeh1 != timeh2); + + return (((uint64_t) timeh1) << 32) | time; +} + +static inline uint64_t rdcycle64() +{ + uint32_t cycle; + uint32_t cycleh1; + uint32_t cycleh2; + + do + { + cycleh1 = read_csr(cycleh); + cycle = read_csr(cycle); + cycleh2 = read_csr(cycleh); + } while(cycleh1 != cycleh2); + + return (((uint64_t) cycleh1) << 32) | cycle; +} + +static inline uint64_t rdinstret64() +{ + uint32_t instret; + uint32_t instreth1; + uint32_t instreth2; + + do + { + instreth1 = read_csr(instreth); + instret = read_csr(instret); + instreth2 = read_csr(instreth); + } while(instreth1 != instreth2); + + return (((uint64_t) instreth1) << 32) | instret; +} + +#else + +#define rdtime64 rdtime +#define rdcycle64 rdcycle +#define rdinstret64 rdinstret + +#endif + #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) #ifdef __cplusplus diff --git a/pk/syscall.c b/pk/syscall.c index 8903ecc..07fa41d 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -16,14 +16,15 @@ typedef long (*syscall_t)(long, long, long, long, long, long, long); void sys_exit(int code) { if (current.cycle0) { - size_t dt = rdtime() - current.time0; - size_t dc = rdcycle() - current.cycle0; - size_t di = rdinstret() - current.instret0; - - printk("%ld ticks\n", dt); - printk("%ld cycles\n", dc); - printk("%ld instructions\n", di); - printk("%d.%d%d CPI\n", dc/di, 10ULL*dc/di % 10, (100ULL*dc + di/2)/di % 10); + uint64_t dt = rdtime64() - current.time0; + uint64_t dc = rdcycle64() - current.cycle0; + uint64_t di = rdinstret64() - current.instret0; + + printk("%lld ticks\n", dt); + printk("%lld cycles\n", dc); + printk("%lld instructions\n", di); + printk("%d.%d%d CPI\n", (int)(dc/di), (int)(10ULL*dc/di % 10), + (int)((100ULL*dc + di/2)/di % 10)); } shutdown(code); } @@ -353,7 +354,7 @@ int sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz) long sys_time(long* loc) { - uintptr_t t = rdcycle() / CLOCK_FREQ; + uint64_t t = rdcycle64() / CLOCK_FREQ; if (loc) *loc = t; return t; @@ -361,7 +362,7 @@ long sys_time(long* loc) int sys_times(long* loc) { - uintptr_t t = rdcycle(); + uint64_t t = rdcycle64(); kassert(CLOCK_FREQ % 1000000 == 0); loc[0] = t / (CLOCK_FREQ / 1000000); loc[1] = 0; @@ -373,7 +374,7 @@ int sys_times(long* loc) int sys_gettimeofday(long* loc) { - uintptr_t t = rdcycle(); + uint64_t t = rdcycle64(); loc[0] = t / CLOCK_FREQ; loc[1] = (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000); @@ -382,7 +383,7 @@ int sys_gettimeofday(long* loc) long sys_clock_gettime(int clk_id, long *loc) { - uintptr_t t = rdcycle(); + uint64_t t = rdcycle64(); loc[0] = t / CLOCK_FREQ; loc[1] = (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000000); |