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