1 /*
2  * Copyright (c) 2012
3  *      Inferno Nettverk A/S, Norway.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. The above copyright notice, this list of conditions and the following
9  *    disclaimer must appear in all copies of the software, derivative works
10  *    or modified versions, and any portions thereof, aswell as in all
11  *    supporting documentation.
12  * 2. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:
14  *      This product includes software developed by
15  *      Inferno Nettverk A/S, Norway.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Inferno Nettverk A/S requests users of this software to return to
31  *
32  *  Software Distribution Coordinator  or  sdc@inet.no
33  *  Inferno Nettverk A/S
34  *  Oslo Research Park
35  *  Gaustadall�en 21
36  *  NO-0349 Oslo
37  *  Norway
38  *
39  * any improvements or extensions that they make and grant Inferno Nettverk A/S
40  * the rights to redistribute these changes.
41  *
42  */
43 
44 static const char rcsid[] =
45 "$Id: cpuaffinity.c,v 1.15 2012/12/05 10:46:12 michaels Exp $";
46 
47 /*
48  * Access to the CPU_foo() macros on Linux requires _GNU_SOURCE to be
49  * defined. This define is not compatible with _BSD_SOURCE which is
50  * required for other parts of the code.
51  * To avoid any unpredictable changes in the build environment, the
52  * _GNU_SOURCE value is only defined in this file and the contents
53  * of this file is kept as simple as possible.
54  */
55 
56 #define _GNU_SOURCE
57 
58 #include "common.h"
59 
60 #include <sched.h>
61 
62 #if HAVE_SCHED_SETAFFINITY
63 
64 #if !HAVE_CPU_EQUAL
65 int
66 CPU_EQUAL(const cpu_set_t *set1, const cpu_set_t *set2);
67 
68 int
CPU_EQUAL(set1,set2)69 CPU_EQUAL(set1, set2)
70    const cpu_set_t *set1;
71    const cpu_set_t *set2;
72 {
73    size_t i;
74 
75    for (i = 0; i < cpu_get_setsize(); i++)
76       if (CPU_ISSET(i, set1) != CPU_ISSET(i, set2))
77          return 0;
78 
79    return 1;
80 }
81 #endif /* !HAVE_CPU_EQUAL */
82 
83 size_t
cpu_get_setsize(void)84 cpu_get_setsize(void)
85 {
86    return CPU_SETSIZE;
87 }
88 
89 void
cpu_set(cpu,set)90 cpu_set(cpu, set)
91    const int cpu;
92    cpu_set_t *set;
93 {
94    CPU_SET(cpu, set);
95 }
96 
97 void
cpu_zero(set)98 cpu_zero(set)
99    cpu_set_t *set;
100 {
101    CPU_ZERO(set);
102 }
103 
104 int
cpu_equal(set1,set2)105 cpu_equal(set1, set2)
106    const cpu_set_t *set1;
107    const cpu_set_t *set2;
108 {
109    return CPU_EQUAL(set1, set2);
110 }
111 
112 int
cpu_isset(cpu,set)113 cpu_isset(cpu, set)
114    const int cpu;
115    const cpu_set_t *set;
116 {
117    return CPU_ISSET(cpu, set);
118 }
119 
120 int
cpu_getaffinity(pid,cpusetsize,mask)121 cpu_getaffinity(pid, cpusetsize, mask)
122    pid_t pid;
123    size_t cpusetsize;
124    cpu_set_t *mask;
125 {
126    return sched_getaffinity(pid, cpusetsize, mask);
127 }
128 
129 int
cpu_setaffinity(pid,cpusetsize,mask)130 cpu_setaffinity(pid, cpusetsize, mask)
131    pid_t pid;
132    size_t cpusetsize;
133    const cpu_set_t *mask;
134 {
135    return sched_setaffinity(pid, cpusetsize, mask);
136 }
137 
138 int
sockd_cpuset_isok(set)139 sockd_cpuset_isok(set)
140    const cpu_set_t *set;
141 {
142    const char *function = "sockd_cpumask_isok()";
143    const long cpus      = sysconf(_SC_NPROCESSORS_ONLN);
144    const size_t setsize = cpu_get_setsize();
145    int i;
146 
147    if (cpus == -1)
148       serr("%s: sysconf(_SC_NPROCESSORS_ONLN) failed", function);
149 
150    for (i = 0; i < (int)setsize; ++i)
151       if (cpu_isset(i, set) && i + 1 > cpus)
152          return 0;
153 
154    return 1;
155 }
156 
157 #endif /* HAVE_SCHED_SETAFFINITY */
158