1
0
forked from 0ad/0ad

add code to check if system is SMP (needed for wtime; not trivial, since hyperthreading may be in play)

This was SVN commit r588.
This commit is contained in:
janwas 2004-06-22 17:20:38 +00:00
parent 4c2463d7c3
commit d633fd201d
4 changed files with 46 additions and 9 deletions

View File

@ -13,6 +13,13 @@ extern int cpu_smp;
// are there actually multiple physical processors,
// not only logical hyperthreaded CPUs? relevant for wtime.
// set cpu_smp if there's more than 1 physical CPU -
// need to know this for wtime's TSC safety check.
// call on each processor (via on_each_cpu).
extern void cpu_check_smp();
#ifdef __cplusplus
}
#endif

View File

@ -399,20 +399,36 @@ int get_cur_processor_id()
}
static void check_hyperthread()
// set cpu_smp if there's more than 1 physical CPU -
// need to know this for wtime's TSC safety check.
// call on each processor (via on_each_cpu).
void cpu_check_smp()
{
assert(cpus > 0 && "must know # CPUs (call OS-specific detect first)");
cpu_smp = 0;
// we don't check if it's Intel and P4 or above - HT may be supported
// on other CPUs in future. haven't come across a processor that
// incorrectly sets the HT feature bit.
if(!ia32_cap(HT))
{
// no HT supported, just check number of CPUs as reported by OS.
cpu_smp = (cpus > 1);
return;
}
// first call. we set cpu_smp below if more than 1 physical CPU is found,
// so clear it until then.
if(cpu_smp == -1)
cpu_smp = 0;
//
// still need to check if HT is actually enabled (BIOS and OS);
// there might be 2 CPUs with HT supported but disabled.
//
// get number of logical CPUs per package
// (the same for all packages on this system)
int log_cpus_per_package;
__asm {
push 1
@ -423,7 +439,16 @@ static void check_hyperthread()
mov log_cpus_per_package, ebx ; ebx[23:16]
}
cpu_smp = 1;
// logical CPUs are initialized after one another =>
// they have the same physical ID.
const int id = get_cur_processor_id();
const int phys_shift = log2(log_cpus_per_package);
const int phys_id = id >> phys_shift;
// more than 1 physical CPU found
static int last_phys_id = -1;
if(last_phys_id != phys_id)
cpu_smp = 1;
}
@ -448,7 +473,6 @@ void ia32_get_cpu_info()
get_cpu_type();
measure_cpu_freq();
check_hyperthread();
check_speedstep();
}

View File

@ -6,9 +6,8 @@
#include "cpu.h"
// helper routine, called by ia32.cpp check_hyperthread
// not possible with POSIX calls.
int on_each_cpu(void(*cb)())
static int on_each_cpu(void(*cb)())
{
const HANDLE hProcess = GetCurrentProcess();
@ -46,6 +45,12 @@ int on_each_cpu(void(*cb)())
}
static void check_smp()
{
on_each_cpu(cpu_check_smp);
}
static void check_speedstep()
{
// CallNtPowerInformation
@ -130,6 +135,7 @@ int win_get_cpu_info()
}
check_speedstep();
check_smp();
return 0;
}

View File

@ -144,7 +144,7 @@ static int choose_impl()
// => unsafe.
if(ia32_cap(TSC) && cpu_freq > 0.0)
{
safe = (cpus == 1 && !cpu_speedstep);
safe = (cpu_smp == 0 && cpu_speedstep == 0);
SAFETY_OVERRIDE(HRT_TSC);
if(safe)
{