diff options
Diffstat (limited to 'pkg/bits')
-rw-r--r-- | pkg/bits/BUILD | 55 | ||||
-rw-r--r-- | pkg/bits/bits32.go | 33 | ||||
-rw-r--r-- | pkg/bits/bits64.go | 33 | ||||
-rw-r--r-- | pkg/bits/bits_state_autogen.go | 6 | ||||
-rw-r--r-- | pkg/bits/bits_template.go | 52 | ||||
-rw-r--r-- | pkg/bits/uint64_test.go | 134 |
6 files changed, 72 insertions, 241 deletions
diff --git a/pkg/bits/BUILD b/pkg/bits/BUILD deleted file mode 100644 index 63f4670d7..000000000 --- a/pkg/bits/BUILD +++ /dev/null @@ -1,55 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") -load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") - -package(licenses = ["notice"]) - -go_library( - name = "bits", - srcs = [ - "bits.go", - "bits32.go", - "bits64.go", - "uint64_arch.go", - "uint64_arch_amd64_asm.s", - "uint64_arch_arm64_asm.s", - "uint64_arch_generic.go", - ], - visibility = ["//:sandbox"], -) - -go_template( - name = "bits_template", - srcs = ["bits_template.go"], - types = [ - "T", - ], -) - -go_template_instance( - name = "bits64", - out = "bits64.go", - package = "bits", - suffix = "64", - template = ":bits_template", - types = { - "T": "uint64", - }, -) - -go_template_instance( - name = "bits32", - out = "bits32.go", - package = "bits", - suffix = "32", - template = ":bits_template", - types = { - "T": "uint32", - }, -) - -go_test( - name = "bits_test", - size = "small", - srcs = ["uint64_test.go"], - library = ":bits", -) diff --git a/pkg/bits/bits32.go b/pkg/bits/bits32.go new file mode 100644 index 000000000..28134a9e7 --- /dev/null +++ b/pkg/bits/bits32.go @@ -0,0 +1,33 @@ +package bits + +// IsOn returns true if *all* bits set in 'bits' are set in 'mask'. +func IsOn32(mask, bits uint32) bool { + return mask&bits == bits +} + +// IsAnyOn returns true if *any* bit set in 'bits' is set in 'mask'. +func IsAnyOn32(mask, bits uint32) bool { + return mask&bits != 0 +} + +// Mask returns a T with all of the given bits set. +func Mask32(is ...int) uint32 { + ret := uint32(0) + for _, i := range is { + ret |= MaskOf32(i) + } + return ret +} + +// MaskOf is like Mask, but sets only a single bit (more efficiently). +func MaskOf32(i int) uint32 { + return uint32(1) << uint32(i) +} + +// IsPowerOfTwo returns true if v is power of 2. +func IsPowerOfTwo32(v uint32) bool { + if v == 0 { + return false + } + return v&(v-1) == 0 +} diff --git a/pkg/bits/bits64.go b/pkg/bits/bits64.go new file mode 100644 index 000000000..73117b19b --- /dev/null +++ b/pkg/bits/bits64.go @@ -0,0 +1,33 @@ +package bits + +// IsOn returns true if *all* bits set in 'bits' are set in 'mask'. +func IsOn64(mask, bits uint64) bool { + return mask&bits == bits +} + +// IsAnyOn returns true if *any* bit set in 'bits' is set in 'mask'. +func IsAnyOn64(mask, bits uint64) bool { + return mask&bits != 0 +} + +// Mask returns a T with all of the given bits set. +func Mask64(is ...int) uint64 { + ret := uint64(0) + for _, i := range is { + ret |= MaskOf64(i) + } + return ret +} + +// MaskOf is like Mask, but sets only a single bit (more efficiently). +func MaskOf64(i int) uint64 { + return uint64(1) << uint64(i) +} + +// IsPowerOfTwo returns true if v is power of 2. +func IsPowerOfTwo64(v uint64) bool { + if v == 0 { + return false + } + return v&(v-1) == 0 +} diff --git a/pkg/bits/bits_state_autogen.go b/pkg/bits/bits_state_autogen.go new file mode 100644 index 000000000..22b8250c6 --- /dev/null +++ b/pkg/bits/bits_state_autogen.go @@ -0,0 +1,6 @@ +// automatically generated by stateify. + +// +build amd64 arm64 +// +build !amd64,!arm64 + +package bits diff --git a/pkg/bits/bits_template.go b/pkg/bits/bits_template.go deleted file mode 100644 index 998645388..000000000 --- a/pkg/bits/bits_template.go +++ /dev/null @@ -1,52 +0,0 @@ -// 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 bits - -// Non-atomic bit operations on a template type T. - -// T is a required type parameter that must be an integral type. -type T uint64 - -// IsOn returns true if *all* bits set in 'bits' are set in 'mask'. -func IsOn(mask, bits T) bool { - return mask&bits == bits -} - -// IsAnyOn returns true if *any* bit set in 'bits' is set in 'mask'. -func IsAnyOn(mask, bits T) bool { - return mask&bits != 0 -} - -// Mask returns a T with all of the given bits set. -func Mask(is ...int) T { - ret := T(0) - for _, i := range is { - ret |= MaskOf(i) - } - return ret -} - -// MaskOf is like Mask, but sets only a single bit (more efficiently). -func MaskOf(i int) T { - return T(1) << T(i) -} - -// IsPowerOfTwo returns true if v is power of 2. -func IsPowerOfTwo(v T) bool { - if v == 0 { - return false - } - return v&(v-1) == 0 -} diff --git a/pkg/bits/uint64_test.go b/pkg/bits/uint64_test.go deleted file mode 100644 index 193d1ebcd..000000000 --- a/pkg/bits/uint64_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// 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 bits - -import ( - "reflect" - "testing" -) - -func TestTrailingZeros64(t *testing.T) { - for i := 0; i <= 64; i++ { - n := uint64(1) << uint(i) - if got, want := TrailingZeros64(n), i; got != want { - t.Errorf("TrailingZeros64(%#x): got %d, wanted %d", n, got, want) - } - } - - for i := 0; i < 64; i++ { - n := ^uint64(0) << uint(i) - if got, want := TrailingZeros64(n), i; got != want { - t.Errorf("TrailingZeros64(%#x): got %d, wanted %d", n, got, want) - } - } - - for i := 0; i < 64; i++ { - n := ^uint64(0) >> uint(i) - if got, want := TrailingZeros64(n), 0; got != want { - t.Errorf("TrailingZeros64(%#x): got %d, wanted %d", n, got, want) - } - } -} - -func TestMostSignificantOne64(t *testing.T) { - for i := 0; i <= 64; i++ { - n := uint64(1) << uint(i) - if got, want := MostSignificantOne64(n), i; got != want { - t.Errorf("MostSignificantOne64(%#x): got %d, wanted %d", n, got, want) - } - } - - for i := 0; i < 64; i++ { - n := ^uint64(0) >> uint(i) - if got, want := MostSignificantOne64(n), 63-i; got != want { - t.Errorf("MostSignificantOne64(%#x): got %d, wanted %d", n, got, want) - } - } - - for i := 0; i < 64; i++ { - n := ^uint64(0) << uint(i) - if got, want := MostSignificantOne64(n), 63; got != want { - t.Errorf("MostSignificantOne64(%#x): got %d, wanted %d", n, got, want) - } - } -} - -func TestForEachSetBit64(t *testing.T) { - for _, want := range [][]int{ - {}, - {0}, - {1}, - {63}, - {0, 1}, - {1, 3, 5}, - {0, 63}, - } { - n := Mask64(want...) - // "Slice values are deeply equal when ... they are both nil or both - // non-nil ..." - got := make([]int, 0) - ForEachSetBit64(n, func(i int) { - got = append(got, i) - }) - if !reflect.DeepEqual(got, want) { - t.Errorf("ForEachSetBit64(%#x): iterated bits %v, wanted %v", n, got, want) - } - } -} - -func TestIsOn(t *testing.T) { - type spec struct { - mask uint64 - bits uint64 - any bool - all bool - } - for _, s := range []spec{ - {Mask64(0), Mask64(0), true, true}, - {Mask64(63), Mask64(63), true, true}, - {Mask64(0), Mask64(1), false, false}, - {Mask64(0), Mask64(0, 1), true, false}, - - {Mask64(1, 63), Mask64(1), true, true}, - {Mask64(1, 63), Mask64(1, 63), true, true}, - {Mask64(1, 63), Mask64(0, 1, 63), true, false}, - {Mask64(1, 63), Mask64(0, 62), false, false}, - } { - if ok := IsAnyOn64(s.mask, s.bits); ok != s.any { - t.Errorf("IsAnyOn(%#x, %#x) = %v, wanted: %v", s.mask, s.bits, ok, s.any) - } - if ok := IsOn64(s.mask, s.bits); ok != s.all { - t.Errorf("IsOn(%#x, %#x) = %v, wanted: %v", s.mask, s.bits, ok, s.all) - } - } -} - -func TestIsPowerOfTwo(t *testing.T) { - for _, tc := range []struct { - v uint64 - want bool - }{ - {v: 0, want: false}, - {v: 1, want: true}, - {v: 2, want: true}, - {v: 3, want: false}, - {v: 4, want: true}, - {v: 5, want: false}, - } { - if got := IsPowerOfTwo64(tc.v); got != tc.want { - t.Errorf("IsPowerOfTwo(%d) = %t, want: %t", tc.v, got, tc.want) - } - } -} |