1SCHED_SETAFFINITY(2)       Linux Programmer's Manual      SCHED_SETAFFINITY(2)
2
3
4

NAME

6       sched_setaffinity,  sched_getaffinity  -  set  and  get  a thread's CPU
7       affinity mask
8

SYNOPSIS

10       #define _GNU_SOURCE             /* See feature_test_macros(7) */
11       #include <sched.h>
12
13       int sched_setaffinity(pid_t pid, size_t cpusetsize,
14                             const cpu_set_t *mask);
15
16       int sched_getaffinity(pid_t pid, size_t cpusetsize,
17                             cpu_set_t *mask);
18

DESCRIPTION

20       A thread's CPU affinity mask determines the set of CPUs on which it  is
21       eligible  to run.  On a multiprocessor system, setting the CPU affinity
22       mask can be used to obtain performance benefits.  For example, by dedi‐
23       cating  one CPU to a particular thread (i.e., setting the affinity mask
24       of that thread to specify a single CPU, and setting the  affinity  mask
25       of  all  other  threads  to exclude that CPU), it is possible to ensure
26       maximum execution speed for that thread.  Restricting a thread  to  run
27       on  a  single  CPU also avoids the performance cost caused by the cache
28       invalidation that occurs when a thread ceases to execute on one CPU and
29       then recommences execution on a different CPU.
30
31       A  CPU  affinity mask is represented by the cpu_set_t structure, a "CPU
32       set", pointed to by mask.  A set of macros for manipulating CPU sets is
33       described in CPU_SET(3).
34
35       sched_setaffinity()  sets  the CPU affinity mask of the thread whose ID
36       is pid to the value specified by mask.  If pid is zero, then the  call‐
37       ing  thread  is used.  The argument cpusetsize is the length (in bytes)
38       of the data pointed to by mask.  Normally this argument would be speci‐
39       fied as sizeof(cpu_set_t).
40
41       If  the  thread specified by pid is not currently running on one of the
42       CPUs specified in mask, then that thread is migrated to one of the CPUs
43       specified in mask.
44
45       sched_getaffinity()  writes the affinity mask of the thread whose ID is
46       pid into the cpu_set_t structure pointed to by  mask.   The  cpusetsize
47       argument  specifies  the size (in bytes) of mask.  If pid is zero, then
48       the mask of the calling thread is returned.
49

RETURN VALUE

51       On success, sched_setaffinity() and sched_getaffinity() return  0.   On
52       error, -1 is returned, and errno is set appropriately.
53

ERRORS

55       EFAULT A supplied memory address was invalid.
56
57       EINVAL The  affinity bit mask mask contains no processors that are cur‐
58              rently physically on the system  and  permitted  to  the  thread
59              according  to  any  restrictions  that  may be imposed by cpuset
60              cgroups or the "cpuset" mechanism described in cpuset(7).
61
62       EINVAL (sched_getaffinity()   and,    in    kernels    before    2.6.9,
63              sched_setaffinity())  cpusetsize is smaller than the size of the
64              affinity mask used by the kernel.
65
66       EPERM  (sched_setaffinity()) The calling thread does not have appropri‐
67              ate  privileges.  The caller needs an effective user ID equal to
68              the real user ID or effective user ID of the  thread  identified
69              by  pid,  or  it must possess the CAP_SYS_NICE capability in the
70              user namespace of the thread pid.
71
72       ESRCH  The thread whose ID is pid could not be found.
73

VERSIONS

75       The CPU affinity system calls were introduced in  Linux  kernel  2.5.8.
76       The  system call wrappers were introduced in glibc 2.3.  Initially, the
77       glibc interfaces included a cpusetsize argument, typed as unsigned int.
78       In  glibc  2.3.3,  the  cpusetsize  argument  was removed, but was then
79       restored in glibc 2.3.4, with type size_t.
80

CONFORMING TO

82       These system calls are Linux-specific.
83

NOTES

