syscall_emul: implement clock_gettime system call
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user