Check in gVisor.

PiperOrigin-RevId: 194583126
Change-Id: Ica1d8821a90f74e7e745962d71801c598c652463
This commit is contained in:
Googler
2018-04-28 01:44:26 -04:00
committed by Adin Scannell
parent f70210e742
commit d02b74a5dc
1034 changed files with 185323 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
package(licenses = ["notice"]) # Apache 2.0
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "sched",
srcs = [
"cpuset.go",
"sched.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/sched",
visibility = ["//pkg/sentry:internal"],
)
go_test(
name = "sched_test",
size = "small",
srcs = ["cpuset_test.go"],
embed = [":sched"],
)
+105
View File
@@ -0,0 +1,105 @@
// 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 sched
import "math/bits"
const (
bitsPerByte = 8
bytesPerLong = 8 // only for 64-bit architectures
)
// CPUSet contains a bitmap to record CPU information.
//
// Note that this definition is only correct for little-endian architectures,
// since Linux's cpumask_t uses unsigned long.
type CPUSet []byte
// CPUSetSize returns the size in bytes of a CPUSet that can contain num cpus.
func CPUSetSize(num uint) uint {
// NOTE: Applications may expect that the size of a CPUSet in
// bytes is always a multiple of sizeof(unsigned long), since this is true
// in Linux. Thus we always round up.
bytes := (num + bitsPerByte - 1) / bitsPerByte
longs := (bytes + bytesPerLong - 1) / bytesPerLong
return longs * bytesPerLong
}
// NewCPUSet returns a CPUSet for the given number of CPUs which initially
// contains no CPUs.
func NewCPUSet(num uint) CPUSet {
return CPUSet(make([]byte, CPUSetSize(num)))
}
// NewFullCPUSet returns a CPUSet for the given number of CPUs, all of which
// are present in the set.
func NewFullCPUSet(num uint) CPUSet {
c := NewCPUSet(num)
var i uint
for ; i < num/bitsPerByte; i++ {
c[i] = 0xff
}
if rem := num % bitsPerByte; rem != 0 {
c[i] = (1 << rem) - 1
}
return c
}
// Size returns the size of 'c' in bytes.
func (c CPUSet) Size() uint {
return uint(len(c))
}
// NumCPUs returns how many cpus are set in the CPUSet.
func (c CPUSet) NumCPUs() uint {
var n int
for _, b := range c {
n += bits.OnesCount8(b)
}
return uint(n)
}
// Copy returns a copy of the CPUSet.
func (c CPUSet) Copy() CPUSet {
return append(CPUSet(nil), c...)
}
// Set sets the bit corresponding to cpu.
func (c *CPUSet) Set(cpu uint) {
(*c)[cpu/bitsPerByte] |= 1 << (cpu % bitsPerByte)
}
// ClearAbove clears bits corresponding to cpu and all higher cpus.
func (c *CPUSet) ClearAbove(cpu uint) {
i := cpu / bitsPerByte
if i >= c.Size() {
return
}
(*c)[i] &^= 0xff << (cpu % bitsPerByte)
for i++; i < c.Size(); i++ {
(*c)[i] = 0
}
}
// ForEachCPU iterates over the CPUSet and calls fn with the cpu index if
// it's set.
func (c CPUSet) ForEachCPU(fn func(uint)) {
for i := uint(0); i < c.Size()*bitsPerByte; i++ {
bit := uint(1) << (i & (bitsPerByte - 1))
if uint(c[i/bitsPerByte])&bit == bit {
fn(i)
}
}
}
+44
View File
@@ -0,0 +1,44 @@
// 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 sched
import (
"testing"
)
func TestNumCPUs(t *testing.T) {
for i := uint(0); i < 1024; i++ {
c := NewCPUSet(i)
for j := uint(0); j < i; j++ {
c.Set(j)
}
n := c.NumCPUs()
if n != i {
t.Errorf("got wrong number of cpus %d, want %d", n, i)
}
}
}
func TestClearAbove(t *testing.T) {
const n = 1024
c := NewFullCPUSet(n)
for i := uint(0); i < n; i++ {
cpu := n - i
c.ClearAbove(cpu)
if got := c.NumCPUs(); got != cpu {
t.Errorf("iteration %d: got %d cpus, wanted %d", i, got, cpu)
}
}
}
+16
View File
@@ -0,0 +1,16 @@
// 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 sched implements scheduler related features.
package sched