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:
parent
4c2463d7c3
commit
d633fd201d
@ -13,6 +13,13 @@ extern int cpu_smp;
|
|||||||
// are there actually multiple physical processors,
|
// are there actually multiple physical processors,
|
||||||
// not only logical hyperthreaded CPUs? relevant for wtime.
|
// 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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)");
|
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
|
// 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
|
// on other CPUs in future. haven't come across a processor that
|
||||||
// incorrectly sets the HT feature bit.
|
// incorrectly sets the HT feature bit.
|
||||||
|
|
||||||
if(!ia32_cap(HT))
|
if(!ia32_cap(HT))
|
||||||
|
{
|
||||||
|
// no HT supported, just check number of CPUs as reported by OS.
|
||||||
|
cpu_smp = (cpus > 1);
|
||||||
return;
|
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
|
// get number of logical CPUs per package
|
||||||
|
// (the same for all packages on this system)
|
||||||
int log_cpus_per_package;
|
int log_cpus_per_package;
|
||||||
__asm {
|
__asm {
|
||||||
push 1
|
push 1
|
||||||
@ -423,6 +439,15 @@ static void check_hyperthread()
|
|||||||
mov log_cpus_per_package, ebx ; ebx[23:16]
|
mov log_cpus_per_package, ebx ; ebx[23:16]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
cpu_smp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +473,6 @@ void ia32_get_cpu_info()
|
|||||||
|
|
||||||
get_cpu_type();
|
get_cpu_type();
|
||||||
measure_cpu_freq();
|
measure_cpu_freq();
|
||||||
check_hyperthread();
|
|
||||||
check_speedstep();
|
check_speedstep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
|
||||||
// helper routine, called by ia32.cpp check_hyperthread
|
|
||||||
// not possible with POSIX calls.
|
// not possible with POSIX calls.
|
||||||
int on_each_cpu(void(*cb)())
|
static int on_each_cpu(void(*cb)())
|
||||||
{
|
{
|
||||||
const HANDLE hProcess = GetCurrentProcess();
|
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()
|
static void check_speedstep()
|
||||||
{
|
{
|
||||||
// CallNtPowerInformation
|
// CallNtPowerInformation
|
||||||
@ -130,6 +135,7 @@ int win_get_cpu_info()
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_speedstep();
|
check_speedstep();
|
||||||
|
check_smp();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ static int choose_impl()
|
|||||||
// => unsafe.
|
// => unsafe.
|
||||||
if(ia32_cap(TSC) && cpu_freq > 0.0)
|
if(ia32_cap(TSC) && cpu_freq > 0.0)
|
||||||
{
|
{
|
||||||
safe = (cpus == 1 && !cpu_speedstep);
|
safe = (cpu_smp == 0 && cpu_speedstep == 0);
|
||||||
SAFETY_OVERRIDE(HRT_TSC);
|
SAFETY_OVERRIDE(HRT_TSC);
|
||||||
if(safe)
|
if(safe)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user