diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2013-12-13 16:38:43 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2013-12-13 16:38:43 -0800 |
commit | dc49b2b13a112af3ce5d81eed2129160f2f0d3a4 (patch) | |
tree | d175ffc7b9ca876e322e09d18e966df892396a1e /pk/syscall.c | |
parent | f62e692e72d1626977be0e92f766bdeed305d903 (diff) | |
download | pk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.zip pk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.tar.gz pk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.tar.bz2 |
Add times syscall
Diffstat (limited to 'pk/syscall.c')
-rw-r--r-- | pk/syscall.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/pk/syscall.c b/pk/syscall.c index a4785a6..044cc78 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -10,6 +10,17 @@ typedef sysret_t (*syscall_t)(long, long, long, long, long, long, long); +#define long_bytes (4 + 4*current.elf64) +#define get_long(base, i) ({ long res; \ + if (current.elf64) res = ((long*)base)[i]; \ + else res = ((int*)base)[i]; \ + res; }) +#define put_long(base, i, data) ({ long res; \ + if (current.elf64) ((long*)base)[i] = (data); \ + else ((int*)base)[i] = (data); }) + +#define CLOCK_FREQ 1000000000 + void sys_exit(int code) { if (current.t0) @@ -162,7 +173,7 @@ sysret_t sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz) { if (oact) { - size_t sz = current.elf64 ? 6*sizeof(uint64_t) : 8*sizeof(uint32_t); + size_t sz = long_bytes * 3; populate_mapping(oact, sz, PROT_WRITE); memset(oact, 0, sz); } @@ -170,37 +181,50 @@ sysret_t sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz) return (sysret_t){0, 0}; } -sysret_t sys_time(long* loc) +sysret_t sys_time(void* loc) { - uintptr_t t = rdcycle(), hz = 1000000000; + uintptr_t t = rdcycle(); if (loc) { - populate_mapping(loc, sizeof(long), PROT_WRITE); - loc[0] = t/hz; + populate_mapping(loc, long_bytes, PROT_WRITE); + put_long(loc, 0, t / CLOCK_FREQ); } return (sysret_t){t, 0}; } +sysret_t sys_times(void* restrict loc) +{ + populate_mapping(loc, 4*long_bytes, PROT_WRITE); + + uintptr_t t = rdcycle(); + kassert(CLOCK_FREQ % 1000000 == 0); + put_long(loc, 0, t / (CLOCK_FREQ / 1000000)); + put_long(loc, 1, 0); + put_long(loc, 2, 0); + put_long(loc, 3, 0); + + return (sysret_t){0, 0}; +} + sysret_t sys_gettimeofday(long* loc) { - populate_mapping(loc, 2*sizeof(long), PROT_WRITE); + populate_mapping(loc, 2*long_bytes, PROT_WRITE); - uintptr_t t = rdcycle(), hz = 1000000000; - loc[0] = t/hz; - loc[1] = (t % hz) / (hz / 1000000); + uintptr_t t = rdcycle(); + put_long(loc, 0, t/CLOCK_FREQ); + put_long(loc, 1, (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000)); return (sysret_t){0, 0}; } sysret_t sys_writev(int fd, const void* iov, int cnt) { - long get(int i) { return current.elf64 ? ((long*)iov)[i] : ((int*)iov)[i]; } - populate_mapping(iov, cnt*2*(current.elf64 ? 8 : 4), PROT_READ); + populate_mapping(iov, cnt*2*long_bytes, PROT_READ); ssize_t ret = 0; for (int i = 0; i < cnt; i++) { - sysret_t r = sys_write(fd, (void*)get(2*i), get(2*i+1)); + sysret_t r = sys_write(fd, (void*)get_long(iov, 2*i), get_long(iov, 2*i+1)); if (r.result < 0) return r; ret += r.result; @@ -235,6 +259,7 @@ sysret_t syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n) [SYS_rt_sigaction] = sys_rt_sigaction, [SYS_time] = sys_time, [SYS_gettimeofday] = sys_gettimeofday, + [SYS_times] = sys_times, [SYS_writev] = sys_writev, }; |