1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2018 Inria. All rights reserved.
4 * Copyright © 2009-2012 Université Bordeaux
5 * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
8
9 /**
10 * This file contains the inline code of functions declared in hwloc.h
11 */
12
13 #ifndef HWLOC_INLINES_H
14 #define HWLOC_INLINES_H
15
16 #ifndef HWLOC_H
17 #error Please include the main hwloc.h instead
18 #endif
19
20 #include <stdlib.h>
21 #include <errno.h>
22
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 static __hwloc_inline int
hwloc_get_type_or_below_depth(hwloc_topology_t topology,hwloc_obj_type_t type)29 hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
30 {
31 int depth = hwloc_get_type_depth(topology, type);
32
33 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN || type == HWLOC_OBJ_MISC)
34 return depth;
35
36 /* find the highest existing level with type order >= */
37 for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
38 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
39 return depth+1;
40
41 /* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth. */
42 /* abort(); */
43 }
44
45 static __hwloc_inline int
hwloc_get_type_or_above_depth(hwloc_topology_t topology,hwloc_obj_type_t type)46 hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
47 {
48 int depth = hwloc_get_type_depth(topology, type);
49
50 if (depth != HWLOC_TYPE_DEPTH_UNKNOWN || type == HWLOC_OBJ_MISC)
51 return depth;
52
53 /* find the lowest existing level with type order <= */
54 for(depth = 0; ; depth++)
55 if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
56 return depth-1;
57
58 /* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
59 /* abort(); */
60 }
61
62 static __hwloc_inline int
hwloc_get_nbobjs_by_type(hwloc_topology_t topology,hwloc_obj_type_t type)63 hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
64 {
65 int depth = hwloc_get_type_depth(topology, type);
66 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
67 return 0;
68 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
69 return -1; /* FIXME: agregate nbobjs from different levels? */
70 return hwloc_get_nbobjs_by_depth(topology, depth);
71 }
72
73 static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type(hwloc_topology_t topology,hwloc_obj_type_t type,unsigned idx)74 hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
75 {
76 int depth = hwloc_get_type_depth(topology, type);
77 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
78 return NULL;
79 if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
80 return NULL;
81 return hwloc_get_obj_by_depth(topology, depth, idx);
82 }
83
84 static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth(hwloc_topology_t topology,unsigned depth,hwloc_obj_t prev)85 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
86 {
87 if (!prev)
88 return hwloc_get_obj_by_depth (topology, depth, 0);
89 if (prev->depth != depth)
90 return NULL;
91 return prev->next_cousin;
92 }
93
94 static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type(hwloc_topology_t topology,hwloc_obj_type_t type,hwloc_obj_t prev)95 hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
96 hwloc_obj_t prev)
97 {
98 int depth = hwloc_get_type_depth(topology, type);
99 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
100 return NULL;
101 return hwloc_get_next_obj_by_depth (topology, depth, prev);
102 }
103
104 static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj(hwloc_topology_t topology)105 hwloc_get_root_obj (hwloc_topology_t topology)
106 {
107 return hwloc_get_obj_by_depth (topology, 0, 0);
108 }
109
110 static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj,const char * name)111 hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
112 {
113 unsigned i;
114 for(i=0; i<obj->infos_count; i++)
115 if (!strcmp(obj->infos[i].name, name))
116 return obj->infos[i].value;
117 return NULL;
118 }
119
120 static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology,size_t len,hwloc_const_nodeset_t nodeset,hwloc_membind_policy_t policy,int flags)121 hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
122 {
123 void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
124 if (p)
125 return p;
126 hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
127 p = hwloc_alloc(topology, len);
128 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
129 /* Enforce the binding by touching the data */
130 memset(p, 0, len);
131 return p;
132 }
133
134 static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology,size_t len,hwloc_const_cpuset_t set,hwloc_membind_policy_t policy,int flags)135 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
136 {
137 void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
138 if (p)
139 return p;
140
141 if (hwloc_set_membind(topology, set, policy, flags) < 0)
142 /* hwloc_set_membind() takes care of ignoring errors if non-STRICT */
143 return NULL;
144
145 p = hwloc_alloc(topology, len);
146 if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
147 /* Enforce the binding by touching the data */
148 memset(p, 0, len);
149 return p;
150 }
151
152
153 #ifdef __cplusplus
154 } /* extern "C" */
155 #endif
156
157
158 #endif /* HWLOC_INLINES_H */
159