diff -r f2cdbf31ce9b source/lib/sysdep/arch/x86_x64/topology.cpp --- source/lib/sysdep/arch/x86_x64/topology.cpp Sat Jul 10 18:42:54 2010 +0100 +++ source/lib/sysdep/arch/x86_x64/topology.cpp Sat Jul 24 22:34:51 2010 +0100 @@ -137,18 +137,24 @@ // core, package and shared cache. if they are available, we can determine // the exact topology; otherwise we have to guess. -// side effect: `removes' (via std::unique) duplicate IDs. -static bool AreApicIdsUnique(u8* apicIds, size_t numProcessors) +// if false is returned, the APIC IDs are fishy and shouldn't be used. +// side effect: sorts IDs and `removes' (via std::unique) duplicates. +static bool AreApicIdsUnique(u8* apicIds, size_t numIds) { - u8* const end = std::unique(apicIds, apicIds+numProcessors); - const size_t numIds = end-apicIds; - if(numIds == numProcessors) // all unique + std::sort(apicIds, apicIds+numIds); + u8* const end = std::unique(apicIds, apicIds+numIds); + const size_t numUnique = end-apicIds; + // all unique => IDs are valid. + if(numUnique == numIds) return true; - // the only legitimate cause of duplication is when no xAPIC is - // present (i.e. all are 0) - debug_assert(numIds == 1); - debug_assert(apicIds[0] == 0); + // all zero => the system lacks an xAPIC. + if(numUnique == 1 && apicIds[0] == 0) + return false; + + // duplicated IDs => something went wrong. for example, VMs might not + // expose all physical processors, and OS X still doesn't support + // thread affinity masks. return false; } @@ -245,7 +251,8 @@ // assume cores are enabled and count as processors. const size_t numPackagesTimesLogical = os_cpu_NumProcessors() / CoresPerPackage(); - debug_assert(numPackagesTimesLogical != 0); + // note: this might give numPackagesTimesLogical == 0 (e.g. when running in some VMs) + // assume hyperthreads are enabled. size_t numPackages = numPackagesTimesLogical; // if they are reported as processors, remove them from the count.