1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2015 Inria. All rights reserved.
4 * Copyright © 2009-2011 Université Bordeaux
5 * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12
13 #include "private/autogen/config.h" /* for HWLOC_WIN_SYS */
14 #include "hwloc.h"
15
16 /* check the binding functions */
17 hwloc_topology_t topology;
18 const struct hwloc_topology_support *support;
19
result_set(const char * msg,int err,int supported)20 static void result_set(const char *msg, int err, int supported)
21 {
22 const char *errmsg = strerror(errno);
23 if (err)
24 printf("%-40s: %sFAILED (%d, %s)\n", msg, supported?"":"X", errno, errmsg);
25 else
26 printf("%-40s: OK\n", msg);
27 }
28
result_get(const char * msg,hwloc_const_bitmap_t expected,hwloc_const_bitmap_t result,int err,int supported)29 static void result_get(const char *msg, hwloc_const_bitmap_t expected, hwloc_const_bitmap_t result, int err, int supported)
30 {
31 const char *errmsg = strerror(errno);
32 if (err)
33 printf("%-40s: %sFAILED (%d, %s)\n", msg, supported?"":"X", errno, errmsg);
34 else if (!expected || hwloc_bitmap_isequal(expected, result))
35 printf("%-40s: OK\n", msg);
36 else {
37 char *expected_s, *result_s;
38 hwloc_bitmap_asprintf(&expected_s, expected);
39 hwloc_bitmap_asprintf(&result_s, result);
40 printf("%-40s: expected %s, got %s\n", msg, expected_s, result_s);
41 free(expected_s);
42 free(result_s);
43 }
44 }
45
test(hwloc_const_bitmap_t cpuset,int flags)46 static void test(hwloc_const_bitmap_t cpuset, int flags)
47 {
48 hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
49 result_set("Bind this singlethreaded process", hwloc_set_cpubind(topology, cpuset, flags), support->cpubind->set_thisproc_cpubind || support->cpubind->set_thisthread_cpubind);
50 result_get("Get this singlethreaded process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags), support->cpubind->get_thisproc_cpubind || support->cpubind->get_thisthread_cpubind);
51 result_set("Bind this thread", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thisthread_cpubind);
52 result_get("Get this thread", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thisthread_cpubind);
53 result_set("Bind this whole process", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_thisproc_cpubind);
54 result_get("Get this whole process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_thisproc_cpubind);
55
56 #ifdef HWLOC_WIN_SYS
57 result_set("Bind process", hwloc_set_proc_cpubind(topology, GetCurrentProcess(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
58 result_get("Get process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, GetCurrentProcess(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
59 result_set("Bind thread", hwloc_set_thread_cpubind(topology, GetCurrentThread(), cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thread_cpubind);
60 result_get("Get thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, GetCurrentThread(), new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thread_cpubind);
61 #else /* !HWLOC_WIN_SYS */
62 result_set("Bind whole process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
63 result_get("Get whole process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
64 result_set("Bind process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags), support->cpubind->set_proc_cpubind);
65 result_get("Get process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags), support->cpubind->get_proc_cpubind);
66 #ifdef hwloc_thread_t
67 result_set("Bind thread", hwloc_set_thread_cpubind(topology, pthread_self(), cpuset, flags), support->cpubind->set_thread_cpubind);
68 result_get("Get thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, pthread_self(), new_cpuset, flags), support->cpubind->get_thread_cpubind);
69 #endif
70 #endif /* !HWLOC_WIN_SYS */
71 printf("\n");
72 hwloc_bitmap_free(new_cpuset);
73 }
74
testmem(hwloc_const_bitmap_t nodeset,hwloc_membind_policy_t policy,int flags,int expected)75 static void testmem(hwloc_const_bitmap_t nodeset, hwloc_membind_policy_t policy, int flags, int expected)
76 {
77 hwloc_bitmap_t new_nodeset = hwloc_bitmap_alloc();
78 hwloc_membind_policy_t newpolicy;
79 void *area;
80 size_t area_size = 1024;
81
82 result_set("Bind this singlethreaded process memory", hwloc_set_membind(topology, nodeset, policy, flags), (support->membind->set_thisproc_membind || support->membind->set_thisthread_membind) && expected);
83 result_get("Get this singlethreaded process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags), (support->membind->get_thisproc_membind || support->membind->get_thisthread_membind) && expected);
84
85 result_set("Bind this thread memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_THREAD), support->membind->set_thisproc_membind && expected);
86 result_get("Get this thread memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_THREAD), support->membind->get_thisproc_membind && expected);
87
88 result_set("Bind this whole process memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_PROCESS), support->membind->set_thisproc_membind && expected);
89 result_get("Get this whole process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_PROCESS), support->membind->get_thisproc_membind && expected);
90
91 #ifdef HWLOC_WIN_SYS
92 result_set("Bind process memory", hwloc_set_proc_membind(topology, GetCurrentProcess(), nodeset, policy, flags), support->membind->set_proc_membind && expected);
93 result_get("Get process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, GetCurrentProcess(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected);
94 #else /* !HWLOC_WIN_SYS */
95 result_set("Bind process memory", hwloc_set_proc_membind(topology, getpid(), nodeset, policy, flags), support->membind->set_proc_membind && expected);
96 result_get("Get process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, getpid(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected);
97 #endif /* !HWLOC_WIN_SYS */
98
99 result_set("Bind area", hwloc_set_area_membind(topology, &new_nodeset, sizeof(new_nodeset), nodeset, policy, flags), support->membind->set_area_membind && expected);
100 result_get("Get area", nodeset, new_nodeset, hwloc_get_area_membind(topology, &new_nodeset, sizeof(new_nodeset), new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected);
101
102 if (!(flags & HWLOC_MEMBIND_MIGRATE)) {
103 result_set("Alloc bound area", (area = hwloc_alloc_membind(topology, area_size, nodeset, policy, flags)) == NULL, (support->membind->alloc_membind && expected) || !(flags & HWLOC_MEMBIND_STRICT));
104 if (area) {
105 memset(area, 0, area_size);
106 result_get("Get bound area", nodeset, new_nodeset, hwloc_get_area_membind(topology, area, area_size, new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected);
107 result_get("Free bound area", NULL, NULL, hwloc_free(topology, area, area_size), support->membind->alloc_membind && expected);
108 }
109
110 result_set("Alloc bound area through policy", (area = hwloc_alloc_membind_policy(topology, area_size, nodeset, policy, flags)) == NULL, (support->membind->set_thisproc_membind && expected) || !(flags & HWLOC_MEMBIND_STRICT));
111 if (area) {
112 memset(area, 0, area_size);
113 result_get("Get bound area", nodeset, new_nodeset, hwloc_get_area_membind(topology, area, area_size, new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected);
114 result_get("Free bound area", NULL, NULL, hwloc_free(topology, area, area_size), support->membind->alloc_membind && expected);
115 }
116 }
117 printf("\n");
118 hwloc_bitmap_free(new_nodeset);
119 }
120
testmem2(hwloc_const_bitmap_t set,int flags)121 static void testmem2(hwloc_const_bitmap_t set, int flags)
122 {
123 printf(" default\n");
124 testmem(set, HWLOC_MEMBIND_DEFAULT, flags, 1);
125 printf(" firsttouch\n");
126 testmem(set, HWLOC_MEMBIND_FIRSTTOUCH, flags, support->membind->firsttouch_membind);
127 printf(" bound\n");
128 testmem(set, HWLOC_MEMBIND_BIND, flags, support->membind->bind_membind);
129 printf(" interleave\n");
130 testmem(set, HWLOC_MEMBIND_INTERLEAVE, flags, support->membind->interleave_membind);
131 printf(" nexttouch\n");
132 testmem(set, HWLOC_MEMBIND_NEXTTOUCH, flags, support->membind->nexttouch_membind);
133 }
134
testmem3(hwloc_const_bitmap_t set)135 static void testmem3(hwloc_const_bitmap_t set)
136 {
137 testmem2(set, 0);
138 printf("now strict\n\n");
139 testmem2(set, HWLOC_MEMBIND_STRICT);
140 printf("now migrate\n\n");
141 testmem2(set, HWLOC_MEMBIND_MIGRATE);
142 printf("now strictly migrate\n\n");
143 testmem2(set, HWLOC_MEMBIND_STRICT | HWLOC_MEMBIND_MIGRATE);
144 }
145
main(void)146 int main(void)
147 {
148 hwloc_bitmap_t set;
149 hwloc_obj_t obj;
150 char *str = NULL;
151
152 hwloc_topology_init(&topology);
153 hwloc_topology_load(topology);
154
155 support = hwloc_topology_get_support(topology);
156
157 obj = hwloc_get_root_obj(topology);
158 set = hwloc_bitmap_dup(obj->cpuset);
159
160 while (hwloc_bitmap_isequal(obj->cpuset, set)) {
161 if (!obj->arity)
162 break;
163 obj = obj->children[0];
164 }
165
166 hwloc_bitmap_asprintf(&str, set);
167 printf("system set is %s\n", str);
168 free(str);
169
170 test(set, 0);
171 printf("now strict\n");
172 test(set, HWLOC_CPUBIND_STRICT);
173
174 hwloc_bitmap_free(set);
175 set = hwloc_bitmap_dup(obj->cpuset);
176 hwloc_bitmap_asprintf(&str, set);
177 printf("obj set is %s\n", str);
178 free(str);
179
180 test(set, 0);
181 printf("now strict\n");
182 test(set, HWLOC_CPUBIND_STRICT);
183
184 hwloc_bitmap_singlify(set);
185 hwloc_bitmap_asprintf(&str, set);
186 printf("singlified to %s\n", str);
187 free(str);
188
189 test(set, 0);
190 printf("now strict\n");
191 test(set, HWLOC_CPUBIND_STRICT);
192 hwloc_bitmap_free(set);
193
194 printf("\n\nmemory tests\n\n");
195 printf("complete node set\n");
196 set = hwloc_bitmap_dup(hwloc_get_root_obj(topology)->cpuset);
197 hwloc_bitmap_asprintf(&str, set);
198 printf("i.e. cpuset %s\n", str);
199 free(str);
200 testmem3(set);
201 hwloc_bitmap_free(set);
202
203 obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 0);
204 assert(obj);
205 set = hwloc_bitmap_dup(obj->cpuset);
206 hwloc_bitmap_asprintf(&str, set);
207 printf("cpuset set is %s\n", str);
208 free(str);
209
210 testmem3(set);
211
212 obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 1);
213 if (obj) {
214 hwloc_bitmap_or(set, set, obj->cpuset);
215 hwloc_bitmap_asprintf(&str, set);
216 printf("cpuset set is %s\n", str);
217 free(str);
218
219 testmem3(set);
220 }
221 hwloc_bitmap_free(set);
222
223 hwloc_topology_destroy(topology);
224 return 0;
225 }
226