diff options
Diffstat (limited to 'pkg/sentry/syscalls/linux/sys_rusage.go')
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_rusage.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_rusage.go b/pkg/sentry/syscalls/linux/sys_rusage.go new file mode 100644 index 000000000..82e42b589 --- /dev/null +++ b/pkg/sentry/syscalls/linux/sys_rusage.go @@ -0,0 +1,112 @@ +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package linux + +import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" + "gvisor.googlesource.com/gvisor/pkg/sentry/usage" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +func getrusage(t *kernel.Task, which int32) linux.Rusage { + var cs usage.CPUStats + + switch which { + case linux.RUSAGE_SELF: + cs = t.ThreadGroup().CPUStats() + + case linux.RUSAGE_CHILDREN: + cs = t.ThreadGroup().JoinedChildCPUStats() + + case linux.RUSAGE_THREAD: + cs = t.CPUStats() + + case linux.RUSAGE_BOTH: + tg := t.ThreadGroup() + cs = tg.CPUStats() + cs.Accumulate(tg.JoinedChildCPUStats()) + } + + return linux.Rusage{ + UTime: linux.NsecToTimeval(cs.UserTime.Nanoseconds()), + STime: linux.NsecToTimeval(cs.SysTime.Nanoseconds()), + NVCSw: int64(cs.VoluntarySwitches), + MaxRSS: int64(t.MaxRSS(which) / 1024), + } +} + +// Getrusage implements linux syscall getrusage(2). +// marked "y" are supported now +// marked "*" are not used on Linux +// marked "p" are pending for support +// +// y struct timeval ru_utime; /* user CPU time used */ +// y struct timeval ru_stime; /* system CPU time used */ +// p long ru_maxrss; /* maximum resident set size */ +// * long ru_ixrss; /* integral shared memory size */ +// * long ru_idrss; /* integral unshared data size */ +// * long ru_isrss; /* integral unshared stack size */ +// p long ru_minflt; /* page reclaims (soft page faults) */ +// p long ru_majflt; /* page faults (hard page faults) */ +// * long ru_nswap; /* swaps */ +// p long ru_inblock; /* block input operations */ +// p long ru_oublock; /* block output operations */ +// * long ru_msgsnd; /* IPC messages sent */ +// * long ru_msgrcv; /* IPC messages received */ +// * long ru_nsignals; /* signals received */ +// y long ru_nvcsw; /* voluntary context switches */ +// y long ru_nivcsw; /* involuntary context switches */ +func Getrusage(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + which := args[0].Int() + addr := args[1].Pointer() + + if which != linux.RUSAGE_SELF && which != linux.RUSAGE_CHILDREN && which != linux.RUSAGE_THREAD { + return 0, nil, syserror.EINVAL + } + + ru := getrusage(t, which) + _, err := t.CopyOut(addr, &ru) + return 0, nil, err +} + +// Times implements linux syscall times(2). +func Times(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + + // Calculate the ticks first, and figure out if any additional work is + // necessary. Linux allows for a NULL addr, in which case only the + // return value is meaningful. We don't need to do anything else. + ticks := uintptr(ktime.NowFromContext(t).Nanoseconds() / linux.ClockTick.Nanoseconds()) + if addr == 0 { + return ticks, nil, nil + } + + cs1 := t.ThreadGroup().CPUStats() + cs2 := t.ThreadGroup().JoinedChildCPUStats() + r := linux.Tms{ + UTime: linux.ClockTFromDuration(cs1.UserTime), + STime: linux.ClockTFromDuration(cs1.SysTime), + CUTime: linux.ClockTFromDuration(cs2.UserTime), + CSTime: linux.ClockTFromDuration(cs2.SysTime), + } + if _, err := t.CopyOut(addr, &r); err != nil { + return 0, nil, err + } + + return ticks, nil, nil +} |