123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /*
- Copyright 2019 The Kubernetes 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 socketmask
- import (
- "fmt"
- )
- //SocketMask interface allows hint providers to create SocketMasks for TopologyHints
- type SocketMask interface {
- Add(sockets ...int) error
- Remove(sockets ...int) error
- And(masks ...SocketMask)
- Or(masks ...SocketMask)
- Clear()
- Fill()
- IsEqual(mask SocketMask) bool
- IsEmpty() bool
- IsSet(socket int) bool
- IsNarrowerThan(mask SocketMask) bool
- String() string
- Count() int
- GetSockets() []int
- }
- type socketMask uint64
- //NewSocketMask creates a new SocketMask
- func NewSocketMask(sockets ...int) (SocketMask, error) {
- s := socketMask(0)
- err := (&s).Add(sockets...)
- if err != nil {
- return nil, err
- }
- return &s, nil
- }
- //Add adds the sockets with topology affinity to the SocketMask
- func (s *socketMask) Add(sockets ...int) error {
- mask := *s
- for _, i := range sockets {
- if i < 0 || i >= 64 {
- return fmt.Errorf("socket number must be in range 0-63")
- }
- mask |= 1 << uint64(i)
- }
- *s = mask
- return nil
- }
- //Remove removes specified sockets from SocketMask
- func (s *socketMask) Remove(sockets ...int) error {
- mask := *s
- for _, i := range sockets {
- if i < 0 || i >= 64 {
- return fmt.Errorf("socket number must be in range 0-63")
- }
- mask &^= 1 << uint64(i)
- }
- *s = mask
- return nil
- }
- //And performs and operation on all bits in masks
- func (s *socketMask) And(masks ...SocketMask) {
- for _, m := range masks {
- *s &= *m.(*socketMask)
- }
- }
- //Or performs or operation on all bits in masks
- func (s *socketMask) Or(masks ...SocketMask) {
- for _, m := range masks {
- *s |= *m.(*socketMask)
- }
- }
- //Clear resets all bits in mask to zero
- func (s *socketMask) Clear() {
- *s = 0
- }
- //Fill sets all bits in mask to one
- func (s *socketMask) Fill() {
- *s = socketMask(^uint64(0))
- }
- //IsEmpty checks mask to see if all bits are zero
- func (s *socketMask) IsEmpty() bool {
- return *s == 0
- }
- //IsSet checks socket in mask to see if bit is set to one
- func (s *socketMask) IsSet(socket int) bool {
- if socket < 0 || socket >= 64 {
- return false
- }
- return (*s & (1 << uint64(socket))) > 0
- }
- //IsEqual checks if masks are equal
- func (s *socketMask) IsEqual(mask SocketMask) bool {
- return *s == *mask.(*socketMask)
- }
- // IsNarrowerThan checks if one mask is narrower than another.
- //
- // A mask is said to be "narrower" than another if it has lets bits set. If the
- // same number of bits are set in both masks, then the mask with more
- // lower-numbered bits set wins out.
- func (s *socketMask) IsNarrowerThan(mask SocketMask) bool {
- if s.Count() == mask.Count() {
- if *s < *mask.(*socketMask) {
- return true
- }
- }
- return s.Count() < mask.Count()
- }
- //String converts mask to string
- func (s *socketMask) String() string {
- str := ""
- for i := uint64(0); i < 64; i++ {
- if (*s & (1 << i)) > 0 {
- str += "1"
- } else {
- str += "0"
- }
- }
- return str
- }
- //Count counts number of bits in mask set to one
- func (s *socketMask) Count() int {
- count := 0
- for i := uint64(0); i < 64; i++ {
- if (*s & (1 << i)) > 0 {
- count++
- }
- }
- return count
- }
- //GetSockets returns each socket number with bits set to one
- func (s *socketMask) GetSockets() []int {
- var sockets []int
- for i := uint64(0); i < 64; i++ {
- if (*s & (1 << i)) > 0 {
- sockets = append(sockets, int(i))
- }
- }
- return sockets
- }
|