mirror of https://github.com/PCSX2/pcsx2.git
Common: Add Threading::SleepUntil()
This commit is contained in:
parent
a346cff472
commit
aea6a9f534
|
@ -19,11 +19,13 @@
|
|||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include "common/General.h"
|
||||
#include "common/Threading.h"
|
||||
#include "common/WindowInfo.h"
|
||||
|
||||
// Darwin (OSX) is a bit different from Linux when requesting properties of
|
||||
|
@ -47,13 +49,13 @@ u64 GetPhysicalMemory()
|
|||
}
|
||||
|
||||
static u64 tickfreq;
|
||||
static mach_timebase_info_data_t s_timebase_info;
|
||||
|
||||
void InitCPUTicks()
|
||||
{
|
||||
mach_timebase_info_data_t info;
|
||||
if (mach_timebase_info(&info) != KERN_SUCCESS)
|
||||
if (mach_timebase_info(&s_timebase_info) != KERN_SUCCESS)
|
||||
abort();
|
||||
tickfreq = (u64)1e9 * (u64)info.denom / (u64)info.numer;
|
||||
tickfreq = (u64)1e9 * (u64)s_timebase_info.denom / (u64)s_timebase_info.numer;
|
||||
}
|
||||
|
||||
// returns the performance-counter frequency: ticks per second (Hz)
|
||||
|
@ -110,4 +112,27 @@ bool WindowInfo::InhibitScreensaver(const WindowInfo& wi, bool inhibit)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
void Threading::SleepUntil(u64 ticks)
|
||||
{
|
||||
// This is definitely sub-optimal, but apparently clock_nanosleep() doesn't exist.
|
||||
const s64 diff = static_cast<s64>(ticks - GetCPUTicks());
|
||||
if (diff <= 0)
|
||||
return;
|
||||
|
||||
const u64 nanos = (static_cast<u64>(diff) * static_cast<u64>(s_timebase_info.denom)) / static_cast<u64>(s_timebase_info.numer);
|
||||
if (nanos == 0)
|
||||
return;
|
||||
|
||||
struct timespec ts;
|
||||
ts.tv_sec = nanos / 1000000000ULL;
|
||||
ts.tv_nsec = nanos % 1000000000ULL;
|
||||
nanosleep(&ts, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
|
||||
// having the LOCK prefix is very bad indeed.
|
||||
|
||||
__forceinline void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
__forceinline void Threading::Timeslice()
|
||||
{
|
||||
sched_yield();
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "common/Pcsx2Types.h"
|
||||
#include "common/General.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Threading.h"
|
||||
#include "common/WindowInfo.h"
|
||||
|
||||
// Returns 0 on failure (not supported by the operating system).
|
||||
|
@ -149,4 +150,17 @@ bool Common::PlaySoundAsync(const char* path)
|
|||
#endif
|
||||
}
|
||||
|
||||
void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
void Threading::SleepUntil(u64 ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = static_cast<time_t>(ticks / 1000000000ULL);
|
||||
ts.tv_nsec = static_cast<long>(ticks % 1000000000ULL);
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,11 +54,6 @@
|
|||
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
|
||||
// having the LOCK prefix is very bad indeed.
|
||||
|
||||
__forceinline void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
}
|
||||
|
||||
__forceinline void Threading::Timeslice()
|
||||
{
|
||||
sched_yield();
|
||||
|
|
|
@ -55,6 +55,9 @@ namespace Threading
|
|||
// sleeps the current thread for the given number of milliseconds.
|
||||
extern void Sleep(int ms);
|
||||
|
||||
// sleeps the current thread until the specified time point, or later.
|
||||
extern void SleepUntil(u64 ticks);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ThreadHandle
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "common/RedtapeWindows.h"
|
||||
#include "common/Exceptions.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Threading.h"
|
||||
#include "common/General.h"
|
||||
#include "common/WindowInfo.h"
|
||||
|
||||
|
@ -30,6 +31,23 @@
|
|||
|
||||
alignas(16) static LARGE_INTEGER lfreq;
|
||||
|
||||
// This gets leaked... oh well.
|
||||
static thread_local HANDLE s_sleep_timer;
|
||||
static thread_local bool s_sleep_timer_created = false;
|
||||
|
||||
static HANDLE GetSleepTimer()
|
||||
{
|
||||
if (s_sleep_timer_created)
|
||||
return s_sleep_timer;
|
||||
|
||||
s_sleep_timer_created = true;
|
||||
s_sleep_timer = CreateWaitableTimerEx(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
|
||||
if (!s_sleep_timer)
|
||||
s_sleep_timer = CreateWaitableTimer(nullptr, TRUE, nullptr);
|
||||
|
||||
return s_sleep_timer;
|
||||
}
|
||||
|
||||
void InitCPUTicks()
|
||||
{
|
||||
QueryPerformanceFrequency(&lfreq);
|
||||
|
@ -91,4 +109,34 @@ bool Common::PlaySoundAsync(const char* path)
|
|||
return PlaySoundW(wpath.c_str(), NULL, SND_ASYNC | SND_NODEFAULT);
|
||||
}
|
||||
|
||||
void Threading::Sleep(int ms)
|
||||
{
|
||||
::Sleep(ms);
|
||||
}
|
||||
|
||||
void Threading::SleepUntil(u64 ticks)
|
||||
{
|
||||
// This is definitely sub-optimal, but there's no way to sleep until a QPC timestamp on Win32.
|
||||
const s64 diff = static_cast<s64>(ticks - GetCPUTicks());
|
||||
if (diff <= 0)
|
||||
return;
|
||||
|
||||
const HANDLE hTimer = GetSleepTimer();
|
||||
if (!hTimer)
|
||||
return;
|
||||
|
||||
const u64 one_hundred_nanos_diff = (static_cast<u64>(diff) * 10000000ULL) / GetTickFrequency();
|
||||
if (one_hundred_nanos_diff == 0)
|
||||
return;
|
||||
|
||||
LARGE_INTEGER fti;
|
||||
fti.QuadPart = -static_cast<s64>(one_hundred_nanos_diff);
|
||||
|
||||
if (SetWaitableTimer(hTimer, &fti, 0, nullptr, nullptr, FALSE))
|
||||
{
|
||||
WaitForSingleObject(hTimer, INFINITE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,11 +23,6 @@
|
|||
#include <process.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
__fi void Threading::Sleep(int ms)
|
||||
{
|
||||
::Sleep(ms);
|
||||
}
|
||||
|
||||
__fi void Threading::Timeslice()
|
||||
{
|
||||
::Sleep(0);
|
||||
|
|
Loading…
Reference in New Issue