-
Notifications
You must be signed in to change notification settings - Fork 168
/
topology-netbsd.c
218 lines (188 loc) · 6.36 KB
/
topology-netbsd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
* Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
* Copyright © 2009-2023 Inria. All rights reserved.
* Copyright © 2009-2010, 2020 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#define _NETBSD_SOURCE /* request "_np" functions */
#include "private/autogen/config.h"
#include <sys/types.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/param.h>
#include <pthread.h>
#include <sched.h>
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include "hwloc.h"
#include "private/private.h"
#include "private/debug.h"
static void
hwloc_netbsd_bsd2hwloc(hwloc_bitmap_t hwloc_cpuset, const cpuset_t *cpuset)
{
unsigned cpu, cpulimit;
int found = 0;
hwloc_bitmap_zero(hwloc_cpuset);
cpulimit = cpuset_size(cpuset) * CHAR_BIT;
for (cpu = 0; cpu < cpulimit; cpu++)
if (cpuset_isset(cpu, cpuset)) {
hwloc_bitmap_set(hwloc_cpuset, cpu);
found++;
}
/* when never bound, it returns an empty set, fill it instead */
if (!found)
hwloc_bitmap_fill(hwloc_cpuset);
}
static void
hwloc_netbsd_hwloc2bsd(hwloc_const_bitmap_t hwloc_cpuset, cpuset_t *cpuset)
{
unsigned cpu, cpulimit;
cpuset_zero(cpuset);
cpulimit = cpuset_size(cpuset) * CHAR_BIT;
for (cpu = 0; cpu < cpulimit; cpu++)
if (hwloc_bitmap_isset(hwloc_cpuset, cpu))
cpuset_set(cpu, cpuset);
}
static int
hwloc_netbsd_set_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
hwloc_netbsd_hwloc2bsd(hwloc_cpuset, cpuset);
status = sched_setaffinity_np(pid, cpuset_size(cpuset), cpuset);
cpuset_destroy(cpuset);
return status;
}
static int
hwloc_netbsd_get_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
status = sched_getaffinity_np(pid, cpuset_size(cpuset), cpuset);
hwloc_netbsd_bsd2hwloc(hwloc_cpuset, cpuset);
cpuset_destroy(cpuset);
return status;
}
static int
hwloc_netbsd_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_set_proc_cpubind(topology, 0, hwloc_cpuset, flags);
}
static int
hwloc_netbsd_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_get_proc_cpubind(topology, 0, hwloc_cpuset, flags);
}
static int
hwloc_netbsd_set_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
hwloc_netbsd_hwloc2bsd(hwloc_cpuset, cpuset);
status = pthread_setaffinity_np(tid, cpuset_size(cpuset), cpuset);
cpuset_destroy(cpuset);
if (status) {
errno = status;
return -1;
}
return 0;
}
static int
hwloc_netbsd_get_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
status = pthread_getaffinity_np(tid, cpuset_size(cpuset), cpuset);
hwloc_netbsd_bsd2hwloc(hwloc_cpuset, cpuset);
cpuset_destroy(cpuset);
if (status) {
errno = status;
return -1;
}
return 0;
}
static int
hwloc_netbsd_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_set_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags);
}
static int
hwloc_netbsd_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_get_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags);
}
static int
hwloc_look_netbsd(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus)
{
/*
* This backend uses the underlying OS.
* However we don't enforce topology->is_thissystem so that
* we may still force use this backend when debugging with !thissystem.
*/
struct hwloc_topology *topology = backend->topology;
int64_t memsize;
assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);
if (!topology->levels[0][0]->cpuset) {
/* Nobody (even the x86 backend) created objects yet, setup basic objects */
int nbprocs = hwloc_fallback_nbprocessors(0);
if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs);
}
memsize = hwloc_fallback_memsize();
if (memsize > 0)
topology->machine_memory.local_memory = memsize;;
/* Add NetBSD specific information */
hwloc__add_info(&topology->infos, "Backend", "NetBSD");
hwloc_add_uname_info(topology, NULL);
return 0;
}
void
hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_netbsd_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_netbsd_get_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_netbsd_set_thisproc_cpubind;
hooks->get_thisproc_cpubind = hwloc_netbsd_get_thisproc_cpubind;
hooks->set_thread_cpubind = hwloc_netbsd_set_thread_cpubind;
hooks->get_thread_cpubind = hwloc_netbsd_get_thread_cpubind;
hooks->set_thisthread_cpubind = hwloc_netbsd_set_thisthread_cpubind;
hooks->get_thisthread_cpubind = hwloc_netbsd_get_thisthread_cpubind;
}
static struct hwloc_backend *
hwloc_netbsd_component_instantiate(struct hwloc_topology *topology,
struct hwloc_disc_component *component,
unsigned excluded_phases __hwloc_attribute_unused,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(topology, component, 0);
if (!backend)
return NULL;
backend->discover = hwloc_look_netbsd;
return backend;
}
static struct hwloc_disc_component hwloc_netbsd_disc_component = {
"netbsd",
HWLOC_DISC_PHASE_CPU,
HWLOC_DISC_PHASE_GLOBAL,
hwloc_netbsd_component_instantiate,
50,
1,
NULL
};
const struct hwloc_component hwloc_netbsd_component = {
HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_netbsd_disc_component
};