00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00038 #ifndef TOPOLOGY_HELPER_H
00039 #define TOPOLOGY_HELPER_H
00040
00041 #ifndef TOPOLOGY_H
00042 #error Please include the main topology.h instead
00043 #endif
00044
00045
00046
00057 static __inline__ unsigned
00058 topo_get_type_or_below_depth (topo_topology_t topology, topo_obj_type_t type)
00059 {
00060 unsigned depth = topo_get_type_depth(topology, type);
00061 unsigned minorder = topo_get_type_order(type);
00062
00063 if (depth != TOPO_TYPE_DEPTH_UNKNOWN)
00064 return depth;
00065
00066
00067 for(depth = topo_get_type_depth(topology, TOPO_OBJ_PROC); ; depth--)
00068 if (topo_get_type_order(topo_get_depth_type(topology, depth)) < minorder)
00069 return depth+1;
00070
00071
00072 abort();
00073 }
00074
00081 static __inline__ unsigned
00082 topo_get_type_or_above_depth (topo_topology_t topology, topo_obj_type_t type)
00083 {
00084 unsigned depth = topo_get_type_depth(topology, type);
00085 unsigned maxorder = topo_get_type_order(type);
00086
00087 if (depth != TOPO_TYPE_DEPTH_UNKNOWN)
00088 return depth;
00089
00090
00091 for(depth = 0; ; depth++)
00092 if (topo_get_type_order(topo_get_depth_type(topology, depth)) > maxorder)
00093 return depth-1;
00094
00095
00096 abort();
00097 }
00098
00104 static __inline__ int
00105 topo_get_type_nbobjs (topo_topology_t topology, topo_obj_type_t type)
00106 {
00107 unsigned depth = topo_get_type_depth(topology, type);
00108 if (depth == TOPO_TYPE_DEPTH_UNKNOWN)
00109 return 0;
00110 if (depth == TOPO_TYPE_DEPTH_MULTIPLE)
00111 return -1;
00112 return topo_get_depth_nbobjs(topology, depth);
00113 }
00114
00124 static __inline__ topo_obj_t
00125 topo_get_system_obj (topo_topology_t topology)
00126 {
00127 return topo_get_obj_by_depth (topology, 0, 0);
00128 }
00129
00136 static __inline__ topo_obj_t
00137 topo_get_obj (topo_topology_t topology, topo_obj_type_t type, unsigned index)
00138 {
00139 unsigned depth = topo_get_type_depth(topology, type);
00140 if (depth == TOPO_TYPE_DEPTH_UNKNOWN)
00141 return NULL;
00142 if (depth == TOPO_TYPE_DEPTH_MULTIPLE)
00143 return NULL;
00144 return topo_get_obj_by_depth(topology, depth, index);
00145 }
00146
00151 static __inline__ topo_obj_t
00152 topo_get_next_obj_by_depth (topo_topology_t topology, unsigned depth, topo_obj_t prev)
00153 {
00154 if (!prev)
00155 return topo_get_obj_by_depth (topology, depth, 0);
00156 if (prev->depth != depth)
00157 return NULL;
00158 return prev->next_cousin;
00159 }
00160
00167 static __inline__ topo_obj_t
00168 topo_get_next_obj (topo_topology_t topology, topo_obj_type_t type,
00169 topo_obj_t prev)
00170 {
00171 unsigned depth = topo_get_type_depth(topology, type);
00172 if (depth == TOPO_TYPE_DEPTH_UNKNOWN || depth == TOPO_TYPE_DEPTH_MULTIPLE)
00173 return NULL;
00174 return topo_get_next_obj_by_depth (topology, depth, prev);
00175 }
00176
00181 static __inline__ topo_obj_t
00182 topo_get_next_child (topo_topology_t topology, topo_obj_t father, topo_obj_t prev)
00183 {
00184 if (!prev)
00185 return father->first_child;
00186 if (prev->father != father)
00187 return NULL;
00188 return prev->next_sibling;
00189 }
00190
00192 static __inline__ topo_obj_t
00193 topo_get_common_ancestor_obj (topo_obj_t obj1, topo_obj_t obj2)
00194 {
00195 while (obj1->depth > obj2->depth)
00196 obj1 = obj1->father;
00197 while (obj2->depth > obj1->depth)
00198 obj2 = obj2->father;
00199 while (obj1 != obj2) {
00200 obj1 = obj1->father;
00201 obj2 = obj2->father;
00202 }
00203 return obj1;
00204 }
00205
00208 static __inline__ int
00209 topo_obj_is_in_subtree (topo_obj_t obj, topo_obj_t subtree_root)
00210 {
00211 return topo_cpuset_isincluded(&obj->cpuset, &subtree_root->cpuset);
00212 }
00213
00228 static __inline__ topo_obj_t
00229 topo_get_next_obj_below_cpuset_by_depth (topo_topology_t topology, const topo_cpuset_t *set,
00230 unsigned depth, topo_obj_t prev)
00231 {
00232 topo_obj_t next = topo_get_next_obj_by_depth(topology, depth, prev);
00233 while (next && !topo_cpuset_isincluded(&next->cpuset, set))
00234 next = next->next_cousin;
00235 return next;
00236 }
00237
00243 static __inline__ topo_obj_t
00244 topo_get_next_obj_below_cpuset (topo_topology_t topology, const topo_cpuset_t *set,
00245 topo_obj_type_t type, topo_obj_t prev)
00246 {
00247 unsigned depth = topo_get_type_depth(topology, type);
00248 if (depth == TOPO_TYPE_DEPTH_UNKNOWN || depth == TOPO_TYPE_DEPTH_MULTIPLE)
00249 return NULL;
00250 return topo_get_next_obj_below_cpuset_by_depth(topology, set, depth, prev);
00251 }
00252
00255 static __inline__ topo_obj_t
00256 topo_get_obj_below_cpuset_by_depth (topo_topology_t topology, const topo_cpuset_t *set,
00257 unsigned depth, unsigned index)
00258 {
00259 int count = 0;
00260 topo_obj_t obj = topo_get_obj_by_depth (topology, depth, 0);
00261 while (obj) {
00262 if (topo_cpuset_isincluded(&obj->cpuset, set)) {
00263 if (count == index)
00264 return obj;
00265 count++;
00266 }
00267 obj = obj->next_cousin;
00268 }
00269 return NULL;
00270 }
00271
00277 static __inline__ topo_obj_t
00278 topo_get_obj_below_cpuset (topo_topology_t topology, const topo_cpuset_t *set,
00279 topo_obj_type_t type, unsigned index)
00280 {
00281 unsigned depth = topo_get_type_depth(topology, type);
00282 if (depth == TOPO_TYPE_DEPTH_UNKNOWN || depth == TOPO_TYPE_DEPTH_MULTIPLE)
00283 return NULL;
00284 return topo_get_obj_below_cpuset_by_depth(topology, set, depth, index);
00285 }
00286
00288 static __inline__ unsigned
00289 topo_get_nbobjs_below_cpuset_by_depth (topo_topology_t topology, const topo_cpuset_t *set,
00290 unsigned depth)
00291 {
00292 topo_obj_t obj = topo_get_obj_by_depth (topology, depth, 0);
00293 int count = 0;
00294 while (obj) {
00295 if (topo_cpuset_isincluded(&obj->cpuset, set))
00296 count++;
00297 obj = obj->next_cousin;
00298 }
00299 return count;
00300 }
00301
00307 static __inline__ int
00308 topo_get_nbobjs_below_cpuset (topo_topology_t topology, const topo_cpuset_t *set,
00309 topo_obj_type_t type)
00310 {
00311 unsigned depth = topo_get_type_depth(topology, type);
00312 if (depth == TOPO_TYPE_DEPTH_UNKNOWN)
00313 return 0;
00314 if (depth == TOPO_TYPE_DEPTH_MULTIPLE)
00315 return -1;
00316 return topo_get_nbobjs_below_cpuset_by_depth(topology, set, depth);
00317 }
00318
00331 static inline topo_obj_t
00332 topo_get_cpuset_covering_child (topo_topology_t topology, const topo_cpuset_t *set,
00333 topo_obj_t father)
00334 {
00335 topo_obj_t child = father->first_child;
00336 while (child) {
00337 if (topo_cpuset_isincluded(set, &child->cpuset))
00338 return child;
00339 child = child->next_sibling;
00340 }
00341 return NULL;
00342 }
00343
00348 static inline topo_obj_t
00349 topo_get_cpuset_covering_obj (topo_topology_t topology, const topo_cpuset_t *set)
00350 {
00351 struct topo_obj *current = topo_get_system_obj(topology);
00352
00353 if (!topo_cpuset_isincluded(set, ¤t->cpuset))
00354 return NULL;
00355
00356 while (1) {
00357 topo_obj_t child = topo_get_cpuset_covering_child(topology, set, current);
00358 if (!child)
00359 return current;
00360 current = child;
00361 }
00362 }
00363
00364
00380 static __inline__ topo_obj_t
00381 topo_get_next_obj_above_cpuset_by_depth(topo_topology_t topology, const topo_cpuset_t *set,
00382 unsigned depth, topo_obj_t prev)
00383 {
00384 topo_obj_t next = topo_get_next_obj_by_depth(topology, depth, prev);
00385 while (next && !topo_cpuset_intersects(set, &next->cpuset))
00386 next = next->next_cousin;
00387 return next;
00388 }
00389
00401 static __inline__ topo_obj_t
00402 topo_get_next_obj_above_cpuset(topo_topology_t topology, const topo_cpuset_t *set,
00403 topo_obj_type_t type, topo_obj_t prev)
00404 {
00405 unsigned depth = topo_get_type_depth(topology, type);
00406 if (depth == TOPO_TYPE_DEPTH_UNKNOWN || depth == TOPO_TYPE_DEPTH_MULTIPLE)
00407 return NULL;
00408 return topo_get_next_obj_above_cpuset_by_depth(topology, set, depth, prev);
00409 }
00410
00423 static __inline__ topo_obj_t
00424 topo_get_cpuset_covering_cache (topo_topology_t topology, const topo_cpuset_t *set)
00425 {
00426 topo_obj_t current = topo_get_cpuset_covering_obj(topology, set);
00427 while (current) {
00428 if (current->type == TOPO_OBJ_CACHE)
00429 return current;
00430 current = current->father;
00431 }
00432 return NULL;
00433 }
00434
00439 static __inline__ topo_obj_t
00440 topo_get_shared_cache_above (topo_topology_t topology, topo_obj_t obj)
00441 {
00442 topo_obj_t current = obj->father;
00443 while (current) {
00444 if (!topo_cpuset_isequal(¤t->cpuset, &obj->cpuset)
00445 && current->type == TOPO_OBJ_CACHE)
00446 return current;
00447 current = current->father;
00448 }
00449 return NULL;
00450 }
00451
00464 extern int topo_get_cpuset_objs (topo_topology_t topology, const topo_cpuset_t *set,
00465 topo_obj_t * __topo_restrict objs, int max);
00466
00474
00475 extern int topo_get_closest_objs (topo_topology_t topology, topo_obj_t src, topo_obj_t * __topo_restrict objs, int max);
00476
00495 static __inline__ void
00496 topo_distribute(topo_topology_t topology, topo_obj_t root, topo_cpuset_t *cpuset, int n)
00497 {
00498 int i;
00499 int chunk_size, complete_chunks;
00500 topo_cpuset_t *cpusetp;
00501
00502 if (!root->arity || n == 1) {
00503
00504 for (i=0; i<n; i++)
00505 cpuset[i] = root->cpuset;
00506 return;
00507 }
00508
00509
00510 chunk_size = (n + root->arity - 1) / root->arity;
00511 complete_chunks = n % root->arity;
00512 if (!complete_chunks)
00513 complete_chunks = root->arity;
00514
00515
00516 for (cpusetp = cpuset, i = 0;
00517 i < complete_chunks;
00518 i ++, cpusetp += chunk_size)
00519 topo_distribute(topology, root->children[i], cpusetp, chunk_size);
00520
00521
00522 for ( ;
00523 i < root->arity;
00524 i++, cpusetp += chunk_size-1)
00525 topo_distribute(topology, root->children[i], cpusetp, chunk_size-1);
00526 }
00527
00528
00529 #endif