mirror of https://github.com/PCSX2/pcsx2.git
cdvdgigaherz: Use condition variables for event waiting
Also use atomics for thread exit variables.
This commit is contained in:
parent
f678ff8cfd
commit
f8f79788e4
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "CDVD.h"
|
||||
#include <cstdio>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include "svnrev.h"
|
||||
|
||||
Settings g_settings;
|
||||
|
@ -22,8 +24,9 @@ static std::string s_config_file{"inis/cdvdGigaherz.ini"};
|
|||
|
||||
void (*newDiscCB)();
|
||||
|
||||
static std::mutex s_keepalive_lock;
|
||||
static std::condition_variable s_keepalive_cv;
|
||||
HANDLE hThread_keepAlive = nullptr;
|
||||
HANDLE hNotify_keepAlive = nullptr;
|
||||
DWORD pidThreadKeepAlive = 0;
|
||||
|
||||
#define STRFY(x) #x
|
||||
|
@ -116,8 +119,7 @@ void WriteSettings()
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CDVD processing functions //
|
||||
|
||||
bool cdvd_is_open = false;
|
||||
bool cdvdKeepAlive_is_open = false;
|
||||
std::atomic<bool> s_keepalive_is_open;
|
||||
bool disc_has_changed = false;
|
||||
bool weAreInNewDiskCB = false;
|
||||
|
||||
|
@ -133,14 +135,10 @@ extern s32 prefetch_last_mode;
|
|||
DWORD CALLBACK keepAliveThread(PVOID param)
|
||||
{
|
||||
printf(" * CDVD: KeepAlive thread started...\n");
|
||||
std::unique_lock<std::mutex> guard(s_keepalive_lock);
|
||||
|
||||
while (cdvdKeepAlive_is_open) {
|
||||
// Sleep 30 seconds with thread abort check
|
||||
if (WaitForSingleObject(hNotify_keepAlive, 30000) != WAIT_TIMEOUT)
|
||||
break;
|
||||
if (!cdvdKeepAlive_is_open) {
|
||||
break;
|
||||
}
|
||||
while (!s_keepalive_cv.wait_for(guard, std::chrono::seconds(30),
|
||||
[]() { return !s_keepalive_is_open; })) {
|
||||
|
||||
//printf(" * keepAliveThread: polling drive.\n");
|
||||
//if (prefetch_last_mode == CDVD_MODE_2048)
|
||||
|
@ -156,14 +154,10 @@ DWORD CALLBACK keepAliveThread(PVOID param)
|
|||
|
||||
s32 StartKeepAliveThread()
|
||||
{
|
||||
hNotify_keepAlive = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (hNotify_keepAlive == nullptr)
|
||||
return -1;
|
||||
|
||||
cdvdKeepAlive_is_open = true;
|
||||
s_keepalive_is_open = true;
|
||||
hThread_keepAlive = CreateThread(NULL, 0, keepAliveThread, NULL, 0, &pidThreadKeepAlive);
|
||||
if (hThread_keepAlive == nullptr) {
|
||||
cdvdKeepAlive_is_open = false;
|
||||
s_keepalive_is_open = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -174,13 +168,15 @@ s32 StartKeepAliveThread()
|
|||
|
||||
void StopKeepAliveThread()
|
||||
{
|
||||
cdvdKeepAlive_is_open = false;
|
||||
PulseEvent(hNotify_keepAlive);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(s_keepalive_lock);
|
||||
s_keepalive_is_open = false;
|
||||
}
|
||||
s_keepalive_cv.notify_one();
|
||||
if (WaitForSingleObject(hThread_keepAlive, 5000) == WAIT_TIMEOUT) {
|
||||
TerminateThread(hThread_keepAlive, 0);
|
||||
}
|
||||
CloseHandle(hThread_keepAlive);
|
||||
CloseHandle(hNotify_keepAlive);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -93,8 +93,6 @@ std::wstring GetValidDrive();
|
|||
|
||||
extern Settings g_settings;
|
||||
|
||||
extern bool cdvd_is_open;
|
||||
extern bool cdvdKeepAlive_is_open;
|
||||
extern bool disc_has_changed;
|
||||
extern bool weAreInNewDiskCB;
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
*/
|
||||
|
||||
#include "CDVD.h"
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
|
||||
const s32 prefetch_max_blocks = 16;
|
||||
s32 prefetch_mode = 0;
|
||||
|
@ -21,12 +23,16 @@ s32 prefetch_last_lba = 0;
|
|||
s32 prefetch_last_mode = 0;
|
||||
s32 prefetch_left = 0;
|
||||
|
||||
HANDLE hNotify = nullptr;
|
||||
HANDLE hThread = nullptr;
|
||||
HANDLE hRequestComplete = nullptr;
|
||||
|
||||
static std::mutex s_notify_lock;
|
||||
static std::condition_variable s_notify_cv;
|
||||
static std::mutex s_request_lock;
|
||||
static std::condition_variable s_request_cv;
|
||||
static std::mutex s_cache_lock;
|
||||
|
||||
static std::atomic<bool> cdvd_is_open;
|
||||
|
||||
DWORD pidThread = 0;
|
||||
|
||||
typedef struct
|
||||
|
@ -128,6 +134,7 @@ bool cdvdUpdateDiscStatus()
|
|||
DWORD CALLBACK cdvdThread(PVOID param)
|
||||
{
|
||||
printf(" * CDVD: IO thread started...\n");
|
||||
std::unique_lock<std::mutex> guard(s_notify_lock);
|
||||
|
||||
while (cdvd_is_open) {
|
||||
if (cdvdUpdateDiscStatus()) {
|
||||
|
@ -136,10 +143,7 @@ DWORD CALLBACK cdvdThread(PVOID param)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (prefetch_left)
|
||||
WaitForSingleObject(hNotify, 1);
|
||||
else
|
||||
WaitForSingleObject(hNotify, 250);
|
||||
s_notify_cv.wait_for(guard, std::chrono::milliseconds(prefetch_left ? 1 : 250));
|
||||
|
||||
// check again to make sure we're not done here...
|
||||
if (!cdvd_is_open)
|
||||
|
@ -181,7 +185,7 @@ DWORD CALLBACK cdvdThread(PVOID param)
|
|||
|
||||
handlingRequest = false;
|
||||
threadRequestPending = false;
|
||||
PulseEvent(hRequestComplete);
|
||||
s_request_cv.notify_one();
|
||||
|
||||
prefetch_last_lba = info.lsn;
|
||||
prefetch_last_mode = info.mode;
|
||||
|
@ -199,14 +203,6 @@ DWORD CALLBACK cdvdThread(PVOID param)
|
|||
|
||||
s32 cdvdStartThread()
|
||||
{
|
||||
hNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (hNotify == nullptr)
|
||||
return -1;
|
||||
|
||||
hRequestComplete = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (hRequestComplete == nullptr)
|
||||
return -1;
|
||||
|
||||
cdvd_is_open = true;
|
||||
hThread = CreateThread(NULL, 0, cdvdThread, NULL, 0, &pidThread);
|
||||
|
||||
|
@ -223,13 +219,11 @@ s32 cdvdStartThread()
|
|||
void cdvdStopThread()
|
||||
{
|
||||
cdvd_is_open = false;
|
||||
PulseEvent(hNotify);
|
||||
s_notify_cv.notify_one();
|
||||
if (WaitForSingleObject(hThread, 4000) == WAIT_TIMEOUT) {
|
||||
TerminateThread(hThread, 0);
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
CloseHandle(hNotify);
|
||||
CloseHandle(hRequestComplete);
|
||||
}
|
||||
|
||||
s32 cdvdRequestSector(u32 sector, s32 mode)
|
||||
|
@ -247,8 +241,7 @@ s32 cdvdRequestSector(u32 sector, s32 mode)
|
|||
}
|
||||
|
||||
threadRequestPending = true;
|
||||
ResetEvent(hRequestComplete);
|
||||
PulseEvent(hNotify);
|
||||
s_notify_cv.notify_one();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -260,8 +253,10 @@ s32 cdvdRequestComplete()
|
|||
|
||||
s8 *cdvdGetSector(s32 sector, s32 mode)
|
||||
{
|
||||
while (threadRequestPending) {
|
||||
WaitForSingleObject(hRequestComplete, 10);
|
||||
{
|
||||
std::unique_lock<std::mutex> guard(s_request_lock);
|
||||
while (threadRequestPending)
|
||||
s_request_cv.wait_for(guard, std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
s32 offset;
|
||||
|
|
Loading…
Reference in New Issue