113 lines
3.8 KiB
Go
113 lines
3.8 KiB
Go
// Copyright 2018 The gVisor Authors.
|
|
//
|
|
// 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.dev/gvisor/pkg/abi/linux"
|
|
"gvisor.dev/gvisor/pkg/sentry/arch"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
|
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
|
"gvisor.dev/gvisor/pkg/sentry/usage"
|
|
"gvisor.dev/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
|
|
}
|