summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrandon Potter <brandon.potter@amd.com>2015-04-22 07:51:27 -0700
committerBrandon Potter <brandon.potter@amd.com>2015-04-22 07:51:27 -0700
commit4991c2996516b3226c37cde7ea4b05552e66277a (patch)
tree60fdc46ad2a057da7fd23e8018fc5be81fcee76a /src
parent00e3cab8fc3ffce89c4bbb2e6c4ab3aea873a18d (diff)
downloadgem5-4991c2996516b3226c37cde7ea4b05552e66277a.tar.xz
syscall_emul: implement clock_gettime system call
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/linux/process.cc4
-rw-r--r--src/kern/linux/linux.hh6
-rw-r--r--src/sim/syscall_emul.hh43
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;