static uint32 assign_cpu(void) { const cpu_topology_node* node; do { int32 nextID = atomic_add(&sLastCPU, 1); node = get_cpu_topology(); while (node->level != CPU_TOPOLOGY_SMT) { int levelSize = node->children_count; node = node->children[nextID % levelSize]; nextID /= levelSize; } } while (gCPU[node->id].disabled); return node->id; }
status_t _user_get_cpu_topology_info(cpu_topology_node_info* topologyInfos, uint32* topologyInfoCount) { if (topologyInfoCount == NULL || !IS_USER_ADDRESS(topologyInfoCount)) return B_BAD_ADDRESS; const cpu_topology_node* node = get_cpu_topology(); uint32 count = 0; count_topology_nodes(node, count); if (topologyInfos == NULL) return user_memcpy(topologyInfoCount, &count, sizeof(uint32)); else if (!IS_USER_ADDRESS(topologyInfoCount)) return B_BAD_ADDRESS; uint32 userCount; status_t error = user_memcpy(&userCount, topologyInfoCount, sizeof(uint32)); if (error != B_OK) return error; if (userCount == 0) return B_OK; count = std::min(count, userCount); cpu_topology_node_info* topology = new(std::nothrow) cpu_topology_node_info[count]; if (topology == NULL) return B_NO_MEMORY; ArrayDeleter<cpu_topology_node_info> _(topology); memset(topology, 0, sizeof(cpu_topology_node_info) * count); uint32 nodesLeft = count; generate_topology_array(topology, node, nodesLeft); ASSERT(nodesLeft == 0); error = user_memcpy(topologyInfos, topology, sizeof(cpu_topology_node_info) * count); if (error != B_OK) return error; return user_memcpy(topologyInfoCount, &count, sizeof(uint32)); }