summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/thread_group.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2018-08-23 16:31:25 -0700
committerShentubot <shentubot@google.com>2018-08-23 16:32:36 -0700
commit64403265a04aa0c8be3ebb652a09f6e2d7a84ca7 (patch)
tree8191f06fca712de5588cd418a70707e9df0f2c25 /pkg/sentry/kernel/thread_group.go
parente855e9cebc45f5fd7a9583f476c8965fc395a15e (diff)
Implement POSIX per-process interval timers.
PiperOrigin-RevId: 210021612 Change-Id: If7c161e6fd08cf17942bfb6bc5a8d2c4e271c61e
Diffstat (limited to 'pkg/sentry/kernel/thread_group.go')
-rw-r--r--pkg/sentry/kernel/thread_group.go27
1 files changed, 25 insertions, 2 deletions
diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go
index 441b8a822..13dce08ce 100644
--- a/pkg/sentry/kernel/thread_group.go
+++ b/pkg/sentry/kernel/thread_group.go
@@ -155,6 +155,14 @@ type ThreadGroup struct {
// tm contains process timers. TimerManager fields are immutable.
tm TimerManager
+ // timers is the thread group's POSIX interval timers. nextTimerID is the
+ // TimerID at which allocation should begin searching for an unused ID.
+ //
+ // timers and nextTimerID are protected by timerMu.
+ timerMu sync.Mutex `state:"nosave"`
+ timers map[linux.TimerID]*IntervalTimer
+ nextTimerID linux.TimerID
+
// exitedCPUStats is the CPU usage for all exited tasks in the thread
// group. exitedCPUStats is protected by the TaskSet mutex.
exitedCPUStats usage.CPUStats
@@ -218,6 +226,7 @@ func NewThreadGroup(ns *PIDNamespace, sh *SignalHandlers, terminationSignal linu
limits: limits,
}
tg.tm = newTimerManager(tg, monotonicClock)
+ tg.timers = make(map[linux.TimerID]*IntervalTimer)
tg.rscr.Store(&RSEQCriticalRegion{})
return tg
}
@@ -252,9 +261,23 @@ func (tg *ThreadGroup) Limits() *limits.LimitSet {
// release releases the thread group's resources.
func (tg *ThreadGroup) release() {
- // This must be done without holding the TaskSet mutex since thread group
- // timers call SendSignal with Timer.mu locked.
+ // These must be done without holding the TaskSet or signal mutexes since
+ // timers send signals with Timer.mu locked.
+
tg.tm.destroy()
+
+ var its []*IntervalTimer
+ tg.pidns.owner.mu.Lock()
+ tg.signalHandlers.mu.Lock()
+ for _, it := range tg.timers {
+ its = append(its, it)
+ }
+ tg.timers = make(map[linux.TimerID]*IntervalTimer) // nil maps can't be saved
+ tg.signalHandlers.mu.Unlock()
+ tg.pidns.owner.mu.Unlock()
+ for _, it := range its {
+ it.DestroyTimer()
+ }
}
// forEachChildThreadGroupLocked indicates over all child ThreadGroups.