summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/timekeeper.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2018-10-17 15:48:55 -0700
committerShentubot <shentubot@google.com>2018-10-17 15:50:02 -0700
commitb2a88ff4713325fca736f6a3bf200be02d2d72a7 (patch)
tree489e54828c2bfe0bf326976920e5d5e612f877a0 /pkg/sentry/kernel/timekeeper.go
parent6922eee6499212a009fdc254224f916bd1c46f29 (diff)
Check thread group CPU timers in the CPU clock ticker.
This reduces the number of goroutines and runtime timers when ITIMER_VIRTUAL or ITIMER_PROF are enabled, or when RLIMIT_CPU is set. This also ensures that thread group CPU timers only advance if running tasks are observed at the time the CPU clock advances, mostly eliminating the possibility that a CPU timer expiration observes no running tasks and falls back to the group leader. PiperOrigin-RevId: 217603396 Change-Id: Ia24ce934d5574334857d9afb5ad8ca0b6a6e65f4
Diffstat (limited to 'pkg/sentry/kernel/timekeeper.go')
-rw-r--r--pkg/sentry/kernel/timekeeper.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go
index df5dbe128..2167f3efe 100644
--- a/pkg/sentry/kernel/timekeeper.go
+++ b/pkg/sentry/kernel/timekeeper.go
@@ -15,6 +15,7 @@
package kernel
import (
+ "fmt"
"sync"
"time"
@@ -277,3 +278,28 @@ func (t *Timekeeper) GetTime(c sentrytime.ClockID) (int64, error) {
func (t *Timekeeper) BootTime() ktime.Time {
return t.bootTime
}
+
+// timekeeperClock is a ktime.Clock that reads time from a
+// kernel.Timekeeper-managed clock.
+//
+// +stateify savable
+type timekeeperClock struct {
+ tk *Timekeeper
+ c sentrytime.ClockID
+
+ // Implements ktime.Clock.WallTimeUntil.
+ ktime.WallRateClock `state:"nosave"`
+
+ // Implements waiter.Waitable. (We have no ability to detect
+ // discontinuities from external changes to CLOCK_REALTIME).
+ ktime.NoClockEvents `state:"nosave"`
+}
+
+// Now implements ktime.Clock.Now.
+func (tc *timekeeperClock) Now() ktime.Time {
+ now, err := tc.tk.GetTime(tc.c)
+ if err != nil {
+ panic(fmt.Sprintf("timekeeperClock(ClockID=%v)).Now: %v", tc.c, err))
+ }
+ return ktime.FromNanoseconds(now)
+}