85       After a call to sched_setaffinity(), the  set  of  CPUs  on  which  the
86       thread  will  actually  run is the intersection of the set specified in
87       the mask argument and the set of CPUs actually present on  the  system.
88       The  system  may  further  restrict the set of CPUs on which the thread
89       runs if the "cpuset" mechanism described in cpuset(7)  is  being  used.
90       These  restrictions  on the actual set of CPUs on which the thread will
91       run are silently imposed by the kernel.
92
93       There are various ways of determining the number of CPUs  available  on
94       the  system, including: inspecting the contents of /proc/cpuinfo; using
95       sysconf(3)  to  obtain  the  values  of  the  _SC_NPROCESSORS_CONF  and
96       _SC_NPROCESSORS_ONLN  parameters; and inspecting the list of CPU direc‐
97       tories under /sys/devices/system/cpu/.
98
99       sched(7) has a description of the Linux scheduling scheme.
100
101       The affinity mask is a per-thread attribute that can be adjusted  inde‐
102       pendently  for  each  of  the  threads  in  a  thread group.  The value
103       returned from a call to gettid(2) can be passed in  the  argument  pid.
104       Specifying  pid as 0 will set the attribute for the calling thread, and
105       passing the value returned from  a  call  to  getpid(2)  will  set  the
106       attribute  for  the main thread of the thread group.  (If you are using
107       the POSIX threads API, then use  pthread_setaffinity_np(3)  instead  of
108       sched_setaffinity().)
109
110       The  isolcpus  boot  option  can be used to isolate one or more CPUs at
111       boot time, so that no processes are scheduled onto those CPUs.  Follow‐
112       ing  the  use  of  this boot option, the only way to schedule processes
113       onto the isolated CPUs is  via  sched_setaffinity()  or  the  cpuset(7)
114       mechanism.   For  further information, see the kernel source file Docu‐
115       mentation/admin-guide/kernel-parameters.txt.  As noted  in  that  file,
116       isolcpus  is  the  preferred  mechanism  of  isolating CPUs (versus the
117       alternative of manually setting the CPU affinity of  all  processes  on
118       the system).
119
120       A  child  created  via fork(2) inherits its parent's CPU affinity mask.
121       The affinity mask is preserved across an execve(2).
122
123   C library/kernel differences
124       This manual page describes the glibc interface  for  the  CPU  affinity
125       calls.   The  actual  system call interface is slightly different, with
126       the mask being typed as unsigned long *, reflecting the fact  that  the
127       underlying  implementation  of  CPU sets is a simple bit mask.  On suc‐
128       cess, the raw sched_getaffinity() system  call  returns  the  size  (in
129       bytes) of the cpumask_t data type that is used internally by the kernel
130       to represent the CPU set bit mask.
131
132   Handling systems with large CPU affinity masks
133       The underlying system calls (which represent CPU masks as bit masks  of
134       type  unsigned  long *)  impose  no  restriction on the size of the CPU
135       mask.  However, the cpu_set_t data type used by glibc has a fixed  size
136       of  128  bytes,  meaning that the maximum CPU number that can be repre‐
137       sented is 1023.  If the kernel CPU affinity mask is larger  than  1024,
138       then calls of the form:
139
140           sched_getaffinity(pid, sizeof(cpu_set_t), &mask);
141
142       fail with the error EINVAL, the error produced by the underlying system
143       call for the case where  the  mask  size  specified  in  cpusetsize  is
144       smaller  than  the  size  of  the  affinity  mask  used  by the kernel.
145       (Depending on the system CPU topology, the kernel affinity mask can  be
146       substantially larger than the number of active CPUs in the system.)
147
148       When  working on systems with large kernel CPU affinity masks, one must
149       dynamically allocate the mask argument (see CPU_ALLOC(3)).   Currently,
150       the only way to do this is by probing for the size of the required mask
151       using sched_getaffinity() calls with increasing mask sizes  (until  the
152       call does not fail with the error EINVAL).
153
154       Be  aware that CPU_ALLOC(3) may allocate a slightly larger CPU set than
155       requested (because CPU sets are implemented as bit masks  allocated  in
156       units of sizeof(long)).  Consequently, sched_getaffinity() can set bits
157       beyond the requested allocation size, because the  kernel  sees  a  few
158       additional bits.  Therefore, the caller should iterate over the bits in
159       the returned set, counting those which are set, and stop upon  reaching
160       the value returned by CPU_COUNT(3) (rather than iterating over the num‐
161       ber of bits requested to be allocated).
162

