socketmask.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package socketmask
  14. import (
  15. "fmt"
  16. )
  17. //SocketMask interface allows hint providers to create SocketMasks for TopologyHints
  18. type SocketMask interface {
  19. Add(sockets ...int) error
  20. Remove(sockets ...int) error
  21. And(masks ...SocketMask)
  22. Or(masks ...SocketMask)
  23. Clear()
  24. Fill()
  25. IsEqual(mask SocketMask) bool
  26. IsEmpty() bool
  27. IsSet(socket int) bool
  28. IsNarrowerThan(mask SocketMask) bool
  29. String() string
  30. Count() int
  31. GetSockets() []int
  32. }
  33. type socketMask uint64
  34. //NewSocketMask creates a new SocketMask
  35. func NewSocketMask(sockets ...int) (SocketMask, error) {
  36. s := socketMask(0)
  37. err := (&s).Add(sockets...)
  38. if err != nil {
  39. return nil, err
  40. }
  41. return &s, nil
  42. }
  43. //Add adds the sockets with topology affinity to the SocketMask
  44. func (s *socketMask) Add(sockets ...int) error {
  45. mask := *s
  46. for _, i := range sockets {
  47. if i < 0 || i >= 64 {
  48. return fmt.Errorf("socket number must be in range 0-63")
  49. }
  50. mask |= 1 << uint64(i)
  51. }
  52. *s = mask
  53. return nil
  54. }
  55. //Remove removes specified sockets from SocketMask
  56. func (s *socketMask) Remove(sockets ...int) error {
  57. mask := *s
  58. for _, i := range sockets {
  59. if i < 0 || i >= 64 {
  60. return fmt.Errorf("socket number must be in range 0-63")
  61. }
  62. mask &^= 1 << uint64(i)
  63. }
  64. *s = mask
  65. return nil
  66. }
  67. //And performs and operation on all bits in masks
  68. func (s *socketMask) And(masks ...SocketMask) {
  69. for _, m := range masks {
  70. *s &= *m.(*socketMask)
  71. }
  72. }
  73. //Or performs or operation on all bits in masks
  74. func (s *socketMask) Or(masks ...SocketMask) {
  75. for _, m := range masks {
  76. *s |= *m.(*socketMask)
  77. }
  78. }
  79. //Clear resets all bits in mask to zero
  80. func (s *socketMask) Clear() {
  81. *s = 0
  82. }
  83. //Fill sets all bits in mask to one
  84. func (s *socketMask) Fill() {
  85. *s = socketMask(^uint64(0))
  86. }
  87. //IsEmpty checks mask to see if all bits are zero
  88. func (s *socketMask) IsEmpty() bool {
  89. return *s == 0
  90. }
  91. //IsSet checks socket in mask to see if bit is set to one
  92. func (s *socketMask) IsSet(socket int) bool {
  93. if socket < 0 || socket >= 64 {
  94. return false
  95. }
  96. return (*s & (1 << uint64(socket))) > 0
  97. }
  98. //IsEqual checks if masks are equal
  99. func (s *socketMask) IsEqual(mask SocketMask) bool {
  100. return *s == *mask.(*socketMask)
  101. }
  102. // IsNarrowerThan checks if one mask is narrower than another.
  103. //
  104. // A mask is said to be "narrower" than another if it has lets bits set. If the
  105. // same number of bits are set in both masks, then the mask with more
  106. // lower-numbered bits set wins out.
  107. func (s *socketMask) IsNarrowerThan(mask SocketMask) bool {
  108. if s.Count() == mask.Count() {
  109. if *s < *mask.(*socketMask) {
  110. return true
  111. }
  112. }
  113. return s.Count() < mask.Count()
  114. }
  115. //String converts mask to string
  116. func (s *socketMask) String() string {
  117. str := ""
  118. for i := uint64(0); i < 64; i++ {
  119. if (*s & (1 << i)) > 0 {
  120. str += "1"
  121. } else {
  122. str += "0"
  123. }
  124. }
  125. return str
  126. }
  127. //Count counts number of bits in mask set to one
  128. func (s *socketMask) Count() int {
  129. count := 0
  130. for i := uint64(0); i < 64; i++ {
  131. if (*s & (1 << i)) > 0 {
  132. count++
  133. }
  134. }
  135. return count
  136. }
  137. //GetSockets returns each socket number with bits set to one
  138. func (s *socketMask) GetSockets() []int {
  139. var sockets []int
  140. for i := uint64(0); i < 64; i++ {
  141. if (*s & (1 << i)) > 0 {
  142. sockets = append(sockets, int(i))
  143. }
  144. }
  145. return sockets
  146. }