enum topo_level { TOPO_LEVEL_PKG = 0, TOPO_LEVEL_GROUP = 1, TOPO_LEVEL_CACHEGROUP = 2, TOPO_LEVEL_CORE = 3, TOPO_LEVEL_COUNT = 4, }; struct topo_analysis { ... int children[TOPO_LEVEL_COUNT]; }; static bool _topo_analyze(struct topo_node *node, int all, enum topo_level level, struct topo_analysis *res) { struct topo_node *curr; int *children, count; bool next; count = 0; curr = topo_next_node(node, node); while (curr != NULL) { switch (level) { case TOPO_LEVEL_PKG: next = curr->type != TOPO_TYPE_GROUP; break; case TOPO_LEVEL_GROUP: next = curr->type != TOPO_TYPE_CACHE || curr->subtype != CG_SHARE_L3; break; case TOPO_LEVEL_CACHEGROUP: next = curr->type != TOPO_TYPE_CORE; break; case TOPO_LEVEL_CORE: next = curr->type != TOPO_TYPE_PU; break; } if (next) { curr = topo_next_node(node, curr); continue; } if (!all && CPU_EMPTY(&curr->cpuset)) { curr = topo_next_nonchild_node(node, curr); continue; } count++; if (level < TOPO_LEVEL_CORE && !_topo_analyze(curr, all, level + 1, res)) return (false); curr = topo_next_nonchild_node(node, curr); } if (count == 0) { count = 1; if (level < TOPO_LEVEL_CORE && !_topo_analyze(node, all, level + 1, res)) return (false); } children = &res->children[level]; if (*children == -1) *children = count; else if (*children != count) return (false); return (true); } static bool topo_analyze(struct topo_node *node, int all, struct topo_analysis *res) { return (_topo_analysis(node, all, TOPO_LEVEL_PKG, res)); }