remove winmm dependency (timeSetEvent -> thread)
This was SVN commit r453.
This commit is contained in:
parent
131573f7c4
commit
69fb0064b4
@ -32,13 +32,8 @@
|
|||||||
|
|
||||||
// we no longer use TGT, due to issues on Win9x; GTC is just as good.
|
// we no longer use TGT, due to issues on Win9x; GTC is just as good.
|
||||||
// (don't want to accelerate the tick rate, because performance will suffer).
|
// (don't want to accelerate the tick rate, because performance will suffer).
|
||||||
// still need the header for the event timer (triggers periodic recalibration).
|
// avoid dependency on WinMM (event timer) to shorten startup time;
|
||||||
// don't bother trying to avoid dependency on winmm - FMOD pulls it in anyway.
|
// fmod pulls it in, but it's delay-loaded.
|
||||||
#include <mmsystem.h>
|
|
||||||
// not included by win_internal due to its WIN32_LEAN_AND_MEAN define
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma comment(lib, "winmm.lib")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ticks per second; average of last few values measured in calibrate()
|
// ticks per second; average of last few values measured in calibrate()
|
||||||
@ -105,7 +100,7 @@ static i64 hrt_nominal_freq = -1;
|
|||||||
// in case there are unforeseen problems with one of them.
|
// in case there are unforeseen problems with one of them.
|
||||||
// order of preference (due to resolution and speed): TSC, QPC, GTC.
|
// order of preference (due to resolution and speed): TSC, QPC, GTC.
|
||||||
// split out of reset_impl so we can just return when impl is chosen.
|
// split out of reset_impl so we can just return when impl is chosen.
|
||||||
static void choose_impl()
|
static int choose_impl()
|
||||||
{
|
{
|
||||||
bool safe;
|
bool safe;
|
||||||
#define SAFETY_OVERRIDE(impl)\
|
#define SAFETY_OVERRIDE(impl)\
|
||||||
@ -143,7 +138,7 @@ static void choose_impl()
|
|||||||
{
|
{
|
||||||
hrt_impl = HRT_TSC;
|
hrt_impl = HRT_TSC;
|
||||||
hrt_nominal_freq = (i64)cpu_freq;
|
hrt_nominal_freq = (i64)cpu_freq;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // TSC
|
#endif // TSC
|
||||||
@ -201,7 +196,7 @@ static void choose_impl()
|
|||||||
{
|
{
|
||||||
hrt_impl = HRT_QPC;
|
hrt_impl = HRT_QPC;
|
||||||
hrt_nominal_freq = qpc_freq;
|
hrt_nominal_freq = qpc_freq;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // QPC
|
#endif // QPC
|
||||||
@ -213,14 +208,14 @@ static void choose_impl()
|
|||||||
{
|
{
|
||||||
hrt_impl = HRT_GTC;
|
hrt_impl = HRT_GTC;
|
||||||
hrt_nominal_freq = 1000;
|
hrt_nominal_freq = 1000;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no warning here - doesn't inspire confidence in VC dead code removal.
|
// no warning here - doesn't inspire confidence in VC dead code removal.
|
||||||
debug_warn("hrt_choose_impl: no safe timer found!");
|
debug_warn("hrt_choose_impl: no safe timer found!");
|
||||||
hrt_impl = HRT_NONE;
|
hrt_impl = HRT_NONE;
|
||||||
hrt_nominal_freq = -1;
|
hrt_nominal_freq = -1;
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -287,7 +282,7 @@ static i64 ticks_lk()
|
|||||||
//
|
//
|
||||||
// don't want to saddle timer module with the problem of initializing
|
// don't want to saddle timer module with the problem of initializing
|
||||||
// us on first call - it wouldn't otherwise need to be thread-safe.
|
// us on first call - it wouldn't otherwise need to be thread-safe.
|
||||||
static void reset_impl_lk()
|
static int reset_impl_lk()
|
||||||
{
|
{
|
||||||
HRTImpl old_impl = hrt_impl;
|
HRTImpl old_impl = hrt_impl;
|
||||||
double old_time = 0.0;
|
double old_time = 0.0;
|
||||||
@ -297,7 +292,7 @@ static void reset_impl_lk()
|
|||||||
old_time = ticks_lk() / hrt_freq;
|
old_time = ticks_lk() / hrt_freq;
|
||||||
// don't call hrt_time to avoid recursive lock.
|
// don't call hrt_time to avoid recursive lock.
|
||||||
|
|
||||||
choose_impl();
|
CHECK_ERR(choose_impl());
|
||||||
// post: hrt_impl != HRT_NONE, hrt_nominal_freq > 0
|
// post: hrt_impl != HRT_NONE, hrt_nominal_freq > 0
|
||||||
|
|
||||||
hrt_freq = (double)hrt_nominal_freq;
|
hrt_freq = (double)hrt_nominal_freq;
|
||||||
@ -306,23 +301,8 @@ static void reset_impl_lk()
|
|||||||
// want it 0-based, but it must not go backwards WRT previous reading.
|
// want it 0-based, but it must not go backwards WRT previous reading.
|
||||||
if(old_impl != hrt_impl)
|
if(old_impl != hrt_impl)
|
||||||
hrt_origin = ticks_lk() - (i64)(old_time * hrt_freq);
|
hrt_origin = ticks_lk() - (i64)(old_time * hrt_freq);
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
static void init_calibration_thread();
|
|
||||||
|
|
||||||
static void hrt_init()
|
|
||||||
{
|
|
||||||
lock();
|
|
||||||
|
|
||||||
static bool initialized = false;
|
|
||||||
assert(!initialized && "init_lk called more than once!");
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
reset_impl_lk();
|
|
||||||
init_calibration_thread();
|
|
||||||
|
|
||||||
unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -472,49 +452,72 @@ unlock();
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
// calibration thread
|
||||||
|
|
||||||
// setup calibration thread
|
|
||||||
// note: winmm event is better than a thread or just checking elapsed time
|
// note: winmm event is better than a thread or just checking elapsed time
|
||||||
// in hrt_ticks, because it's called right after GTC is updated;
|
// in hrt_ticks, because it's called right after GTC is updated;
|
||||||
// otherwise, we may be in the middle of a tick.
|
// otherwise, we may be in the middle of a tick.
|
||||||
|
// however, we want to avoid dependency on WinMM to shorten startup time.
|
||||||
|
// hence, start a thread.
|
||||||
|
|
||||||
static UINT mm_event;
|
static HANDLE hThread;
|
||||||
|
static HANDLE hExitEvent;
|
||||||
|
|
||||||
// keep calibrate() portable, don't need args anyway
|
#include <process.h>
|
||||||
static void CALLBACK trampoline(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
|
|
||||||
|
static unsigned __stdcall calibration_thread(void* data)
|
||||||
{
|
{
|
||||||
UNUSED(uTimerID);
|
for(;;)
|
||||||
UNUSED(uMsg);
|
{
|
||||||
UNUSED(dwUser);
|
if(WaitForSingleObject(hExitEvent, 1000) != WAIT_TIMEOUT)
|
||||||
UNUSED(dw1);
|
break;
|
||||||
UNUSED(dw2);
|
|
||||||
|
|
||||||
calibrate();
|
calibrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hExitEvent);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
static inline int init_calibration_thread()
|
||||||
static void init_calibration_thread()
|
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
hExitEvent = CreateEvent(0, 0, 0, 0);
|
||||||
|
hThread = (HANDLE)_beginthreadex(0, 0, calibration_thread, 0, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// choosing resolution of winmm timer. don't want to increase the
|
|
||||||
// system clock interrupt rate (=> higher system load),
|
|
||||||
// so set res to current tick rate.
|
|
||||||
DWORD adj, incr;
|
|
||||||
BOOL adj_disabled;
|
|
||||||
GetSystemTimeAdjustment(&adj, &incr, &adj_disabled);
|
|
||||||
DWORD res = adj / 10000;
|
|
||||||
mm_event = timeSetEvent(1000, res, trampoline, 0, TIME_PERIODIC);
|
|
||||||
atexit2(timeKillEvent, mm_event, CC_STDCALL_1);
|
|
||||||
|
|
||||||
#else
|
static inline int shutdown_calibration_thread()
|
||||||
|
{
|
||||||
|
SetEvent(hExitEvent);
|
||||||
|
if(WaitForSingleObject(hThread, 250) != WAIT_OBJECT_0)
|
||||||
|
TerminateThread(hThread, 0);
|
||||||
|
CloseHandle(hThread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: port thread. it's no big deal, but the timer should work without.
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
static int hrt_init()
|
||||||
|
{
|
||||||
|
lock();
|
||||||
|
|
||||||
|
reset_impl_lk();
|
||||||
|
int err = init_calibration_thread();
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hrt_shutdown()
|
||||||
|
{
|
||||||
|
lock();
|
||||||
|
|
||||||
|
int err = shutdown_calibration_thread();
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -579,7 +582,7 @@ static int wtime_init()
|
|||||||
|
|
||||||
static int wtime_shutdown()
|
static int wtime_shutdown()
|
||||||
{
|
{
|
||||||
return 0;
|
return hrt_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wtime_reset_impl()
|
void wtime_reset_impl()
|
||||||
|
Loading…
Reference in New Issue
Block a user