EXAMPLE

164       The program below creates a child process.  The parent and  child  then
165       each  assign  themselves to a specified CPU and execute identical loops
166       that consume some CPU time.  Before terminating, the parent  waits  for
167       the child to complete.  The program takes three command-line arguments:
168       the CPU number for the parent, the CPU number for the  child,  and  the
169       number of loop iterations that both processes should perform.
170
171       As  the  sample runs below demonstrate, the amount of real and CPU time
172       consumed when running the program will  depend  on  intra-core  caching
173       effects and whether the processes are using the same CPU.
174
175       We  first  employ  lscpu(1) to determine that this (x86) system has two
176       cores, each with two CPUs:
177
178           $ lscpu | grep -i 'core.*:|socket'
179           Thread(s) per core:    2
180           Core(s) per socket:    2
181           Socket(s):             1
182
183       We then time the operation of the example program for three cases: both
184       processes  running on the same CPU; both processes running on different
185       CPUs on the same core; and both processes running on different CPUs  on
186       different cores.
187
188           $ time -p ./a.out 0 0 100000000
189           real 14.75
190           user 3.02
191           sys 11.73
192           $ time -p ./a.out 0 1 100000000
193           real 11.52
194           user 3.98
195           sys 19.06
196           $ time -p ./a.out 0 3 100000000
197           real 7.89
198           user 3.29
199           sys 12.07
200
201   Program source
202
203       #define _GNU_SOURCE
204       #include <sched.h>
205       #include <stdio.h>
206       #include <stdlib.h>
207       #include <unistd.h>
208       #include <sys/wait.h>
209
210       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
211                               } while (0)
212
213       int
214       main(int argc, char *argv[])
215       {
216           cpu_set_t set;
217           int parentCPU, childCPU;
218           int nloops, j;
219
220           if (argc != 4) {
221               fprintf(stderr, "Usage: %s parent-cpu child-cpu num-loops\n",
222                       argv[0]);
223               exit(EXIT_FAILURE);
224           }
225
226           parentCPU = atoi(argv[1]);
227           childCPU = atoi(argv[2]);
228           nloops = atoi(argv[3]);
229
230           CPU_ZERO(&set);
231
232           switch (fork()) {
233           case -1:            /* Error */
234               errExit("fork");
235
236           case 0:             /* Child */
237               CPU_SET(childCPU, &set);
238
239               if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
240                   errExit("sched_setaffinity");
241
242               for (j = 0; j < nloops; j++)
243                   getppid();
244
245               exit(EXIT_SUCCESS);
246
247           default:            /* Parent */
248               CPU_SET(parentCPU, &set);
249
250               if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
251                   errExit("sched_setaffinity");
252
253               for (j = 0; j < nloops; j++)
254                   getppid();
255
256               wait(NULL);     /* Wait for child to terminate */
257               exit(EXIT_SUCCESS);
258           }
259       }
260

SEE ALSO

262       lscpu(1), nproc(1), taskset(1), clone(2), getcpu(2), getpriority(2),
263       gettid(2), nice(2), sched_get_priority_max(2),
264       sched_get_priority_min(2), sched_getscheduler(2),
265       sched_setscheduler(2), setpriority(2), CPU_SET(3), get_nprocs(3),
266       pthread_setaffinity_np(3), sched_getcpu(3), capabilities(7), cpuset(7),
267       sched(7), numactl(8)
268

COLOPHON

270       This page is part of release 4.15 of the Linux man-pages project.  A
271       description of the project, information about reporting bugs, and the
272       latest version of this page, can be found at
273       https://www.kernel.org/doc/man-pages/.
274
275
276
277Linux                             2017-09-15              SCHED_SETAFFINITY(2)
Impressum