66
|
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
|
|
5 // CPU affinity functions
|
|
6
|
|
7 package unix
|
|
8
|
|
9 import (
|
|
10 "math/bits"
|
|
11 "unsafe"
|
|
12 )
|
|
13
|
|
14 const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
|
15
|
|
16 // CPUSet represents a CPU affinity mask.
|
|
17 type CPUSet [cpuSetSize]cpuMask
|
|
18
|
|
19 func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
|
20 _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
|
21 if e != 0 {
|
|
22 return errnoErr(e)
|
|
23 }
|
|
24 return nil
|
|
25 }
|
|
26
|
|
27 // SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
|
28 // If pid is 0 the calling thread is used.
|
|
29 func SchedGetaffinity(pid int, set *CPUSet) error {
|
|
30 return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
|
31 }
|
|
32
|
|
33 // SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
|
34 // If pid is 0 the calling thread is used.
|
|
35 func SchedSetaffinity(pid int, set *CPUSet) error {
|
|
36 return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
|
37 }
|
|
38
|
|
39 // Zero clears the set s, so that it contains no CPUs.
|
|
40 func (s *CPUSet) Zero() {
|
|
41 for i := range s {
|
|
42 s[i] = 0
|
|
43 }
|
|
44 }
|
|
45
|
|
46 func cpuBitsIndex(cpu int) int {
|
|
47 return cpu / _NCPUBITS
|
|
48 }
|
|
49
|
|
50 func cpuBitsMask(cpu int) cpuMask {
|
|
51 return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
|
52 }
|
|
53
|
|
54 // Set adds cpu to the set s.
|
|
55 func (s *CPUSet) Set(cpu int) {
|
|
56 i := cpuBitsIndex(cpu)
|
|
57 if i < len(s) {
|
|
58 s[i] |= cpuBitsMask(cpu)
|
|
59 }
|
|
60 }
|
|
61
|
|
62 // Clear removes cpu from the set s.
|
|
63 func (s *CPUSet) Clear(cpu int) {
|
|
64 i := cpuBitsIndex(cpu)
|
|
65 if i < len(s) {
|
|
66 s[i] &^= cpuBitsMask(cpu)
|
|
67 }
|
|
68 }
|
|
69
|
|
70 // IsSet reports whether cpu is in the set s.
|
|
71 func (s *CPUSet) IsSet(cpu int) bool {
|
|
72 i := cpuBitsIndex(cpu)
|
|
73 if i < len(s) {
|
|
74 return s[i]&cpuBitsMask(cpu) != 0
|
|
75 }
|
|
76 return false
|
|
77 }
|
|
78
|
|
79 // Count returns the number of CPUs in the set s.
|
|
80 func (s *CPUSet) Count() int {
|
|
81 c := 0
|
|
82 for _, b := range s {
|
|
83 c += bits.OnesCount64(uint64(b))
|
|
84 }
|
|
85 return c
|
|
86 }
|