2022-12-08 13:05:19 -03:00

92 lines
1.9 KiB
Go

// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
package cgroups_v2
import (
"math"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/gitpod-io/gitpod/common-go/cgroups"
"golang.org/x/xerrors"
)
const (
StatUsageTotal = "usage_usec"
StatUsageUser = "user_usec"
StatUsageSystem = "system_usec"
)
type Cpu struct {
path string
}
func NewCpuControllerWithMount(mountPoint, path string) *Cpu {
fullPath := filepath.Join(mountPoint, path)
return &Cpu{
path: fullPath,
}
}
func NewCpuController(path string) *Cpu {
return &Cpu{
path: path,
}
}
// Max return the quota and period in microseconds
func (c *Cpu) Max() (quota uint64, period uint64, err error) {
path := filepath.Join(c.path, "cpu.max")
content, err := os.ReadFile(path)
if err != nil {
return 0, 0, err
}
values := strings.Split(strings.TrimSpace(string(content)), " ")
if len(values) < 2 {
return 0, 0, xerrors.Errorf("%s has less than 2 values", path)
}
if values[0] == "max" {
quota = math.MaxUint64
} else {
quota, err = strconv.ParseUint(values[0], 10, 64)
if err != nil {
return 0, 0, err
}
}
period, err = strconv.ParseUint(values[1], 10, 64)
if err != nil {
return 0, 0, err
}
return quota, period, nil
}
// Stat returns cpu statistics (all values are in microseconds)
func (c *Cpu) Stat() (*cgroups.CpuStats, error) {
path := filepath.Join(c.path, "cpu.stat")
statMap, err := cgroups.ReadFlatKeyedFile(path)
if err != nil {
return nil, err
}
stats := cgroups.CpuStats{
UsageTotal: statMap[StatUsageTotal],
UsageUser: statMap[StatUsageUser],
UsageSystem: statMap[StatUsageSystem],
}
return &stats, nil
}
func (c *Cpu) PSI() (cgroups.PSI, error) {
path := filepath.Join(c.path, "cpu.pressure")
return cgroups.ReadPSIValue(path)
}