diff options
author | Brandon Potter <brandon.potter@amd.com> | 2015-04-22 07:51:27 -0700 |
---|---|---|
committer | Brandon Potter <brandon.potter@amd.com> | 2015-04-22 07:51:27 -0700 |
commit | 4991c2996516b3226c37cde7ea4b05552e66277a (patch) | |
tree | 60fdc46ad2a057da7fd23e8018fc5be81fcee76a /src | |
parent | 00e3cab8fc3ffce89c4bbb2e6c4ab3aea873a18d (diff) | |
download | gem5-4991c2996516b3226c37cde7ea4b05552e66277a.tar.xz |
syscall_emul: implement clock_gettime system call
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/linux/process.cc | 4 | ||||
-rw-r--r-- | src/kern/linux/linux.hh | 6 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 43 |
3 files changed, 46 insertions, 7 deletions
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index 05a323bd4..9a2bb96b5 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -446,7 +446,7 @@ static SyscallDesc syscallDescs64[] = { /* 225 */ SyscallDesc("timer_getoverrun", unimplementedFunc), /* 226 */ SyscallDesc("timer_delete", unimplementedFunc), /* 227 */ SyscallDesc("clock_settime", unimplementedFunc), - /* 228 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 228 */ SyscallDesc("clock_gettime", clock_gettimeFunc<X86Linux64>), /* 229 */ SyscallDesc("clock_getres", unimplementedFunc), /* 230 */ SyscallDesc("clock_nanosleep", unimplementedFunc), /* 231 */ SyscallDesc("exit_group", exitGroupFunc), @@ -806,7 +806,7 @@ static SyscallDesc syscallDescs32[] = { /* 262 */ SyscallDesc("timer_getoverrun", unimplementedFunc), /* 263 */ SyscallDesc("timer_delete", unimplementedFunc), /* 264 */ SyscallDesc("clock_settime", unimplementedFunc), - /* 265 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 265 */ SyscallDesc("clock_gettime", clock_gettimeFunc<X86Linux32>), /* 266 */ SyscallDesc("clock_getres", unimplementedFunc), /* 267 */ SyscallDesc("clock_nanosleep", unimplementedFunc), /* 268 */ SyscallDesc("statfs64", unimplementedFunc), diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 5e929f1c0..475f9e438 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -130,6 +130,12 @@ class Linux : public OperatingSystem int64_t tv_usec; //!< microseconds }; + /// For clock_gettime(). + struct timespec { + time_t tv_sec; //!< seconds + int64_t tv_nsec; //!< nanoseconds + }; + /// Clock ticks per second, for times(). static const int M5_SC_CLK_TCK = 100; diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index bb73e1fd2..8c1a21a65 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2013 ARM Limited + * Copyright (c) 2015 Advanced Micro Devices, Inc. * All rights reserved * * The license below extends only to copyright in the software and shall @@ -397,6 +398,8 @@ SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, /// A readable name for 1,000,000, for converting microseconds to seconds. const int one_million = 1000000; +/// A readable name for 1,000,000,000, for converting nanoseconds to seconds. +const int one_billion = 1000000000; /// Approximate seconds since the epoch (1/1/1970). About a billion, /// by my reckoning. We want to keep this a constant (not use the @@ -407,13 +410,24 @@ const unsigned seconds_since_epoch = 1000000000; /// microseconds. template <class T1, class T2> void -getElapsedTime(T1 &sec, T2 &usec) +getElapsedTimeMicro(T1 &sec, T2 &usec) { - int elapsed_usecs = curTick() / SimClock::Int::us; + uint64_t elapsed_usecs = curTick() / SimClock::Int::us; sec = elapsed_usecs / one_million; usec = elapsed_usecs % one_million; } +/// Helper function to convert current elapsed time to seconds and +/// nanoseconds. +template <class T1, class T2> +void +getElapsedTimeNano(T1 &sec, T2 &nsec) +{ + uint64_t elapsed_nsecs = curTick() / SimClock::Int::ns; + sec = elapsed_nsecs / one_billion; + nsec = elapsed_nsecs % one_billion; +} + ////////////////////////////////////////////////////////////////////// // // The following emulation functions are generic, but need to be @@ -1283,6 +1297,25 @@ getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } +/// Target clock_gettime() function. +template <class OS> +SyscallReturn +clock_gettimeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + int index = 1; + //int clk_id = p->getSyscallArg(tc, index); + TypedBufferArg<typename OS::timespec> tp(p->getSyscallArg(tc, index)); + + getElapsedTimeNano(tp->tv_sec, tp->tv_nsec); + tp->tv_sec += seconds_since_epoch; + tp->tv_sec = TheISA::htog(tp->tv_sec); + tp->tv_nsec = TheISA::htog(tp->tv_nsec); + + tp.copyOut(tc->getMemProxy()); + + return 0; +} + /// Target gettimeofday() handler. template <class OS> SyscallReturn @@ -1292,7 +1325,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process, int index = 0; TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index)); - getElapsedTime(tp->tv_sec, tp->tv_usec); + getElapsedTimeMicro(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; tp->tv_sec = TheISA::htog(tp->tv_sec); tp->tv_usec = TheISA::htog(tp->tv_usec); @@ -1369,7 +1402,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, switch (who) { case OS::TGT_RUSAGE_SELF: - getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); + getElapsedTimeMicro(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); rup->ru_utime.tv_sec = TheISA::htog(rup->ru_utime.tv_sec); rup->ru_utime.tv_usec = TheISA::htog(rup->ru_utime.tv_usec); break; @@ -1423,7 +1456,7 @@ timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { typename OS::time_t sec, usec; - getElapsedTime(sec, usec); + getElapsedTimeMicro(sec, usec); sec += seconds_since_epoch; int index = 0; |