affinity_linux.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // CPU affinity functions
  5. package unix
  6. import (
  7. "math/bits"
  8. "unsafe"
  9. )
  10. const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
  11. // CPUSet represents a CPU affinity mask.
  12. type CPUSet [cpuSetSize]cpuMask
  13. func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
  14. _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
  15. if e != 0 {
  16. return errnoErr(e)
  17. }
  18. return nil
  19. }
  20. // SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
  21. // If pid is 0 the calling thread is used.
  22. func SchedGetaffinity(pid int, set *CPUSet) error {
  23. return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
  24. }
  25. // SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
  26. // If pid is 0 the calling thread is used.
  27. func SchedSetaffinity(pid int, set *CPUSet) error {
  28. return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
  29. }
  30. // Zero clears the set s, so that it contains no CPUs.
  31. func (s *CPUSet) Zero() {
  32. clear(s[:])
  33. }
  34. // Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
  35. // will silently ignore any invalid CPU bits in [CPUSet] so this is an
  36. // efficient way of resetting the CPU affinity of a process.
  37. func (s *CPUSet) Fill() {
  38. for i := range s {
  39. s[i] = ^cpuMask(0)
  40. }
  41. }
  42. func cpuBitsIndex(cpu int) int {
  43. return cpu / _NCPUBITS
  44. }
  45. func cpuBitsMask(cpu int) cpuMask {
  46. return cpuMask(1 << (uint(cpu) % _NCPUBITS))
  47. }
  48. // Set adds cpu to the set s.
  49. func (s *CPUSet) Set(cpu int) {
  50. i := cpuBitsIndex(cpu)
  51. if i < len(s) {
  52. s[i] |= cpuBitsMask(cpu)
  53. }
  54. }
  55. // Clear removes cpu from the set s.
  56. func (s *CPUSet) Clear(cpu int) {
  57. i := cpuBitsIndex(cpu)
  58. if i < len(s) {
  59. s[i] &^= cpuBitsMask(cpu)
  60. }
  61. }
  62. // IsSet reports whether cpu is in the set s.
  63. func (s *CPUSet) IsSet(cpu int) bool {
  64. i := cpuBitsIndex(cpu)
  65. if i < len(s) {
  66. return s[i]&cpuBitsMask(cpu) != 0
  67. }
  68. return false
  69. }
  70. // Count returns the number of CPUs in the set s.
  71. func (s *CPUSet) Count() int {
  72. c := 0
  73. for _, b := range s {
  74. c += bits.OnesCount64(uint64(b))
  75. }
  76. return c
  77. }