mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add CLOCK_BOOTTIME as a CLOCK_MONOTONIC alias
Makes CLOCK_BOOTTIME available with * clock_gettime * timerfd_create * clock_gettime vDSO CLOCK_BOOTTIME is implemented as an alias to CLOCK_MONOTONIC. CLOCK_MONOTONIC already keeps track of time across save and restore. This is the closest possible behavior to Linux CLOCK_BOOTIME, as there is no concept of suspend/resume. Updates google/gvisor#218
This commit is contained in:
@@ -121,8 +121,13 @@ func getClock(t *kernel.Task, clockID int32) (ktime.Clock, error) {
|
||||
switch clockID {
|
||||
case linux.CLOCK_REALTIME, linux.CLOCK_REALTIME_COARSE:
|
||||
return t.Kernel().RealtimeClock(), nil
|
||||
case linux.CLOCK_MONOTONIC, linux.CLOCK_MONOTONIC_COARSE, linux.CLOCK_MONOTONIC_RAW:
|
||||
case linux.CLOCK_MONOTONIC, linux.CLOCK_MONOTONIC_COARSE,
|
||||
linux.CLOCK_MONOTONIC_RAW, linux.CLOCK_BOOTTIME:
|
||||
// CLOCK_MONOTONIC approximates CLOCK_MONOTONIC_RAW.
|
||||
// CLOCK_BOOTTIME is internally mapped to CLOCK_MONOTONIC, as:
|
||||
// - CLOCK_BOOTTIME should behave as CLOCK_MONOTONIC while also including suspend time.
|
||||
// - gVisor has no concept of suspend/resume.
|
||||
// - CLOCK_MONOTONIC already includes save/restore time, which is the closest to suspend time.
|
||||
return t.Kernel().MonotonicClock(), nil
|
||||
case linux.CLOCK_PROCESS_CPUTIME_ID:
|
||||
return t.ThreadGroup().CPUClock(), nil
|
||||
|
||||
@@ -38,7 +38,7 @@ func TimerfdCreate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel
|
||||
switch clockID {
|
||||
case linux.CLOCK_REALTIME:
|
||||
c = t.Kernel().RealtimeClock()
|
||||
case linux.CLOCK_MONOTONIC:
|
||||
case linux.CLOCK_MONOTONIC, linux.CLOCK_BOOTTIME:
|
||||
c = t.Kernel().MonotonicClock()
|
||||
default:
|
||||
return 0, nil, syserror.EINVAL
|
||||
|
||||
@@ -132,6 +132,9 @@ std::string PrintClockId(::testing::TestParamInfo<clockid_t> info) {
|
||||
return "CLOCK_MONOTONIC_COARSE";
|
||||
case CLOCK_MONOTONIC_RAW:
|
||||
return "CLOCK_MONOTONIC_RAW";
|
||||
case CLOCK_BOOTTIME:
|
||||
// CLOCK_BOOTTIME is a monotonic clock.
|
||||
return "CLOCK_BOOTTIME";
|
||||
default:
|
||||
return absl::StrCat(info.param);
|
||||
}
|
||||
@@ -140,15 +143,14 @@ std::string PrintClockId(::testing::TestParamInfo<clockid_t> info) {
|
||||
INSTANTIATE_TEST_SUITE_P(ClockGettime, MonotonicClockTest,
|
||||
::testing::Values(CLOCK_MONOTONIC,
|
||||
CLOCK_MONOTONIC_COARSE,
|
||||
CLOCK_MONOTONIC_RAW),
|
||||
CLOCK_MONOTONIC_RAW,
|
||||
CLOCK_BOOTTIME),
|
||||
PrintClockId);
|
||||
|
||||
TEST(ClockGettime, UnimplementedReturnsEINVAL) {
|
||||
SKIP_IF(!IsRunningOnGvisor());
|
||||
|
||||
struct timespec tp;
|
||||
EXPECT_THAT(clock_gettime(CLOCK_BOOTTIME, &tp),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
EXPECT_THAT(clock_gettime(CLOCK_REALTIME_ALARM, &tp),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
EXPECT_THAT(clock_gettime(CLOCK_BOOTTIME_ALARM, &tp),
|
||||
|
||||
@@ -39,6 +39,8 @@ std::string PrintClockId(::testing::TestParamInfo<clockid_t> info) {
|
||||
return "CLOCK_MONOTONIC";
|
||||
case CLOCK_REALTIME:
|
||||
return "CLOCK_REALTIME";
|
||||
case CLOCK_BOOTTIME:
|
||||
return "CLOCK_BOOTTIME";
|
||||
default:
|
||||
return absl::StrCat(info.param);
|
||||
}
|
||||
@@ -95,7 +97,9 @@ TEST_P(CorrectVDSOClockTest, IsCorrect) {
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ClockGettime, CorrectVDSOClockTest,
|
||||
::testing::Values(CLOCK_MONOTONIC, CLOCK_REALTIME),
|
||||
::testing::Values(CLOCK_MONOTONIC,
|
||||
CLOCK_REALTIME,
|
||||
CLOCK_BOOTTIME),
|
||||
PrintClockId);
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -33,6 +33,8 @@ int __common_clock_gettime(clockid_t clock, struct timespec* ts) {
|
||||
ret = ClockRealtime(ts);
|
||||
break;
|
||||
|
||||
// Fallthrough, CLOCK_BOOTTIME is an alias for CLOCK_MONOTONIC
|
||||
case CLOCK_BOOTTIME:
|
||||
case CLOCK_MONOTONIC:
|
||||
ret = ClockMonotonic(ts);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user