Core: Convert volatile bools to atomics

Converts over bools that are typically used as loop checks into atomics.
This commit is contained in:
Lioncash 2015-05-21 19:52:26 -04:00
parent 01ec940650
commit de2e84344d
6 changed files with 63 additions and 64 deletions

View File

@ -14,7 +14,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;
volatile bool GeckoSockServer::server_running; std::atomic<bool> 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;
@ -31,13 +31,13 @@ GeckoSockServer::~GeckoSockServer()
{ {
--client_count; --client_count;
client_running = false; client_running.store(false);
clientThread.join(); clientThread.join();
} }
if (client_count <= 0) if (client_count <= 0)
{ {
server_running = false; server_running.store(false);
connectionThread.join(); connectionThread.join();
} }
} }
@ -48,14 +48,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; bind_tries++) for (int bind_tries = 0; bind_tries <= 10 && !server_running.load(); bind_tries++)
{ {
server_running = server.listen(server_port) == sf::Socket::Done; server_running.store(server.listen(server_port) == sf::Socket::Done);
if (!server_running) if (!server_running.load())
server_port++; server_port++;
} }
if (!server_running) if (!server_running.load())
return; return;
Core::DisplayMessage( Core::DisplayMessage(
@ -65,7 +65,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) while (server_running.load())
{ {
if (server.accept(*new_client) == sf::Socket::Done) if (server.accept(*new_client) == sf::Socket::Done)
{ {
@ -89,7 +89,7 @@ bool GeckoSockServer::GetAvailableSock()
client = std::move(waiting_socks.front()); client = std::move(waiting_socks.front());
if (clientThread.joinable()) if (clientThread.joinable())
{ {
client_running = false; client_running.store(false);
clientThread.join(); clientThread.join();
recv_fifo = std::deque<u8>(); recv_fifo = std::deque<u8>();
@ -106,13 +106,13 @@ bool GeckoSockServer::GetAvailableSock()
void GeckoSockServer::ClientThread() void GeckoSockServer::ClientThread()
{ {
client_running = true; client_running.store(true);
Common::SetCurrentThreadName("Gecko Client"); Common::SetCurrentThreadName("Gecko Client");
client->setBlocking(false); client->setBlocking(false);
while (client_running) while (client_running.load())
{ {
bool did_nothing = true; bool did_nothing = true;
@ -124,7 +124,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 = false; client_running.store(false);
if (got != 0) if (got != 0)
{ {
@ -141,7 +141,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 = false; client_running.store(false);
} }
} // unlock transfer } // unlock transfer

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <atomic>
#include <deque> #include <deque>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -31,14 +32,14 @@ public:
std::deque<u8> recv_fifo; std::deque<u8> recv_fifo;
private: private:
static int client_count; static int client_count;
volatile bool client_running; std::atomic<bool> 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 volatile bool server_running; static std::atomic<bool> 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;

View File

@ -302,7 +302,7 @@ void Wiimote::Update()
void Wiimote::Prepare(int _index) void Wiimote::Prepare(int _index)
{ {
m_index = _index; m_index = _index;
m_need_prepare = true; m_need_prepare.store(true);
} }
bool Wiimote::PrepareOnThread() bool Wiimote::PrepareOnThread()
@ -406,27 +406,27 @@ static unsigned int CalculateWantedBB()
void WiimoteScanner::WantWiimotes(bool do_want) void WiimoteScanner::WantWiimotes(bool do_want)
{ {
m_want_wiimotes = do_want; m_want_wiimotes.store(do_want);
} }
void WiimoteScanner::WantBB(bool do_want) void WiimoteScanner::WantBB(bool do_want)
{ {
m_want_bb = do_want; m_want_bb.store(do_want);
} }
void WiimoteScanner::StartScanning() void WiimoteScanner::StartScanning()
{ {
if (!m_run_thread) if (!m_run_thread.load())
{ {
m_run_thread = true; m_run_thread.store(true);
m_scan_thread = std::thread(&WiimoteScanner::ThreadFunc, this); m_scan_thread = std::thread(&WiimoteScanner::ThreadFunc, this);
} }
} }
void WiimoteScanner::StopScanning() void WiimoteScanner::StopScanning()
{ {
m_run_thread = false; m_run_thread.store(false);
if (m_scan_thread.joinable()) if (m_scan_thread.joinable())
{ {
m_scan_thread.join(); m_scan_thread.join();
@ -448,14 +448,14 @@ void WiimoteScanner::ThreadFunc()
NOTICE_LOG(WIIMOTE, "Wiimote scanning has started."); NOTICE_LOG(WIIMOTE, "Wiimote scanning has started.");
while (m_run_thread) while (m_run_thread.load())
{ {
std::vector<Wiimote*> found_wiimotes; std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = nullptr; Wiimote* found_board = nullptr;
//NOTICE_LOG(WIIMOTE, "In loop"); //NOTICE_LOG(WIIMOTE, "In loop");
if (m_want_wiimotes || m_want_bb) if (m_want_wiimotes.load() || m_want_bb.load())
{ {
FindWiimotes(found_wiimotes, found_board); FindWiimotes(found_wiimotes, found_board);
} }
@ -470,9 +470,10 @@ void WiimoteScanner::ThreadFunc()
// TODO: this is a fairly lame place for this // TODO: this is a fairly lame place for this
CheckForDisconnectedWiimotes(); CheckForDisconnectedWiimotes();
if (m_want_wiimotes) if (m_want_wiimotes.load())
HandleFoundWiimotes(found_wiimotes); HandleFoundWiimotes(found_wiimotes);
if (m_want_bb && found_board)
if (m_want_bb.load() && found_board)
TryToConnectBalanceBoard(found_board); TryToConnectBalanceBoard(found_board);
//std::this_thread::yield(); //std::this_thread::yield();
@ -484,7 +485,7 @@ void WiimoteScanner::ThreadFunc()
bool Wiimote::Connect() bool Wiimote::Connect()
{ {
m_thread_ready = false; m_thread_ready.store(false);
StartThread(); StartThread();
WaitReady(); WaitReady();
return IsConnected(); return IsConnected();
@ -492,13 +493,13 @@ bool Wiimote::Connect()
void Wiimote::StartThread() void Wiimote::StartThread()
{ {
m_run_thread = true; 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 = false; m_run_thread.store(false);
IOWakeup(); IOWakeup();
if (m_wiimote_thread.joinable()) if (m_wiimote_thread.joinable())
m_wiimote_thread.join(); m_wiimote_thread.join();
@ -506,12 +507,9 @@ void Wiimote::StopThread()
void Wiimote::SetReady() void Wiimote::SetReady()
{ {
if (!m_thread_ready) if (!m_thread_ready.load())
{ {
{ m_thread_ready.store(true);
std::lock_guard<std::mutex> Guard(m_thread_ready_mutex);
m_thread_ready = true;
}
m_thread_ready_cond.notify_all(); m_thread_ready_cond.notify_all();
} }
} }
@ -519,7 +517,7 @@ void Wiimote::SetReady()
void Wiimote::WaitReady() void Wiimote::WaitReady()
{ {
std::unique_lock<std::mutex> lock(m_thread_ready_mutex); std::unique_lock<std::mutex> lock(m_thread_ready_mutex);
while (!m_thread_ready) while (!m_thread_ready.load())
{ {
m_thread_ready_cond.wait(lock); m_thread_ready_cond.wait(lock);
} }
@ -546,11 +544,11 @@ void Wiimote::ThreadFunc()
} }
// main loop // main loop
while (IsConnected() && m_run_thread) while (IsConnected() && m_run_thread.load())
{ {
if (m_need_prepare) if (m_need_prepare.load())
{ {
m_need_prepare = false; m_need_prepare.store(false);
if (!PrepareOnThread()) if (!PrepareOnThread())
{ {
ERROR_LOG(WIIMOTE, "Wiimote::PrepareOnThread failed. Disconnecting Wiimote %d.", m_index + 1); ERROR_LOG(WIIMOTE, "Wiimote::PrepareOnThread failed. Disconnecting Wiimote %d.", m_index + 1);

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <atomic>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -96,11 +97,11 @@ private:
std::thread m_wiimote_thread; std::thread m_wiimote_thread;
// Whether to keep running the thread. // Whether to keep running the thread.
volatile bool m_run_thread; std::atomic<bool> m_run_thread;
// Whether to call PrepareOnThread. // Whether to call PrepareOnThread.
volatile bool m_need_prepare; std::atomic<bool> m_need_prepare;
// Whether the thread has finished ConnectInternal. // Whether the thread has finished ConnectInternal.
volatile bool m_thread_ready; std::atomic<bool> m_thread_ready;
std::mutex m_thread_ready_mutex; std::mutex m_thread_ready_mutex;
std::condition_variable m_thread_ready_cond; std::condition_variable m_thread_ready_cond;
@ -134,9 +135,9 @@ private:
std::thread m_scan_thread; std::thread m_scan_thread;
volatile bool m_run_thread; std::atomic<bool> m_run_thread;
volatile bool m_want_wiimotes; std::atomic<bool> m_want_wiimotes;
volatile bool m_want_bb; std::atomic<bool> m_want_bb;
#if defined(_WIN32) #if defined(_WIN32)
void CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb); void CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb);

View File

@ -26,12 +26,12 @@ NetSettings g_NetPlaySettings;
NetPlayClient::~NetPlayClient() NetPlayClient::~NetPlayClient()
{ {
// not perfect // not perfect
if (m_is_running) if (m_is_running.load())
StopGame(); StopGame();
if (is_connected) if (is_connected)
{ {
m_do_loop = false; m_do_loop.store(false);
m_thread.join(); m_thread.join();
} }
@ -409,8 +409,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_DISABLE_GAME: case NP_MSG_DISABLE_GAME:
{ {
PanicAlertT("Other client disconnected while game is running!! NetPlay is disabled. You must manually stop the game."); PanicAlertT("Other client disconnected while game is running!! NetPlay is disabled. You must manually stop the game.");
std::lock_guard<std::recursive_mutex> lkg(m_crit.game); m_is_running.store(false);
m_is_running = false;
NetPlay_Disable(); NetPlay_Disable();
} }
break; break;
@ -499,7 +498,7 @@ void NetPlayClient::SendAsync(sf::Packet* packet)
// called from ---NETPLAY--- thread // called from ---NETPLAY--- thread
void NetPlayClient::ThreadFunc() void NetPlayClient::ThreadFunc()
{ {
while (m_do_loop) while (m_do_loop.load())
{ {
ENetEvent netEvent; ENetEvent netEvent;
int net; int net;
@ -523,11 +522,11 @@ void NetPlayClient::ThreadFunc()
enet_packet_destroy(netEvent.packet); enet_packet_destroy(netEvent.packet);
break; break;
case ENET_EVENT_TYPE_DISCONNECT: case ENET_EVENT_TYPE_DISCONNECT:
m_is_running = false; m_is_running.store(false);
NetPlay_Disable(); NetPlay_Disable();
m_dialog->AppendChat("< LOST CONNECTION TO SERVER >"); m_dialog->AppendChat("< LOST CONNECTION TO SERVER >");
PanicAlertT("Lost connection to server!"); PanicAlertT("Lost connection to server!");
m_do_loop = false; m_do_loop.store(false);
netEvent.peer->data = nullptr; netEvent.peer->data = nullptr;
break; break;
@ -636,7 +635,7 @@ bool NetPlayClient::StartGame(const std::string &path)
*spac << (char *)&g_NetPlaySettings; *spac << (char *)&g_NetPlaySettings;
SendAsync(spac); SendAsync(spac);
if (m_is_running) if (m_is_running.load())
{ {
PanicAlertT("Game is already running!"); PanicAlertT("Game is already running!");
return false; return false;
@ -644,7 +643,7 @@ bool NetPlayClient::StartGame(const std::string &path)
m_dialog->AppendChat(" -- STARTING GAME -- "); m_dialog->AppendChat(" -- STARTING GAME -- ");
m_is_running = true; m_is_running.store(true);
NetPlay_Enable(this); NetPlay_Enable(this);
ClearBuffers(); ClearBuffers();
@ -823,7 +822,7 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, GCPadStatus* pad_status)
// to retrieve data for slot 1. // to retrieve data for slot 1.
while (!m_pad_buffer[pad_nb].Pop(*pad_status)) while (!m_pad_buffer[pad_nb].Pop(*pad_status))
{ {
if (!m_is_running) if (!m_is_running.load())
return false; return false;
// TODO: use a condition instead of sleeping // TODO: use a condition instead of sleeping
@ -893,7 +892,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
{ {
// wait for receiving thread to push some data // wait for receiving thread to push some data
Common::SleepCurrentThread(1); Common::SleepCurrentThread(1);
if (false == m_is_running) if (!m_is_running.load())
return false; return false;
} }
@ -918,7 +917,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
while (!m_wiimote_buffer[_number].Pop(nw)) while (!m_wiimote_buffer[_number].Pop(nw))
{ {
Common::SleepCurrentThread(1); Common::SleepCurrentThread(1);
if (false == m_is_running) if (!m_is_running.load())
return false; return false;
} }
++tries; ++tries;
@ -942,9 +941,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()
{ {
std::lock_guard<std::recursive_mutex> lkg(m_crit.game); if (!m_is_running.load())
if (false == m_is_running)
{ {
PanicAlertT("Game isn't running!"); PanicAlertT("Game isn't running!");
return false; return false;
@ -952,7 +949,7 @@ bool NetPlayClient::StopGame()
m_dialog->AppendChat(" -- STOPPING GAME -- "); m_dialog->AppendChat(" -- STOPPING GAME -- ");
m_is_running = false; m_is_running.store(false);
NetPlay_Disable(); NetPlay_Disable();
// stop game // stop game
@ -964,8 +961,9 @@ bool NetPlayClient::StopGame()
// called from ---GUI--- thread // called from ---GUI--- thread
void NetPlayClient::Stop() void NetPlayClient::Stop()
{ {
if (m_is_running == false) if (!m_is_running.load())
return; return;
bool isPadMapped = false; bool isPadMapped = false;
for (PadMapping mapping : m_pad_map) for (PadMapping mapping : m_pad_map)
{ {

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <atomic>
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <queue> #include <queue>
@ -108,9 +109,9 @@ protected:
ENetPeer* m_server; ENetPeer* m_server;
std::thread m_thread; std::thread m_thread;
std::string m_selected_game; std::string m_selected_game;
volatile bool m_is_running; std::atomic<bool> m_is_running;
volatile bool m_do_loop; std::atomic<bool> m_do_loop;
unsigned int m_target_buffer_size; unsigned int m_target_buffer_size;