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