1
2
3
4
5
6
7 package unix
8
9 import (
10 "math/bits"
11 "unsafe"
12 )
13
14 const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
15
16
17
18
19
20
21 type CPUSet [cpuSetSize]cpuMask
22
23
24
25 type CPUSetDynamic []cpuMask
26
27 func schedAffinity(trap uintptr, pid int, size uintptr, ptr unsafe.Pointer) error {
28 _, _, e := RawSyscall(trap, uintptr(pid), uintptr(size), uintptr(ptr))
29 if e != 0 {
30 return errnoErr(e)
31 }
32 return nil
33 }
34
35
36
37 func SchedGetaffinity(pid int, set *CPUSet) error {
38 return schedAffinity(SYS_SCHED_GETAFFINITY, pid, unsafe.Sizeof(*set), unsafe.Pointer(set))
39 }
40
41
42
43 func SchedSetaffinity(pid int, set *CPUSet) error {
44 return schedAffinity(SYS_SCHED_SETAFFINITY, pid, unsafe.Sizeof(*set), unsafe.Pointer(set))
45 }
46
47
48 func (s *CPUSet) Zero() {
49 clear(s[:])
50 }
51
52
53
54
55 func (s *CPUSet) Fill() {
56 cpuMaskFill(s[:])
57 }
58
59 func cpuBitsIndex(cpu int) int {
60 return cpu / _NCPUBITS
61 }
62
63 func cpuBitsMask(cpu int) cpuMask {
64 return cpuMask(1 << (uint(cpu) % _NCPUBITS))
65 }
66
67 func cpuMaskFill(s []cpuMask) {
68 for i := range s {
69 s[i] = ^cpuMask(0)
70 }
71 }
72
73 func cpuMaskSet(s []cpuMask, cpu int) {
74 i := cpuBitsIndex(cpu)
75 if i < len(s) {
76 s[i] |= cpuBitsMask(cpu)
77 }
78 }
79
80 func cpuMaskClear(s []cpuMask, cpu int) {
81 i := cpuBitsIndex(cpu)
82 if i < len(s) {
83 s[i] &^= cpuBitsMask(cpu)
84 }
85 }
86
87 func cpuMaskIsSet(s []cpuMask, cpu int) bool {
88 i := cpuBitsIndex(cpu)
89 if i < len(s) {
90 return s[i]&cpuBitsMask(cpu) != 0
91 }
92 return false
93 }
94
95 func cpuMaskCount(s []cpuMask) int {
96 c := 0
97 for _, b := range s {
98 c += bits.OnesCount64(uint64(b))
99 }
100 return c
101 }
102
103
104 func (s *CPUSet) Set(cpu int) {
105 cpuMaskSet(s[:], cpu)
106 }
107
108
109 func (s *CPUSet) Clear(cpu int) {
110 cpuMaskClear(s[:], cpu)
111 }
112
113
114 func (s *CPUSet) IsSet(cpu int) bool {
115 return cpuMaskIsSet(s[:], cpu)
116 }
117
118
119 func (s *CPUSet) Count() int {
120 return cpuMaskCount(s[:])
121 }
122
123
124
125 func NewCPUSet(maxCPU int) CPUSetDynamic {
126 numMasks := (maxCPU + _NCPUBITS - 1) / _NCPUBITS
127 if numMasks == 0 {
128 numMasks = 1
129 }
130 return make(CPUSetDynamic, numMasks)
131 }
132
133
134 func (s CPUSetDynamic) Zero() {
135 clear(s)
136 }
137
138
139
140
141 func (s CPUSetDynamic) Fill() {
142 cpuMaskFill(s)
143 }
144
145
146 func (s CPUSetDynamic) Set(cpu int) {
147 cpuMaskSet(s, cpu)
148 }
149
150
151 func (s CPUSetDynamic) Clear(cpu int) {
152 cpuMaskClear(s, cpu)
153 }
154
155
156 func (s CPUSetDynamic) IsSet(cpu int) bool {
157 return cpuMaskIsSet(s, cpu)
158 }
159
160
161 func (s CPUSetDynamic) Count() int {
162 return cpuMaskCount(s)
163 }
164
165 func (s CPUSetDynamic) size() uintptr {
166 return uintptr(len(s)) * unsafe.Sizeof(cpuMask(0))
167 }
168
169 func (s CPUSetDynamic) pointer() unsafe.Pointer {
170 if len(s) == 0 {
171 return nil
172 }
173 return unsafe.Pointer(&s[0])
174 }
175
176
177
178
179
180
181 func SchedGetaffinityDynamic(pid int, set CPUSetDynamic) error {
182 return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set.size(), set.pointer())
183 }
184
185
186
187 func SchedSetaffinityDynamic(pid int, set CPUSetDynamic) error {
188 return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set.size(), set.pointer())
189 }
190
View as plain text