aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2013-12-13 16:38:43 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2013-12-13 16:38:43 -0800
commitdc49b2b13a112af3ce5d81eed2129160f2f0d3a4 (patch)
treed175ffc7b9ca876e322e09d18e966df892396a1e
parentf62e692e72d1626977be0e92f766bdeed305d903 (diff)
downloadpk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.zip
pk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.tar.gz
pk-dc49b2b13a112af3ce5d81eed2129160f2f0d3a4.tar.bz2
Add times syscall
-rw-r--r--pk/syscall.c49
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,
};