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)
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 Machine 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)
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 (int) 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,int depth,hwloc_obj_t prev)85 hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int 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     struct hwloc_info_s *info = &obj->infos[i];
116     if (!strcmp(info->name, name))
117       return info->value;
118   }
119   return NULL;
120 }
121 
122 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)123 hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
124 {
125   void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
126   if (p)
127     return p;
128 
129   if (hwloc_set_membind(topology, set, policy, flags) < 0)
130     /* hwloc_set_membind() takes care of ignoring errors if non-STRICT */
131     return NULL;
132 
133   p = hwloc_alloc(topology, len);
134   if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
135     /* Enforce the binding by touching the data */
136     memset(p, 0, len);
137   return p;
138 }
139 
140 
141 #ifdef __cplusplus
142 } /* extern "C" */
143 #endif
144 
145 
146 #endif /* HWLOC_INLINES_H */
147