1
0
forked from 0ad/0ad

implement the previously mentioned cmdline params

qpc: refactor IsSafe

This was SVN commit r5336.
This commit is contained in:
janwas 2007-09-08 08:09:32 +00:00
parent 87b0d08c0e
commit 5383eff15c
5 changed files with 121 additions and 31 deletions

View File

@ -283,20 +283,27 @@ bool mahaf_Init()
if(!ModuleShouldInitialize(&initState))
return true;
if(wutil_HasCommandLineArgument("-wNoMahaf"))
goto fail;
{
char driverPathname[PATH_MAX];
GetDriverPathname(driverPathname, ARRAY_SIZE(driverPathname));
StartDriver(driverPathname);
}
DWORD shareMode = 0;
{
const DWORD shareMode = 0;
hAken = CreateFile("\\\\.\\Aken", GENERIC_READ, shareMode, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hAken == INVALID_HANDLE_VALUE)
{
ModuleSetError(&initState);
return false;
goto fail;
}
return true;
fail:
ModuleSetError(&initState);
return false;
}

View File

@ -13,6 +13,7 @@
#include "lib/sysdep/win/win.h"
#include "lib/sysdep/win/wcpu.h"
#include "lib/sysdep/win/wutil.h" // wutil_argv
#include "pit.h" // PIT_FREQ
#include "pmt.h" // PMT_FREQ
@ -39,16 +40,16 @@ void CounterQPC::Shutdown()
bool CounterQPC::IsSafe() const
{
// the PIT is entirely safe (even if annoyingly slow to read)
if(m_frequency == PIT_FREQ)
return true;
// note: we have separate modules that directly access some of the
// counters potentially used by QPC. disabling the redundant counters
// would be ugly (increased coupling). instead, we'll make sure our
// implementations could (if necessary) coexist with QPC, but it
// shouldn't come to that since only one counter is needed/used.
// the PIT is entirely safe (even if annoyingly slow to read)
if(m_frequency == PIT_FREQ)
return true;
// the PMT is generally safe (see discussion in CounterPmt::IsSafe),
// but older QPC implementations had problems with 24-bit rollover.
// "System clock problem can inflate benchmark scores"
@ -57,32 +58,29 @@ bool CounterQPC::IsSafe() const
// incorrect values every 4.6 seconds (i.e. 24 bits @ 3.57 MHz) unless
// the timer is polled in the meantime. fortunately, this is guaranteed
// by our periodic updates (which come at least that often).
if(m_frequency == PIT_FREQ)
if(m_frequency == PMT_FREQ)
return true;
// two other implementations have been observed: HPET
// (on Vista) and RDTSC (on MP HAL).
//
// - the HPET is reliable but can't easily be recognized since its
// frequency is variable (the spec says > 10 MHz; the master 14.318 MHz
// oscillator is often used). note: considering frequencies between
// 10..100 MHz to be a HPET would be dangerous because it may actually
// be faster or RDTSC slower.
//
// - the TSC implementation has been known to be buggy (even mentioned
// in MSDN) and we don't know which systems have been patched. it is
// therefore considered unsafe and recognized by comparing frequency
// against the CPU clock.
// QPC frequency matches the CPU clock => it uses RDTSC => unsafe.
if(IsSimilarMagnitude(m_frequency, wcpu_ClockFrequency()))
return false;
// the TSC has been known to be buggy (even mentioned in MSDN). it is
// used on MP HAL systems and can be detected by comparing QPF with the
// CPU clock. we consider it unsafe unless the user promises (via
// command line) that it's patched and thus reliable on their system.
bool usesTsc = IsSimilarMagnitude(m_frequency, wcpu_ClockFrequency());
// unconfirmed reports indicate QPC sometimes uses 1/3 of the
// CPU clock frequency, so check that as well.
if(IsSimilarMagnitude(m_frequency, wcpu_ClockFrequency()/3))
return false;
usesTsc |= IsSimilarMagnitude(m_frequency, wcpu_ClockFrequency()/3);
if(usesTsc)
{
const bool isTscSafe = wutil_HasCommandLineArgument("-wQpcTscSafe");
return isTscSafe;
}
// otherwise: it's apparently using the HPET => safe.
// the HPET is reliable and used on Vista. it can't easily be recognized
// since its frequency is variable (the spec says > 10 MHz; the master
// 14.318 MHz oscillator is often used). considering frequencies in
// [10, 100 MHz) to be a HPET would be dangerous because it may actually
// be faster or RDTSC slower. we have to exclude all other cases and
// assume it's a HPET - and thus safe - if we get here.
return true;
}

View File

@ -22,7 +22,7 @@
#include "counter.h"
WINIT_REGISTER_EARLY_INIT2(whrt_Init); // whrt -> wtime
WINIT_REGISTER_EARLY_INIT2(whrt_Init); // wutil -> whrt -> wtime
WINIT_REGISTER_LATE_SHUTDOWN(whrt_Shutdown);

View File

@ -145,6 +145,77 @@ LibError LibError_from_win32(DWORD ret, bool warn_if_failed)
}
//-----------------------------------------------------------------------------
// command line
// copy of GetCommandLine string. will be tokenized and then referenced by
// the argv pointers.
static char* argvContents;
int wutil_argc = 0;
char** wutil_argv = 0;
static void ReadCommandLine()
{
const char* commandLine = GetCommandLine();
// (this changes as quotation marks are removed)
size_t numChars = strlen(commandLine);
argvContents = (char*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, numChars+1);
strcpy_s(argvContents, numChars+1, commandLine);
// first pass: tokenize string and count number of arguments
bool ignoreSpace = false;
for(size_t i = 0; i < numChars; i++)
{
switch(argvContents[i])
{
case '"':
ignoreSpace = !ignoreSpace;
// strip the " character
memmove(argvContents+i, argvContents+i+1, numChars-i);
numChars--;
break;
case ' ':
if(!ignoreSpace)
{
argvContents[i] = '\0';
wutil_argc++;
}
break;
}
}
// have argv entries point into the tokenized string
wutil_argv = (char**)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, wutil_argc*sizeof(char*));
char* nextArg = argvContents;
for(int i = 0; i < wutil_argc; i++)
{
wutil_argv[i] = nextArg;
nextArg += strlen(nextArg)+1;
}
}
static void FreeCommandLine()
{
HeapFree(GetProcessHeap(), 0, wutil_argv);
HeapFree(GetProcessHeap(), 0, argvContents);
}
bool wutil_HasCommandLineArgument(const char* arg)
{
for(int i = 0; i < wutil_argc; i++)
{
if(!strcmp(wutil_argv[i], arg))
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// directories
@ -363,6 +434,8 @@ static LibError wutil_Init()
EnableLowFragmentationHeap();
ReadCommandLine();
GetDirectories();
DetectWindowsVersion();
@ -376,6 +449,8 @@ static LibError wutil_Init()
static LibError wutil_Shutdown()
{
FreeCommandLine();
FreeUser32Dll();
ShutdownLocks();

View File

@ -85,6 +85,16 @@ LibError LibError_from_GLE(bool warn_if_failed = true);
extern LibError LibError_from_win32(DWORD ret, bool warn_if_failed = true);
//
// command line
//
extern int wutil_argc;
extern char** wutil_argv;
extern bool wutil_HasCommandLineArgument(const char* arg);
//
// directories
//