Merge pull request #4093 from leoetlino/flags-and-events
Use Common::Flag and Common::Event when possible
This commit is contained in:
commit
caa7ff7c25
|
@ -34,7 +34,7 @@ void AOSound::SoundLoop()
|
||||||
|
|
||||||
buf_size = format.bits / 8 * format.channels * format.rate;
|
buf_size = format.bits / 8 * format.channels * format.rate;
|
||||||
|
|
||||||
while (m_run_thread.load())
|
while (m_run_thread.IsSet())
|
||||||
{
|
{
|
||||||
m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
|
m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ void AOSound::SoundLoop()
|
||||||
|
|
||||||
bool AOSound::Start()
|
bool AOSound::Start()
|
||||||
{
|
{
|
||||||
m_run_thread.store(true);
|
m_run_thread.Set();
|
||||||
memset(realtimeBuffer, 0, sizeof(realtimeBuffer));
|
memset(realtimeBuffer, 0, sizeof(realtimeBuffer));
|
||||||
|
|
||||||
thread = std::thread(&AOSound::SoundLoop, this);
|
thread = std::thread(&AOSound::SoundLoop, this);
|
||||||
|
@ -63,7 +63,7 @@ void AOSound::Update()
|
||||||
|
|
||||||
void AOSound::Stop()
|
void AOSound::Stop()
|
||||||
{
|
{
|
||||||
m_run_thread.store(false);
|
m_run_thread.Clear();
|
||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ class AOSound final : public SoundStream
|
||||||
{
|
{
|
||||||
#if defined(HAVE_AO) && HAVE_AO
|
#if defined(HAVE_AO) && HAVE_AO
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
std::atomic<bool> m_run_thread;
|
Common::Flag m_run_thread;
|
||||||
std::mutex soundCriticalSection;
|
std::mutex soundCriticalSection;
|
||||||
Common::Event soundSyncEvent;
|
Common::Event soundSyncEvent;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ static soundtouch::SoundTouch soundTouch;
|
||||||
//
|
//
|
||||||
bool OpenALStream::Start()
|
bool OpenALStream::Start()
|
||||||
{
|
{
|
||||||
m_run_thread.store(true);
|
m_run_thread.Set();
|
||||||
bool bReturn = false;
|
bool bReturn = false;
|
||||||
|
|
||||||
ALDeviceList pDeviceList;
|
ALDeviceList pDeviceList;
|
||||||
|
@ -75,7 +75,7 @@ bool OpenALStream::Start()
|
||||||
|
|
||||||
void OpenALStream::Stop()
|
void OpenALStream::Stop()
|
||||||
{
|
{
|
||||||
m_run_thread.store(false);
|
m_run_thread.Clear();
|
||||||
// kick the thread if it's waiting
|
// kick the thread if it's waiting
|
||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ void OpenALStream::SoundLoop()
|
||||||
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
|
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
|
||||||
soundTouch.setSetting(SETTING_OVERLAP_MS, 12);
|
soundTouch.setSetting(SETTING_OVERLAP_MS, 12);
|
||||||
|
|
||||||
while (m_run_thread.load())
|
while (m_run_thread.IsSet())
|
||||||
{
|
{
|
||||||
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
|
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
|
||||||
const u32 stereo_16_bit_size = 4;
|
const u32 stereo_16_bit_size = 4;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "AudioCommon/SoundStream.h"
|
#include "AudioCommon/SoundStream.h"
|
||||||
|
@ -68,7 +67,7 @@ public:
|
||||||
static bool isValid() { return true; }
|
static bool isValid() { return true; }
|
||||||
private:
|
private:
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
std::atomic<bool> m_run_thread;
|
Common::Flag m_run_thread;
|
||||||
|
|
||||||
Common::Event soundSyncEvent;
|
Common::Event soundSyncEvent;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ bool PulseAudio::Start()
|
||||||
|
|
||||||
NOTICE_LOG(AUDIO, "PulseAudio backend using %d channels", m_channels);
|
NOTICE_LOG(AUDIO, "PulseAudio backend using %d channels", m_channels);
|
||||||
|
|
||||||
m_run_thread = true;
|
m_run_thread.Set();
|
||||||
m_thread = std::thread(&PulseAudio::SoundLoop, this);
|
m_thread = std::thread(&PulseAudio::SoundLoop, this);
|
||||||
|
|
||||||
// Initialize DPL2 parameters
|
// Initialize DPL2 parameters
|
||||||
|
@ -38,7 +38,7 @@ bool PulseAudio::Start()
|
||||||
|
|
||||||
void PulseAudio::Stop()
|
void PulseAudio::Stop()
|
||||||
{
|
{
|
||||||
m_run_thread = false;
|
m_run_thread.Clear();
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ void PulseAudio::SoundLoop()
|
||||||
|
|
||||||
if (PulseInit())
|
if (PulseInit())
|
||||||
{
|
{
|
||||||
while (m_run_thread.load() && m_pa_connected == 1 && m_pa_error >= 0)
|
while (m_run_thread.IsSet() && m_pa_connected == 1 && m_pa_error >= 0)
|
||||||
m_pa_error = pa_mainloop_iterate(m_pa_ml, 1, nullptr);
|
m_pa_error = pa_mainloop_iterate(m_pa_ml, 1, nullptr);
|
||||||
|
|
||||||
if (m_pa_error < 0)
|
if (m_pa_error < 0)
|
||||||
|
|
|
@ -8,10 +8,9 @@
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#include "AudioCommon/SoundStream.h"
|
#include "AudioCommon/SoundStream.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
|
|
||||||
class PulseAudio final : public SoundStream
|
class PulseAudio final : public SoundStream
|
||||||
|
@ -41,7 +40,7 @@ private:
|
||||||
static void UnderflowCallback(pa_stream* s, void* userdata);
|
static void UnderflowCallback(pa_stream* s, void* userdata);
|
||||||
|
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
std::atomic<bool> m_run_thread;
|
Common::Flag m_run_thread;
|
||||||
|
|
||||||
bool m_stereo; // stereo, else surround
|
bool m_stereo; // stereo, else surround
|
||||||
int m_bytespersample;
|
int m_bytespersample;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Common/CPUDetect.h"
|
#include "Common/CPUDetect.h"
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
#include "Common/Logging/LogManager.h"
|
#include "Common/Logging/LogManager.h"
|
||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
#include "Common/MemoryUtil.h"
|
#include "Common/MemoryUtil.h"
|
||||||
|
@ -101,7 +102,7 @@ void EmuThread();
|
||||||
static bool s_is_stopping = false;
|
static bool s_is_stopping = false;
|
||||||
static bool s_hardware_initialized = false;
|
static bool s_hardware_initialized = false;
|
||||||
static bool s_is_started = false;
|
static bool s_is_started = false;
|
||||||
static std::atomic<bool> s_is_booting{false};
|
static Common::Flag s_is_booting;
|
||||||
static void* s_window_handle = nullptr;
|
static void* s_window_handle = nullptr;
|
||||||
static std::string s_state_filename;
|
static std::string s_state_filename;
|
||||||
static std::thread s_emu_thread;
|
static std::thread s_emu_thread;
|
||||||
|
@ -469,7 +470,7 @@ static void FifoPlayerThread()
|
||||||
void EmuThread()
|
void EmuThread()
|
||||||
{
|
{
|
||||||
const SConfig& core_parameter = SConfig::GetInstance();
|
const SConfig& core_parameter = SConfig::GetInstance();
|
||||||
s_is_booting.store(true);
|
s_is_booting.Set();
|
||||||
|
|
||||||
Common::SetCurrentThreadName("Emuthread - Starting");
|
Common::SetCurrentThreadName("Emuthread - Starting");
|
||||||
|
|
||||||
|
@ -488,7 +489,7 @@ void EmuThread()
|
||||||
|
|
||||||
if (!g_video_backend->Initialize(s_window_handle))
|
if (!g_video_backend->Initialize(s_window_handle))
|
||||||
{
|
{
|
||||||
s_is_booting.store(false);
|
s_is_booting.Clear();
|
||||||
PanicAlert("Failed to initialize video backend!");
|
PanicAlert("Failed to initialize video backend!");
|
||||||
Host_Message(WM_USER_STOP);
|
Host_Message(WM_USER_STOP);
|
||||||
return;
|
return;
|
||||||
|
@ -503,7 +504,7 @@ void EmuThread()
|
||||||
|
|
||||||
if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread))
|
if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread))
|
||||||
{
|
{
|
||||||
s_is_booting.store(false);
|
s_is_booting.Clear();
|
||||||
HW::Shutdown();
|
HW::Shutdown();
|
||||||
g_video_backend->Shutdown();
|
g_video_backend->Shutdown();
|
||||||
PanicAlert("Failed to initialize DSP emulation!");
|
PanicAlert("Failed to initialize DSP emulation!");
|
||||||
|
@ -545,7 +546,7 @@ void EmuThread()
|
||||||
|
|
||||||
// The hardware is initialized.
|
// The hardware is initialized.
|
||||||
s_hardware_initialized = true;
|
s_hardware_initialized = true;
|
||||||
s_is_booting.store(false);
|
s_is_booting.Clear();
|
||||||
|
|
||||||
// Set execution state to known values (CPU/FIFO/Audio Paused)
|
// Set execution state to known values (CPU/FIFO/Audio Paused)
|
||||||
CPU::Break();
|
CPU::Break();
|
||||||
|
@ -1024,7 +1025,7 @@ void HostDispatchJobs()
|
||||||
// CORE_UNINITIALIZED: s_is_booting -> s_hardware_initialized
|
// CORE_UNINITIALIZED: s_is_booting -> s_hardware_initialized
|
||||||
// We need to check variables in the same order as the state
|
// We need to check variables in the same order as the state
|
||||||
// transition, otherwise we race and get transient failures.
|
// transition, otherwise we race and get transient failures.
|
||||||
if (!job.run_after_stop && !s_is_booting.load() && !IsRunning())
|
if (!job.run_after_stop && !s_is_booting.IsSet() && !IsRunning())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
guard.unlock();
|
guard.unlock();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -21,7 +20,7 @@
|
||||||
u16 GeckoSockServer::server_port;
|
u16 GeckoSockServer::server_port;
|
||||||
int GeckoSockServer::client_count;
|
int GeckoSockServer::client_count;
|
||||||
std::thread GeckoSockServer::connectionThread;
|
std::thread GeckoSockServer::connectionThread;
|
||||||
std::atomic<bool> GeckoSockServer::server_running;
|
Common::Flag GeckoSockServer::server_running;
|
||||||
std::mutex GeckoSockServer::connection_lock;
|
std::mutex GeckoSockServer::connection_lock;
|
||||||
std::queue<std::unique_ptr<sf::TcpSocket>> GeckoSockServer::waiting_socks;
|
std::queue<std::unique_ptr<sf::TcpSocket>> GeckoSockServer::waiting_socks;
|
||||||
|
|
||||||
|
@ -37,13 +36,13 @@ GeckoSockServer::~GeckoSockServer()
|
||||||
{
|
{
|
||||||
--client_count;
|
--client_count;
|
||||||
|
|
||||||
client_running.store(false);
|
client_running.Clear();
|
||||||
clientThread.join();
|
clientThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_count <= 0)
|
if (client_count <= 0)
|
||||||
{
|
{
|
||||||
server_running.store(false);
|
server_running.Clear();
|
||||||
connectionThread.join();
|
connectionThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +53,14 @@ void GeckoSockServer::GeckoConnectionWaiter()
|
||||||
|
|
||||||
sf::TcpListener server;
|
sf::TcpListener server;
|
||||||
server_port = 0xd6ec; // "dolphin gecko"
|
server_port = 0xd6ec; // "dolphin gecko"
|
||||||
for (int bind_tries = 0; bind_tries <= 10 && !server_running.load(); bind_tries++)
|
for (int bind_tries = 0; bind_tries <= 10 && !server_running.IsSet(); bind_tries++)
|
||||||
{
|
{
|
||||||
server_running.store(server.listen(server_port) == sf::Socket::Done);
|
server_running.Set(server.listen(server_port) == sf::Socket::Done);
|
||||||
if (!server_running.load())
|
if (!server_running.IsSet())
|
||||||
server_port++;
|
server_port++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server_running.load())
|
if (!server_running.IsSet())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Core::DisplayMessage(StringFromFormat("USBGecko: Listening on TCP port %u", server_port), 5000);
|
Core::DisplayMessage(StringFromFormat("USBGecko: Listening on TCP port %u", server_port), 5000);
|
||||||
|
@ -69,7 +68,7 @@ void GeckoSockServer::GeckoConnectionWaiter()
|
||||||
server.setBlocking(false);
|
server.setBlocking(false);
|
||||||
|
|
||||||
auto new_client = std::make_unique<sf::TcpSocket>();
|
auto new_client = std::make_unique<sf::TcpSocket>();
|
||||||
while (server_running.load())
|
while (server_running.IsSet())
|
||||||
{
|
{
|
||||||
if (server.accept(*new_client) == sf::Socket::Done)
|
if (server.accept(*new_client) == sf::Socket::Done)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +93,7 @@ bool GeckoSockServer::GetAvailableSock()
|
||||||
client = std::move(waiting_socks.front());
|
client = std::move(waiting_socks.front());
|
||||||
if (clientThread.joinable())
|
if (clientThread.joinable())
|
||||||
{
|
{
|
||||||
client_running.store(false);
|
client_running.Clear();
|
||||||
clientThread.join();
|
clientThread.join();
|
||||||
|
|
||||||
recv_fifo = std::deque<u8>();
|
recv_fifo = std::deque<u8>();
|
||||||
|
@ -111,13 +110,13 @@ bool GeckoSockServer::GetAvailableSock()
|
||||||
|
|
||||||
void GeckoSockServer::ClientThread()
|
void GeckoSockServer::ClientThread()
|
||||||
{
|
{
|
||||||
client_running.store(true);
|
client_running.Set();
|
||||||
|
|
||||||
Common::SetCurrentThreadName("Gecko Client");
|
Common::SetCurrentThreadName("Gecko Client");
|
||||||
|
|
||||||
client->setBlocking(false);
|
client->setBlocking(false);
|
||||||
|
|
||||||
while (client_running.load())
|
while (client_running.IsSet())
|
||||||
{
|
{
|
||||||
bool did_nothing = true;
|
bool did_nothing = true;
|
||||||
|
|
||||||
|
@ -129,7 +128,7 @@ void GeckoSockServer::ClientThread()
|
||||||
std::size_t got = 0;
|
std::size_t got = 0;
|
||||||
|
|
||||||
if (client->receive(&data[0], ArraySize(data), got) == sf::Socket::Disconnected)
|
if (client->receive(&data[0], ArraySize(data), got) == sf::Socket::Disconnected)
|
||||||
client_running.store(false);
|
client_running.Clear();
|
||||||
|
|
||||||
if (got != 0)
|
if (got != 0)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +145,7 @@ void GeckoSockServer::ClientThread()
|
||||||
send_fifo.clear();
|
send_fifo.clear();
|
||||||
|
|
||||||
if (client->send(&packet[0], packet.size()) == sf::Socket::Disconnected)
|
if (client->send(&packet[0], packet.size()) == sf::Socket::Disconnected)
|
||||||
client_running.store(false);
|
client_running.Clear();
|
||||||
}
|
}
|
||||||
} // unlock transfer
|
} // unlock transfer
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SFML/Network.hpp>
|
#include <SFML/Network.hpp>
|
||||||
#include <atomic>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -13,6 +12,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
#include "Core/HW/EXI_Device.h"
|
#include "Core/HW/EXI_Device.h"
|
||||||
|
|
||||||
class GeckoSockServer
|
class GeckoSockServer
|
||||||
|
@ -33,13 +33,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int client_count;
|
static int client_count;
|
||||||
std::atomic<bool> client_running;
|
Common::Flag client_running;
|
||||||
|
|
||||||
// Only ever one server thread
|
// Only ever one server thread
|
||||||
static void GeckoConnectionWaiter();
|
static void GeckoConnectionWaiter();
|
||||||
|
|
||||||
static u16 server_port;
|
static u16 server_port;
|
||||||
static std::atomic<bool> server_running;
|
static Common::Flag server_running;
|
||||||
static std::thread connectionThread;
|
static std::thread connectionThread;
|
||||||
static std::mutex connection_lock;
|
static std::mutex connection_lock;
|
||||||
static std::queue<std::unique_ptr<sf::TcpSocket>> waiting_socks;
|
static std::queue<std::unique_ptr<sf::TcpSocket>> waiting_socks;
|
||||||
|
|
|
@ -205,19 +205,13 @@ void GCMemcardDirectory::FlushThread()
|
||||||
// no-op until signalled
|
// no-op until signalled
|
||||||
m_flush_trigger.Wait();
|
m_flush_trigger.Wait();
|
||||||
|
|
||||||
if (m_exiting)
|
if (m_exiting.TestAndClear())
|
||||||
{
|
|
||||||
m_exiting = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
// no-op as long as signalled within flush_interval
|
// no-op as long as signalled within flush_interval
|
||||||
while (m_flush_trigger.WaitFor(flush_interval))
|
while (m_flush_trigger.WaitFor(flush_interval))
|
||||||
{
|
{
|
||||||
if (m_exiting)
|
if (m_exiting.TestAndClear())
|
||||||
{
|
|
||||||
m_exiting = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushToFile();
|
FlushToFile();
|
||||||
|
@ -226,7 +220,7 @@ void GCMemcardDirectory::FlushThread()
|
||||||
|
|
||||||
GCMemcardDirectory::~GCMemcardDirectory()
|
GCMemcardDirectory::~GCMemcardDirectory()
|
||||||
{
|
{
|
||||||
m_exiting = true;
|
m_exiting.Set();
|
||||||
m_flush_trigger.Set();
|
m_flush_trigger.Set();
|
||||||
m_flush_thread.join();
|
m_flush_thread.join();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -57,6 +56,6 @@ private:
|
||||||
const std::chrono::seconds flush_interval = std::chrono::seconds(1);
|
const std::chrono::seconds flush_interval = std::chrono::seconds(1);
|
||||||
Common::Event m_flush_trigger;
|
Common::Event m_flush_trigger;
|
||||||
std::mutex m_write_mutex;
|
std::mutex m_write_mutex;
|
||||||
std::atomic<bool> m_exiting;
|
Common::Flag m_exiting;
|
||||||
std::thread m_flush_thread;
|
std::thread m_flush_thread;
|
||||||
};
|
};
|
||||||
|
|
|
@ -326,7 +326,7 @@ void Wiimote::ConnectOnInput()
|
||||||
|
|
||||||
void Wiimote::Prepare()
|
void Wiimote::Prepare()
|
||||||
{
|
{
|
||||||
m_need_prepare.store(true);
|
m_need_prepare.Set();
|
||||||
IOWakeup();
|
IOWakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,47 +521,27 @@ void WiimoteScanner::ThreadFunc()
|
||||||
bool Wiimote::Connect(int index)
|
bool Wiimote::Connect(int index)
|
||||||
{
|
{
|
||||||
m_index = index;
|
m_index = index;
|
||||||
m_need_prepare.store(true);
|
m_need_prepare.Set();
|
||||||
|
|
||||||
if (!m_run_thread.load())
|
if (!m_run_thread.IsSet())
|
||||||
{
|
{
|
||||||
m_thread_ready.store(false);
|
|
||||||
StartThread();
|
StartThread();
|
||||||
WaitReady();
|
m_thread_ready_event.Wait();
|
||||||
}
|
}
|
||||||
return IsConnected();
|
return IsConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::StartThread()
|
void Wiimote::StartThread()
|
||||||
{
|
{
|
||||||
m_run_thread.store(true);
|
|
||||||
m_wiimote_thread = std::thread(&Wiimote::ThreadFunc, this);
|
m_wiimote_thread = std::thread(&Wiimote::ThreadFunc, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::StopThread()
|
void Wiimote::StopThread()
|
||||||
{
|
{
|
||||||
m_run_thread.store(false);
|
if (!m_run_thread.TestAndClear())
|
||||||
|
return;
|
||||||
IOWakeup();
|
IOWakeup();
|
||||||
if (m_wiimote_thread.joinable())
|
m_wiimote_thread.join();
|
||||||
m_wiimote_thread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Wiimote::SetReady()
|
|
||||||
{
|
|
||||||
if (!m_thread_ready.load())
|
|
||||||
{
|
|
||||||
m_thread_ready.store(true);
|
|
||||||
m_thread_ready_cond.notify_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Wiimote::WaitReady()
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_thread_ready_mutex);
|
|
||||||
while (!m_thread_ready.load())
|
|
||||||
{
|
|
||||||
m_thread_ready_cond.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::ThreadFunc()
|
void Wiimote::ThreadFunc()
|
||||||
|
@ -577,7 +557,8 @@ void Wiimote::ThreadFunc()
|
||||||
ok = ConnectInternal();
|
ok = ConnectInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetReady();
|
m_thread_ready_event.Set();
|
||||||
|
m_run_thread.Set();
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
|
@ -585,17 +566,13 @@ void Wiimote::ThreadFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
while (IsConnected() && m_run_thread.load())
|
while (IsConnected() && m_run_thread.IsSet())
|
||||||
{
|
{
|
||||||
if (m_need_prepare.load())
|
if (m_need_prepare.TestAndClear() && !PrepareOnThread())
|
||||||
{
|
{
|
||||||
m_need_prepare.store(false);
|
ERROR_LOG(WIIMOTE, "Wiimote::PrepareOnThread failed. Disconnecting Wiimote %d.",
|
||||||
if (!PrepareOnThread())
|
m_index + 1);
|
||||||
{
|
break;
|
||||||
ERROR_LOG(WIIMOTE, "Wiimote::PrepareOnThread failed. Disconnecting Wiimote %d.",
|
|
||||||
m_index + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Write();
|
Write();
|
||||||
Read();
|
Read();
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -95,20 +94,16 @@ private:
|
||||||
virtual void IOWakeup() = 0;
|
virtual void IOWakeup() = 0;
|
||||||
|
|
||||||
void ThreadFunc();
|
void ThreadFunc();
|
||||||
void SetReady();
|
|
||||||
void WaitReady();
|
|
||||||
|
|
||||||
bool m_rumble_state;
|
bool m_rumble_state;
|
||||||
|
|
||||||
std::thread m_wiimote_thread;
|
std::thread m_wiimote_thread;
|
||||||
// Whether to keep running the thread.
|
// Whether to keep running the thread.
|
||||||
std::atomic<bool> m_run_thread{false};
|
Common::Flag m_run_thread;
|
||||||
// Whether to call PrepareOnThread.
|
// Whether to call PrepareOnThread.
|
||||||
std::atomic<bool> m_need_prepare{false};
|
Common::Flag m_need_prepare;
|
||||||
// Whether the thread has finished ConnectInternal.
|
// Triggered when the thread has finished ConnectInternal.
|
||||||
std::atomic<bool> m_thread_ready{false};
|
Common::Event m_thread_ready_event;
|
||||||
std::mutex m_thread_ready_mutex;
|
|
||||||
std::condition_variable m_thread_ready_cond;
|
|
||||||
|
|
||||||
Common::FifoQueue<Report> m_read_reports;
|
Common::FifoQueue<Report> m_read_reports;
|
||||||
Common::FifoQueue<Report> m_write_reports;
|
Common::FifoQueue<Report> m_write_reports;
|
||||||
|
|
|
@ -36,12 +36,12 @@ NetSettings g_NetPlaySettings;
|
||||||
NetPlayClient::~NetPlayClient()
|
NetPlayClient::~NetPlayClient()
|
||||||
{
|
{
|
||||||
// not perfect
|
// not perfect
|
||||||
if (m_is_running.load())
|
if (m_is_running.IsSet())
|
||||||
StopGame();
|
StopGame();
|
||||||
|
|
||||||
if (m_is_connected)
|
if (m_is_connected)
|
||||||
{
|
{
|
||||||
m_do_loop.store(false);
|
m_do_loop.Clear();
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ void NetPlayClient::SendAsync(std::unique_ptr<sf::Packet> packet)
|
||||||
// called from ---NETPLAY--- thread
|
// called from ---NETPLAY--- thread
|
||||||
void NetPlayClient::ThreadFunc()
|
void NetPlayClient::ThreadFunc()
|
||||||
{
|
{
|
||||||
while (m_do_loop.load())
|
while (m_do_loop.IsSet())
|
||||||
{
|
{
|
||||||
ENetEvent netEvent;
|
ENetEvent netEvent;
|
||||||
int net;
|
int net;
|
||||||
|
@ -650,7 +650,7 @@ void NetPlayClient::ThreadFunc()
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
m_dialog->OnConnectionLost();
|
m_dialog->OnConnectionLost();
|
||||||
|
|
||||||
if (m_is_running.load())
|
if (m_is_running.IsSet())
|
||||||
StopGame();
|
StopGame();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -790,7 +790,7 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||||
SendStartGamePacket();
|
SendStartGamePacket();
|
||||||
|
|
||||||
if (m_is_running.load())
|
if (m_is_running.IsSet())
|
||||||
{
|
{
|
||||||
PanicAlertT("Game is already running!");
|
PanicAlertT("Game is already running!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -798,7 +798,7 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||||
|
|
||||||
m_timebase_frame = 0;
|
m_timebase_frame = 0;
|
||||||
|
|
||||||
m_is_running.store(true);
|
m_is_running.Set();
|
||||||
NetPlay_Enable(this);
|
NetPlay_Enable(this);
|
||||||
|
|
||||||
ClearBuffers();
|
ClearBuffers();
|
||||||
|
@ -998,7 +998,7 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, GCPadStatus* pad_status)
|
||||||
// other clients to send it to us
|
// other clients to send it to us
|
||||||
while (m_pad_buffer[pad_nb].Size() == 0)
|
while (m_pad_buffer[pad_nb].Size() == 0)
|
||||||
{
|
{
|
||||||
if (!m_is_running.load())
|
if (!m_is_running.IsSet())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1047,7 +1047,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
|
||||||
|
|
||||||
while (m_wiimote_buffer[_number].Size() == 0)
|
while (m_wiimote_buffer[_number].Size() == 0)
|
||||||
{
|
{
|
||||||
if (!m_is_running.load())
|
if (!m_is_running.IsSet())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1067,7 +1067,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
|
||||||
{
|
{
|
||||||
while (m_wiimote_buffer[_number].Size() == 0)
|
while (m_wiimote_buffer[_number].Size() == 0)
|
||||||
{
|
{
|
||||||
if (!m_is_running.load())
|
if (!m_is_running.IsSet())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1098,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
|
||||||
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
|
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
|
||||||
bool NetPlayClient::StopGame()
|
bool NetPlayClient::StopGame()
|
||||||
{
|
{
|
||||||
m_is_running.store(false);
|
m_is_running.Clear();
|
||||||
|
|
||||||
// stop waiting for input
|
// stop waiting for input
|
||||||
m_gc_pad_event.Set();
|
m_gc_pad_event.Set();
|
||||||
|
@ -1115,10 +1115,10 @@ bool NetPlayClient::StopGame()
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
void NetPlayClient::Stop()
|
void NetPlayClient::Stop()
|
||||||
{
|
{
|
||||||
if (!m_is_running.load())
|
if (!m_is_running.IsSet())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_is_running.store(false);
|
m_is_running.Clear();
|
||||||
|
|
||||||
// stop waiting for input
|
// stop waiting for input
|
||||||
m_gc_pad_event.Set();
|
m_gc_pad_event.Set();
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <SFML/Network/Packet.hpp>
|
#include <SFML/Network/Packet.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -124,8 +123,8 @@ protected:
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
std::string m_selected_game;
|
std::string m_selected_game;
|
||||||
std::atomic<bool> m_is_running{false};
|
Common::Flag m_is_running{false};
|
||||||
std::atomic<bool> m_do_loop{true};
|
Common::Flag m_do_loop{true};
|
||||||
|
|
||||||
unsigned int m_target_buffer_size = 20;
|
unsigned int m_target_buffer_size = 20;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ AsyncRequests::AsyncRequests() : m_enable(false), m_passthrough(true)
|
||||||
void AsyncRequests::PullEventsInternal()
|
void AsyncRequests::PullEventsInternal()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_empty.store(true);
|
m_empty.Set();
|
||||||
|
|
||||||
while (!m_queue.empty())
|
while (!m_queue.empty())
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_empty.store(false);
|
m_empty.Clear();
|
||||||
m_wake_me_up_again |= blocking;
|
m_wake_me_up_again |= blocking;
|
||||||
|
|
||||||
if (!m_enable)
|
if (!m_enable)
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
|
|
||||||
struct EfbPokeData;
|
struct EfbPokeData;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public:
|
||||||
|
|
||||||
void PullEvents()
|
void PullEvents()
|
||||||
{
|
{
|
||||||
if (!m_empty.load())
|
if (!m_empty.IsSet())
|
||||||
PullEventsInternal();
|
PullEventsInternal();
|
||||||
}
|
}
|
||||||
void PushEvent(const Event& event, bool blocking = false);
|
void PushEvent(const Event& event, bool blocking = false);
|
||||||
|
@ -84,7 +84,7 @@ private:
|
||||||
|
|
||||||
static AsyncRequests s_singleton;
|
static AsyncRequests s_singleton;
|
||||||
|
|
||||||
std::atomic<bool> m_empty;
|
Common::Flag m_empty;
|
||||||
std::queue<Event> m_queue;
|
std::queue<Event> m_queue;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
std::condition_variable m_cond;
|
std::condition_variable m_cond;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Common/Atomic.h"
|
#include "Common/Atomic.h"
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
|
@ -36,8 +37,8 @@ static u16 m_bboxright;
|
||||||
static u16 m_bboxbottom;
|
static u16 m_bboxbottom;
|
||||||
static u16 m_tokenReg;
|
static u16 m_tokenReg;
|
||||||
|
|
||||||
static std::atomic<bool> s_interrupt_set;
|
static Common::Flag s_interrupt_set;
|
||||||
static std::atomic<bool> s_interrupt_waiting;
|
static Common::Flag s_interrupt_waiting;
|
||||||
|
|
||||||
static bool IsOnThread()
|
static bool IsOnThread()
|
||||||
{
|
{
|
||||||
|
@ -106,8 +107,8 @@ void Init()
|
||||||
fifo.bFF_LoWatermark = 0;
|
fifo.bFF_LoWatermark = 0;
|
||||||
fifo.bFF_LoWatermarkInt = 0;
|
fifo.bFF_LoWatermarkInt = 0;
|
||||||
|
|
||||||
s_interrupt_set.store(false);
|
s_interrupt_set.Clear();
|
||||||
s_interrupt_waiting.store(false);
|
s_interrupt_waiting.Clear();
|
||||||
|
|
||||||
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
|
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
|
||||||
}
|
}
|
||||||
|
@ -324,18 +325,18 @@ void UpdateInterrupts(u64 userdata)
|
||||||
{
|
{
|
||||||
if (userdata)
|
if (userdata)
|
||||||
{
|
{
|
||||||
s_interrupt_set.store(true);
|
s_interrupt_set.Set();
|
||||||
INFO_LOG(COMMANDPROCESSOR, "Interrupt set");
|
INFO_LOG(COMMANDPROCESSOR, "Interrupt set");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_interrupt_set.store(false);
|
s_interrupt_set.Clear();
|
||||||
INFO_LOG(COMMANDPROCESSOR, "Interrupt cleared");
|
INFO_LOG(COMMANDPROCESSOR, "Interrupt cleared");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
|
||||||
}
|
}
|
||||||
CoreTiming::ForceExceptionCheck(0);
|
CoreTiming::ForceExceptionCheck(0);
|
||||||
s_interrupt_waiting.store(false);
|
s_interrupt_waiting.Clear();
|
||||||
Fifo::RunGpu();
|
Fifo::RunGpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +348,7 @@ void UpdateInterruptsFromVideoBackend(u64 userdata)
|
||||||
|
|
||||||
bool IsInterruptWaiting()
|
bool IsInterruptWaiting()
|
||||||
{
|
{
|
||||||
return s_interrupt_waiting.load();
|
return s_interrupt_waiting.IsSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCPStatusFromGPU()
|
void SetCPStatusFromGPU()
|
||||||
|
@ -387,7 +388,7 @@ void SetCPStatusFromGPU()
|
||||||
|
|
||||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load())
|
if (interrupt != s_interrupt_set.IsSet() && !s_interrupt_waiting.IsSet())
|
||||||
{
|
{
|
||||||
u64 userdata = interrupt ? 1 : 0;
|
u64 userdata = interrupt ? 1 : 0;
|
||||||
if (IsOnThread())
|
if (IsOnThread())
|
||||||
|
@ -395,7 +396,7 @@ void SetCPStatusFromGPU()
|
||||||
if (!interrupt || bpInt || undfInt || ovfInt)
|
if (!interrupt || bpInt || undfInt || ovfInt)
|
||||||
{
|
{
|
||||||
// Schedule the interrupt asynchronously
|
// Schedule the interrupt asynchronously
|
||||||
s_interrupt_waiting.store(true);
|
s_interrupt_waiting.Set();
|
||||||
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,14 +419,14 @@ void SetCPStatusFromCPU()
|
||||||
|
|
||||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load())
|
if (interrupt != s_interrupt_set.IsSet() && !s_interrupt_waiting.IsSet())
|
||||||
{
|
{
|
||||||
u64 userdata = interrupt ? 1 : 0;
|
u64 userdata = interrupt ? 1 : 0;
|
||||||
if (IsOnThread())
|
if (IsOnThread())
|
||||||
{
|
{
|
||||||
if (!interrupt || bpInt || undfInt || ovfInt)
|
if (!interrupt || bpInt || undfInt || ovfInt)
|
||||||
{
|
{
|
||||||
s_interrupt_set.store(interrupt);
|
s_interrupt_set.Set(interrupt);
|
||||||
INFO_LOG(COMMANDPROCESSOR, "Interrupt set");
|
INFO_LOG(COMMANDPROCESSOR, "Interrupt set");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ static bool s_skip_current_frame = false;
|
||||||
|
|
||||||
static Common::BlockingLoop s_gpu_mainloop;
|
static Common::BlockingLoop s_gpu_mainloop;
|
||||||
|
|
||||||
static std::atomic<bool> s_emu_running_state;
|
static Common::Flag s_emu_running_state;
|
||||||
|
|
||||||
// Most of this array is unlikely to be faulted in...
|
// Most of this array is unlikely to be faulted in...
|
||||||
static u8 s_fifo_aux_data[FIFO_SIZE];
|
static u8 s_fifo_aux_data[FIFO_SIZE];
|
||||||
|
@ -147,13 +147,13 @@ void ExitGpuLoop()
|
||||||
FlushGpu();
|
FlushGpu();
|
||||||
|
|
||||||
// Terminate GPU thread loop
|
// Terminate GPU thread loop
|
||||||
s_emu_running_state.store(true);
|
s_emu_running_state.Set();
|
||||||
s_gpu_mainloop.Stop(false);
|
s_gpu_mainloop.Stop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatorState(bool running)
|
void EmulatorState(bool running)
|
||||||
{
|
{
|
||||||
s_emu_running_state.store(running);
|
s_emu_running_state.Set(running);
|
||||||
if (running)
|
if (running)
|
||||||
s_gpu_mainloop.Wakeup();
|
s_gpu_mainloop.Wakeup();
|
||||||
else
|
else
|
||||||
|
@ -307,7 +307,7 @@ void RunGpuLoop()
|
||||||
g_video_backend->PeekMessages();
|
g_video_backend->PeekMessages();
|
||||||
|
|
||||||
// Do nothing while paused
|
// Do nothing while paused
|
||||||
if (!s_emu_running_state.load())
|
if (!s_emu_running_state.IsSet())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s_use_deterministic_gpu_thread)
|
if (s_use_deterministic_gpu_thread)
|
||||||
|
|
Loading…
Reference in New Issue