Replaced Common::CriticalSection with a std::mutex implementation. 64bit Windows builds now use SRWLocks and ConditionVariables(requires Vista/7, x64 builds will no longer work on Windows XP x64). Tell me if you hate that. Removed Common::EventEx. Common::Event now uses a std::condition_variable impl.(using ConditionVariables on Windows x64, Events on x86, or posix condition variables elsewhere). I experience slight speed improvements with these changes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7294 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2011-03-05 06:11:26 +00:00
commit 423018f811
56 changed files with 918 additions and 835 deletions

View file

@ -102,8 +102,8 @@ static std::thread cpuThread;
SCoreStartupParameter g_CoreStartupParameter;
// This event is set when the emuthread starts.
Common::Event emuThreadGoing;
Common::Event cpuRunloopQuit;
Common::Barrier emuThreadGoing(2);
Common::Barrier cpuRunloopQuit(2);
std::string GetStateFileName() { return g_stateFileName; }
void SetStateFileName(std::string val) { g_stateFileName = val; }
@ -248,14 +248,11 @@ bool Init()
// The hardware is initialized.
g_bHwInit = true;
emuThreadGoing.Init();
// Start the emu thread
g_EmuThread = std::thread(EmuThread);
// Wait until the emu thread is running
emuThreadGoing.MsgWait();
emuThreadGoing.Shutdown();
emuThreadGoing.Wait();
Host_SetWaitCursor(false);
@ -359,7 +356,7 @@ void CpuThread()
// Enter CPU run loop. When we leave it - we are done.
CCPU::Run();
cpuRunloopQuit.Set();
cpuRunloopQuit.Wait();
return;
}
@ -372,8 +369,6 @@ void EmuThread()
const SCoreStartupParameter& _CoreParameter =
SConfig::GetInstance().m_LocalCoreStartupParameter;
cpuRunloopQuit.Init();
Common::SetCurrentThreadName("Emuthread - starting");
if (_CoreParameter.bLockThreads)
@ -384,7 +379,7 @@ void EmuThread()
Common::SetCurrentThreadAffinity(2);
}
emuThreadGoing.Set();
emuThreadGoing.Wait();
DisplayMessage("CPU: " + cpu_info.Summarize(), 8000);
DisplayMessage(_CoreParameter.m_strFilename, 3000);
@ -462,7 +457,6 @@ void EmuThread()
VolumeHandler::EjectVolume();
FileMon::Close();
cpuRunloopQuit.Shutdown();
g_bStopping = false;
}

View file

@ -68,7 +68,7 @@ u64 fakeDecStartTicks;
u64 fakeTBStartValue;
u64 fakeTBStartTicks;
static Common::CriticalSection externalEventSection;
static std::mutex externalEventSection;
void (*advanceCallback)(int cyclesExecuted) = NULL;
@ -143,19 +143,18 @@ void Shutdown()
delete ev;
}
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
while(eventTsPool)
{
Event *ev = eventTsPool;
eventTsPool = ev->next;
delete ev;
}
externalEventSection.Leave();
}
void DoState(PointerWrap &p)
{
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
p.Do(downcount);
p.Do(slicelength);
p.Do(globalTimer);
@ -210,7 +209,6 @@ void DoState(PointerWrap &p)
break;
}
}
externalEventSection.Leave();
}
u64 GetTicks()
@ -227,7 +225,7 @@ u64 GetIdleTicks()
// schedule things to be executed on the main thread.
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata)
{
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
Event *ne = GetNewTsEvent();
ne->time = globalTimer + cyclesIntoFuture;
ne->type = event_type;
@ -238,7 +236,6 @@ void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata
if(tsLast)
tsLast->next = ne;
tsLast = ne;
externalEventSection.Leave();
}
// Same as ScheduleEvent_Threadsafe(0, ...) EXCEPT if we are already on the CPU thread
@ -247,9 +244,8 @@ void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata)
{
if(Core::IsCPUThread())
{
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
event_types[event_type].callback(userdata, 0);
externalEventSection.Leave();
}
else
ScheduleEvent_Threadsafe(0, event_type, userdata);
@ -352,10 +348,9 @@ void RemoveEvent(int event_type)
void RemoveThreadsafeEvent(int event_type)
{
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
if (!tsFirst)
{
externalEventSection.Leave();
return;
}
while(tsFirst)
@ -373,7 +368,6 @@ void RemoveThreadsafeEvent(int event_type)
}
if (!tsFirst)
{
externalEventSection.Leave();
return;
}
Event *prev = tsFirst;
@ -392,7 +386,6 @@ void RemoveThreadsafeEvent(int event_type)
ptr = ptr->next;
}
}
externalEventSection.Leave();
}
void RemoveAllEvents(int event_type)
@ -438,8 +431,7 @@ void ProcessFifoWaitEvents()
void MoveEvents()
{
externalEventSection.Enter();
std::lock_guard<std::mutex> lk(externalEventSection);
// Move events from async queue into main queue
while (tsFirst)
{
@ -458,8 +450,6 @@ void MoveEvents()
eventTsPool = ev;
allocatedTsEvents--;
}
externalEventSection.Leave();
}
void Advance()

View file

@ -41,7 +41,7 @@ DSPCoreState core_state = DSPCORE_STOP;
u16 cyclesLeft = 0;
DSPEmitter *dspjit = NULL;
Common::Event step_event;
Common::CriticalSection ExtIntCriticalSection;
static std::mutex ExtIntCriticalSection;
static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
{
@ -165,8 +165,6 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
DSPAnalyzer::Analyze();
step_event.Init();
core_state = DSPCORE_RUNNING;
return true;
@ -183,7 +181,6 @@ void DSPCore_Shutdown()
delete dspjit;
dspjit = NULL;
}
step_event.Shutdown();
DSPCore_FreeMemoryPages();
}
@ -206,9 +203,8 @@ void DSPCore_SetException(u8 level)
// Notify that an external interrupt is pending (used by thread mode)
void DSPCore_SetExternalInterrupt(bool val)
{
ExtIntCriticalSection.Enter();
std::lock_guard<std::mutex> lk(ExtIntCriticalSection);
g_dsp.external_interrupt_waiting = val;
ExtIntCriticalSection.Leave();
}
// Coming from the CPU

View file

@ -249,7 +249,7 @@ struct SDSP
volatile u16 mbox[2][2];
// Mutex protecting the mailbox.
Common::CriticalSection g_CriticalSection;
std::mutex g_CriticalSection;
// Accelerator / DMA / other hardware registers. Not GPRs.
u16 ifx_regs[256];

View file

@ -41,7 +41,7 @@
static void gdsp_do_dma();
Common::CriticalSection g_CriticalSection;
static std::mutex g_CriticalSection;
void gdsp_ifx_init()
{
@ -56,35 +56,34 @@ void gdsp_ifx_init()
g_dsp.mbox[1][1] = 0;
}
u32 gdsp_mbox_peek(u8 mbx)
{
std::unique_lock<std::mutex> lk(g_CriticalSection, std::defer_lock);
if (DSPHost_OnThread())
g_CriticalSection.Enter();
u32 value = ((g_dsp.mbox[mbx][0] << 16) | g_dsp.mbox[mbx][1]);
if (DSPHost_OnThread())
g_CriticalSection.Leave();
return value;
lk.lock();
return ((g_dsp.mbox[mbx][0] << 16) | g_dsp.mbox[mbx][1]);
}
void gdsp_mbox_write_h(u8 mbx, u16 val)
{
std::unique_lock<std::mutex> lk(g_CriticalSection, std::defer_lock);
if (DSPHost_OnThread())
g_CriticalSection.Enter();
g_dsp.mbox[mbx][0] = val & 0x7fff;
if (DSPHost_OnThread())
g_CriticalSection.Leave();
}
lk.lock();
g_dsp.mbox[mbx][0] = val & 0x7fff;
}
void gdsp_mbox_write_l(u8 mbx, u16 val)
{
{
std::unique_lock<std::mutex> lk(g_CriticalSection, std::defer_lock);
if (DSPHost_OnThread())
g_CriticalSection.Enter();
lk.lock();
g_dsp.mbox[mbx][1] = val;
g_dsp.mbox[mbx][0] |= 0x8000;
if (DSPHost_OnThread())
g_CriticalSection.Leave();
}
#if defined(_DEBUG) || defined(DEBUGFAST)
if (mbx == GDSP_MBOX_DSP)
@ -96,29 +95,27 @@ void gdsp_mbox_write_l(u8 mbx, u16 val)
#endif
}
u16 gdsp_mbox_read_h(u8 mbx)
{
std::unique_lock<std::mutex> lk(g_CriticalSection, std::defer_lock);
if (DSPHost_OnThread())
g_CriticalSection.Enter();
u16 val = g_dsp.mbox[mbx][0]; // TODO: mask away the top bit?
if (DSPHost_OnThread())
g_CriticalSection.Leave();
return val;
lk.lock();
return g_dsp.mbox[mbx][0]; // TODO: mask away the top bit?
}
u16 gdsp_mbox_read_l(u8 mbx)
{
u16 val;
{
std::unique_lock<std::mutex> lk(g_CriticalSection, std::defer_lock);
if (DSPHost_OnThread())
g_CriticalSection.Enter();
lk.lock();
u16 val = g_dsp.mbox[mbx][1];
val = g_dsp.mbox[mbx][1];
g_dsp.mbox[mbx][0] &= ~0x8000;
if (DSPHost_OnThread())
g_CriticalSection.Leave();
}
#if defined(_DEBUG) || defined(DEBUGFAST)
if (mbx == GDSP_MBOX_DSP)
@ -132,7 +129,6 @@ u16 gdsp_mbox_read_l(u8 mbx)
return val;
}
void gdsp_ifx_write(u32 addr, u32 val)
{
switch (addr & 0xff)

View file

@ -55,7 +55,7 @@ u32 GeckoCode::Code::GetAddress() const
return gcaddress + (use_po ? pointer_address : (base_address & 0xFE000000));
}
static Common::CriticalSection active_codes_lock;
static std::mutex active_codes_lock;
// currently running code
static GeckoCode::Code *codes_start = NULL, *current_code = NULL;
@ -78,7 +78,7 @@ bool MathOperation(u32& ret, const u32 left, const u32 right, const u8 type);
void SetActiveCodes(const std::vector<GeckoCode>& gcodes)
{
active_codes_lock.Enter();
std::lock_guard<std::mutex> lk(active_codes_lock);
active_codes.clear();
// add enabled codes
@ -94,8 +94,6 @@ void SetActiveCodes(const std::vector<GeckoCode>& gcodes)
}
inserted_asm_codes.clear();
active_codes_lock.Leave();
}
bool RunGeckoCode(GeckoCode& gecko_code)
@ -151,24 +149,23 @@ bool RunGeckoCode(GeckoCode& gecko_code)
bool RunActiveCodes()
{
if (false == SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
return true;
if (false == active_codes_lock.TryEnter())
return true;
std::vector<GeckoCode>::iterator
gcodes_iter = active_codes.begin(),
gcodes_end = active_codes.end();
for (; gcodes_iter!=gcodes_end; ++gcodes_iter)
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
{
if (gcodes_iter->enabled)
RunGeckoCode(*gcodes_iter);
// we don't need to stop all codes if one fails, maybe
//if (false == RunGeckoCode(*gcodes_iter))
//return false;
std::lock_guard<std::mutex> lk(active_codes_lock);
std::vector<GeckoCode>::iterator
gcodes_iter = active_codes.begin(),
gcodes_end = active_codes.end();
for (; gcodes_iter!=gcodes_end; ++gcodes_iter)
{
if (gcodes_iter->enabled)
RunGeckoCode(*gcodes_iter);
// we don't need to stop all codes if one fails, maybe
//if (false == RunGeckoCode(*gcodes_iter))
//return false;
}
}
active_codes_lock.Leave();
return true;
}

View file

@ -35,7 +35,6 @@ namespace
void CCPU::Init(int cpu_core)
{
m_StepEvent.Init();
PowerPC::Init(cpu_core);
m_SyncEvent = 0;
}
@ -43,7 +42,6 @@ void CCPU::Init(int cpu_core)
void CCPU::Shutdown()
{
PowerPC::Shutdown();
m_StepEvent.Shutdown();
m_SyncEvent = 0;
}

View file

@ -570,7 +570,7 @@ void CUCode_Zelda::ExecuteList()
void CUCode_Zelda::DoState(PointerWrap &p)
{
// It's bad if we try to save during Mix()
m_csMix.Enter();
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(m_CRC);
@ -618,6 +618,4 @@ void CUCode_Zelda::DoState(PointerWrap &p)
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
m_csMix.Leave();
}

View file

@ -746,7 +746,7 @@ ContinueWithBlock:
// size is in stereo samples.
void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
{
m_csMix.Enter();
std::lock_guard<std::mutex> lk(m_csMix);
// Safety check
if (_Size > 256 * 1024 - 8)
_Size = 256 * 1024 - 8;
@ -793,5 +793,4 @@ void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
_Buffer += 2;
}
m_csMix.Leave();
}

View file

@ -86,7 +86,7 @@ protected:
bool NeedsResumeMail();
CMailHandler& m_rMailHandler;
Common::CriticalSection m_csMix;
std::mutex m_csMix;
enum EDSP_Codes
{

View file

@ -215,7 +215,7 @@ static unsigned char media_buffer[0x40];
// Needed because data and streaming audio access needs to be managed by the "drive"
// (both requests can happen at the same time, audio takes precedence)
Common::CriticalSection dvdread_section;
static std::mutex dvdread_section;
static int ejectDisc;
static int insertDisc;
@ -345,10 +345,8 @@ void ClearCoverInterrupt()
bool DVDRead(u32 _iDVDOffset, u32 _iRamAddress, u32 _iLength)
{
// We won't need the crit sec when DTK streaming has been rewritten correctly.
dvdread_section.Enter();
bool retval = VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength);
dvdread_section.Leave();
return retval;
std::lock_guard<std::mutex> lk(dvdread_section);
return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength);
}
bool DVDReadADPCM(u8* _pDestBuffer, u32 _iNumSamples)
@ -360,9 +358,10 @@ bool DVDReadADPCM(u8* _pDestBuffer, u32 _iNumSamples)
return false;
}
_iNumSamples &= ~31;
dvdread_section.Enter();
{
std::lock_guard<std::mutex> lk(dvdread_section);
VolumeHandler::ReadToPtr(_pDestBuffer, AudioPos, _iNumSamples);
dvdread_section.Leave();
}
//
// FIX THIS

View file

@ -26,7 +26,7 @@ int GeckoSockServer::client_count;
std::thread GeckoSockServer::connectionThread;
volatile bool GeckoSockServer::server_running;
std::queue<sf::SocketTCP> GeckoSockServer::waiting_socks;
Common::CriticalSection GeckoSockServer::connection_lock;
std::mutex GeckoSockServer::connection_lock;
GeckoSockServer::GeckoSockServer()
: client_running(false)
@ -76,9 +76,8 @@ void GeckoSockServer::GeckoConnectionWaiter()
{
if (server.Accept(new_client) == sf::Socket::Done)
{
connection_lock.Enter();
std::lock_guard<std::mutex> lk(connection_lock);
waiting_socks.push(new_client);
connection_lock.Leave();
}
SLEEP(1);
}
@ -89,7 +88,8 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
{
bool sock_filled = false;
connection_lock.Enter();
std::lock_guard<std::mutex> lk(connection_lock);
if (waiting_socks.size())
{
sock_to_fill = waiting_socks.front();
@ -106,7 +106,6 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
waiting_socks.pop();
sock_filled = true;
}
connection_lock.Leave();
return sock_filled;
}
@ -123,8 +122,10 @@ void GeckoSockServer::ClientThread()
{
u8 data;
std::size_t got = 0;
{
std::lock_guard<std::mutex> lk(transfer_lock);
transfer_lock.Enter();
if (client.Receive((char*)&data, sizeof(data), got)
== sf::Socket::Disconnected)
client_running = false;
@ -138,7 +139,8 @@ void GeckoSockServer::ClientThread()
client_running = false;
send_fifo.pop();
}
transfer_lock.Leave();
} // unlock transfer
SLEEP(1);
}
@ -173,35 +175,40 @@ void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
// PC -> Gecko
// |= 0x08000000 if successful
case CMD_RECV:
transfer_lock.Enter();
{
std::lock_guard<std::mutex> lk(transfer_lock);
if (!recv_fifo.empty())
{
_uData = 0x08000000 | (recv_fifo.front() << 16);
recv_fifo.pop();
}
transfer_lock.Leave();
break;
}
// Gecko -> PC
// |= 0x04000000 if successful
case CMD_SEND:
transfer_lock.Enter();
{
std::lock_guard<std::mutex> lk(transfer_lock);
send_fifo.push(_uData >> 20);
transfer_lock.Leave();
_uData = 0x04000000;
break;
}
// Check if ok for Gecko -> PC, or FIFO full
// |= 0x04000000 if FIFO is not full
case CMD_CHK_TX:
_uData = 0x04000000;
break;
// Check if data in FIFO for PC -> Gecko, or FIFO empty
// |= 0x04000000 if data in recv FIFO
case CMD_CHK_RX:
transfer_lock.Enter();
{
std::lock_guard<std::mutex> lk(transfer_lock);
_uData = recv_fifo.empty() ? 0 : 0x04000000;
transfer_lock.Leave();
break;
}
default:
ERROR_LOG(EXPANSIONINTERFACE, "Uknown USBGecko command %x", _uData);

View file

@ -34,7 +34,7 @@ public:
sf::SocketTCP client;
void ClientThread();
std::thread clientThread;
Common::CriticalSection transfer_lock;
std::mutex transfer_lock;
std::queue<u8> send_fifo;
std::queue<u8> recv_fifo;
@ -50,7 +50,7 @@ private:
static volatile bool server_running;
static std::thread connectionThread;
static std::queue<sf::SocketTCP> waiting_socks;
static Common::CriticalSection connection_lock;
static std::mutex connection_lock;
};
class CEXIGecko

View file

@ -65,8 +65,9 @@ void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// wtf is this?
_pPADStatus->button = PAD_USE_ORIGIN;
// try lock
if (false == g_plugin.controls_crit.TryEnter())
std::unique_lock<std::mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (!lk.owns_lock())
{
// if gui has lock (messing with controls), skip this input cycle
// center axes and return
@ -86,9 +87,6 @@ void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// get input
((GCPad*)g_plugin.controllers[_numPAD])->GetInput(_pPADStatus);
// leave
g_plugin.controls_crit.Leave();
}
// __________________________________________________________________________________________________
@ -99,15 +97,13 @@ void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
//
void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{
// enter
if ( g_plugin.controls_crit.TryEnter() )
std::unique_lock<std::mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (!lk.owns_lock())
{
// TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time
// set rumble
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
// leave
g_plugin.controls_crit.Leave();
}
}

View file

@ -24,7 +24,7 @@
static std::thread connectionThread;
static std::queue<sf::SocketTCP> waiting_socks;
static Common::CriticalSection cs_gba;
static std::mutex cs_gba;
namespace { volatile bool server_running; }
// --- GameBoy Advance "Link Cable" ---
@ -47,9 +47,8 @@ void GBAConnectionWaiter()
{
if (server.Accept(new_client) == sf::Socket::Done)
{
cs_gba.Enter();
std::lock_guard<std::mutex> lk(cs_gba);
waiting_socks.push(new_client);
cs_gba.Leave();
}
SLEEP(1);
}
@ -68,14 +67,14 @@ bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
{
bool sock_filled = false;
cs_gba.Enter();
std::lock_guard<std::mutex> lk(cs_gba);
if (waiting_socks.size())
{
sock_to_fill = waiting_socks.front();
waiting_socks.pop();
sock_filled = true;
}
cs_gba.Leave();
return sock_filled;
}

View file

@ -93,8 +93,8 @@ void Update(int _number)
{
//PanicAlert( "Wiimote_Update" );
// TODO: change this to a TryEnter, and make it give empty input on failure
g_plugin.controls_crit.Enter();
// TODO: change this to a try_to_lock, and make it give empty input on failure
std::lock_guard<std::mutex> lk(g_plugin.controls_lock);
static int _last_number = 4;
if (_number <= _last_number)
@ -108,8 +108,6 @@ void Update(int _number)
((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->Update();
else
WiimoteReal::Update(_number);
g_plugin.controls_crit.Leave();
}
// __________________________________________________________________________________________________

View file

@ -248,14 +248,14 @@ void Wiimote::RequestStatus(const wm_request_status* const rs)
{
using namespace WiimoteReal;
g_refresh_critsec.Enter();
std::lock_guard<std::mutex> lk(g_refresh_lock);
if (g_wiimotes[m_index])
{
wm_request_status rpt;
rpt.rumble = 0;
g_wiimotes[m_index]->SendPacket(WM_REQUEST_STATUS, &rpt, sizeof(rpt));
}
g_refresh_critsec.Leave();
return;
}

View file

@ -661,7 +661,7 @@ void Wiimote::Update()
{
using namespace WiimoteReal;
g_refresh_critsec.Enter();
std::lock_guard<std::mutex> lk(g_refresh_lock);
if (g_wiimotes[m_index])
{
Report rpt = g_wiimotes[m_index]->ProcessReadQueue();
@ -736,7 +736,6 @@ void Wiimote::Update()
delete[] real_data;
}
}
g_refresh_critsec.Leave();
}
if (Frame::IsRecordingInput())
{

View file

@ -35,7 +35,7 @@ namespace WiimoteReal
bool g_real_wiimotes_initialized = false;
unsigned int g_wiimotes_found = 0;
Common::CriticalSection g_refresh_critsec;
std::mutex g_refresh_lock;
Wiimote *g_wiimotes[MAX_WIIMOTES];
@ -439,11 +439,11 @@ void Shutdown(void)
// This is called from the GUI thread
void Refresh()
{
std::lock_guard<std::mutex> lk(g_refresh_lock);
#ifdef _WIN32
g_refresh_critsec.Enter();
Shutdown();
Initialize();
g_refresh_critsec.Leave();
#else
// Make sure real wiimotes have been initialized
if (!g_real_wiimotes_initialized)
@ -458,8 +458,6 @@ void Refresh()
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i])
++wanted_wiimotes;
g_refresh_critsec.Enter();
// Remove wiimotes that are paired with slots no longer configured for a
// real wiimote or that are disconnected
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
@ -486,50 +484,40 @@ void Refresh()
g_wiimotes_found = num_wiimotes;
}
g_refresh_critsec.Leave();
#endif
}
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
{
g_refresh_critsec.Enter();
std::lock_guard<std::mutex> lk(g_refresh_lock);
if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
g_refresh_critsec.Leave();
}
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
{
g_refresh_critsec.Enter();
std::lock_guard<std::mutex> lk(g_refresh_lock);
if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->ControlChannel(_channelID, _pData, _Size);
g_refresh_critsec.Leave();
}
// Read the Wiimote once
void Update(int _WiimoteNumber)
{
g_refresh_critsec.Enter();
std::lock_guard<std::mutex> lk(g_refresh_lock);
if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->Update();
g_refresh_critsec.Leave();
}
void StateChange(EMUSTATE_CHANGE newState)
{
//g_refresh_critsec.Enter(); // enter
//std::lock_guard<std::mutex> lk(g_refresh_lock);
// TODO: disable/enable auto reporting, maybe
//g_refresh_critsec.Leave(); // leave
}
}; // end of namespace

View file

@ -101,7 +101,7 @@ private:
Common::FifoQueue<Report> m_audio_reports;
};
extern Common::CriticalSection g_refresh_critsec;
extern std::mutex g_refresh_lock;
extern Wiimote *g_wiimotes[4];
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);

View file

@ -27,7 +27,7 @@
// for wiimote/ OSD messages
#include "Core.h"
Common::CriticalSection crit_netplay_ptr;
std::mutex crit_netplay_ptr;
static NetPlay* netplay_ptr = NULL;
#define RPT_SIZE_HACK (1 << 16)
@ -42,20 +42,20 @@ NetPlay::NetPlay(NetPlayUI* dialog)
void NetPlay_Enable(NetPlay* const np)
{
CritLocker crit(crit_netplay_ptr); // probably safe without a lock
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
netplay_ptr = np;
}
void NetPlay_Disable()
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
netplay_ptr = NULL;
}
// called from ---GUI--- thread
NetPlay::~NetPlay()
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
netplay_ptr = NULL;
// not perfect
@ -116,7 +116,8 @@ void NetPlay::ClearBuffers()
// called from ---CPU--- thread
bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues)
{
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
// in game mapping for this local pad
unsigned int in_game_num = m_local_player->pad_map[pad_nb];
@ -138,7 +139,7 @@ bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, Ne
}
}
m_crit.players.Leave();
} // unlock players
//Common::Timer bufftimer;
//bufftimer.Start();
@ -181,14 +182,13 @@ void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32
m_wiimote_input[_number].back().assign((char*)_pData, (char*)_pData + _Size);
m_wiimote_input[_number].back().channel = _channelID;
}
m_crit.players.Leave();
}
// called from ---CPU--- thread
void NetPlay::WiimoteUpdate(int _number)
{
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
// in game mapping for this local wiimote
unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now
@ -203,7 +203,7 @@ void NetPlay::WiimoteUpdate(int _number)
m_wiimote_input[_number].clear();
}
m_crit.players.Leave();
} // unlock players
if (0 == m_wiimote_buffer[_number].Size())
{
@ -251,7 +251,7 @@ bool NetPlay::StartGame(const std::string &path)
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
bool NetPlay::StopGame()
{
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
if (false == m_is_running)
{
@ -288,7 +288,7 @@ u8 NetPlay::GetPadNum(u8 numPAD)
// Actual Core function which is called on every frame
bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
if (netplay_ptr)
return netplay_ptr->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus);
@ -300,7 +300,7 @@ bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u
// so all players' games get the same time
u32 CEXIIPL::NetPlay_GetGCTime()
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
if (netplay_ptr)
return 1272737767; // watev
@ -312,7 +312,7 @@ u32 CEXIIPL::NetPlay_GetGCTime()
// return the local pad num that should rumble given a ingame pad num
u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
if (netplay_ptr)
return netplay_ptr->GetPadNum(numPAD);
@ -348,7 +348,7 @@ int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
//bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size)
bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&)
{
CritLocker crit(crit_netplay_ptr);
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
if (netplay_ptr)
//{

View file

@ -75,19 +75,6 @@ enum
CON_ERR_VERSION_MISMATCH
};
// something like this should be in Common stuff
class CritLocker
{
public:
//CritLocker(const CritLocker&);
CritLocker& operator=(const CritLocker&);
CritLocker(Common::CriticalSection& crit) : m_crit(crit) { m_crit.Enter(); }
~CritLocker() { m_crit.Leave(); }
private:
Common::CriticalSection& m_crit;
};
class NetPlayUI
{
public:
@ -135,9 +122,9 @@ protected:
struct
{
Common::CriticalSection game;
std::recursive_mutex game;
// lock order
Common::CriticalSection players, send;
std::recursive_mutex players, send;
} m_crit;
class Player

View file

@ -93,9 +93,10 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
packet >> player.name;
packet >> player.revision;
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
m_players[player.pid] = player;
m_crit.players.Leave();
}
m_dialog->Update();
}
@ -106,9 +107,10 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
PlayerId pid;
packet >> pid;
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
m_players.erase(m_players.find(pid));
m_crit.players.Leave();
}
m_dialog->Update();
}
@ -137,12 +139,13 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
PlayerId pid;
packet >> pid;
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
Player& player = m_players[pid];
for (unsigned int i=0; i<4; ++i)
packet >> player.pad_map[i];
m_crit.players.Leave();
}
m_dialog->Update();
}
@ -171,10 +174,10 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_CHANGE_GAME :
{
// lock here?
m_crit.game.Enter(); // lock game state
{
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
packet >> m_selected_game;
m_crit.game.Leave();
}
// update gui
m_dialog->OnMsgChangeGame(m_selected_game);
@ -183,9 +186,10 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_START_GAME :
{
m_crit.game.Enter(); // lock buffer
{
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
packet >> m_current_game;
m_crit.game.Leave();
}
m_dialog->OnMsgStartGame();
}
@ -200,7 +204,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_DISABLE_GAME :
{
PanicAlertT("Other client disconnected while game is running!! NetPlay is disabled. You manually stop the game.");
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
m_is_running = false;
NetPlay_Disable();
}
@ -215,7 +219,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
spac << (MessageId)NP_MSG_PONG;
spac << ping_key;
CritLocker send_lock(m_crit.send);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_socket.Send(spac);
}
break;
@ -263,7 +267,7 @@ void NetPlayClient::ThreadFunc()
// called from ---GUI--- thread
void NetPlayClient::GetPlayerList(std::string& list, std::vector<int>& pid_list)
{
CritLocker player_lock(m_crit.players); // lock players
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::ostringstream ss;
@ -287,7 +291,7 @@ void NetPlayClient::SendChatMessage(const std::string& msg)
spac << (MessageId)NP_MSG_CHAT_MESSAGE;
spac << msg;
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_socket.Send(spac);
}
@ -300,14 +304,14 @@ void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np)
spac << local_nb; // local pad num
spac << np.nHi << np.nLo;
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_socket.Send(spac);
}
// called from ---GUI--- thread
bool NetPlayClient::StartGame(const std::string &path)
{
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
if (false == NetPlay::StartGame(path))
return false;
@ -317,7 +321,7 @@ bool NetPlayClient::StartGame(const std::string &path)
spac << (MessageId)NP_MSG_START_GAME;
spac << m_current_game;
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_socket.Send(spac);
return true;

View file

@ -60,8 +60,7 @@ void NetPlayServer::ThreadFunc()
spac << (MessageId)NP_MSG_PING;
spac << m_ping_key;
//CritLocker player_lock(m_crit.players);
CritLocker send_lock(m_crit.send);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_ping_timer.Start();
SendToClients(spac);
@ -80,9 +79,11 @@ void NetPlayServer::ThreadFunc()
sf::SocketTCP accept_socket;
m_socket.Accept(accept_socket);
m_crit.game.Enter(); // lock game state
const unsigned int error = OnConnect(accept_socket);
m_crit.game.Leave();
unsigned int error;
{
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
error = OnConnect(accept_socket);
}
if (error)
{
@ -108,10 +109,11 @@ void NetPlayServer::ThreadFunc()
//case sf::Socket::Disconnected :
default :
m_crit.game.Enter(); // lock game state
{
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
OnDisconnect(ready_socket);
m_crit.game.Leave();
break;
}
}
}
}
@ -200,8 +202,8 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
}
// ENTER
m_crit.send.Enter();
{
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
// send join message to already connected clients
sf::Packet spac;
@ -230,16 +232,16 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
socket.Send(spac);
}
// LEAVE
m_crit.send.Leave();
} // unlock send
// add client to the player list
m_crit.players.Enter(); // lock players
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
m_players[socket] = player;
m_crit.send.Enter(); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
UpdatePadMapping(); // sync pad mappings with everyone
m_crit.send.Leave();
m_crit.players.Leave();
}
// add client to selector/ used for receiving
m_selector.Add(socket);
@ -255,14 +257,14 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
if (m_is_running)
{
PanicAlertT("Client disconnect while game is running!! NetPlay is disabled. You must manually stop the game.");
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
m_is_running = false;
NetPlay_Disable();
sf::Packet spac;
spac << (MessageId)NP_MSG_DISABLE_GAME;
// this thread doesnt need players lock
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
}
@ -272,11 +274,11 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
m_selector.Remove(socket);
CritLocker player_lock(m_crit.players); // lock players
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
m_players.erase(m_players.find(socket));
// alert other players of disconnect
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
m_dialog->Update();
@ -287,7 +289,7 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
// called from ---GUI--- thread
bool NetPlayServer::GetPadMapping(const int pid, int map[])
{
CritLocker player_lock(m_crit.players); // lock players
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::map<sf::SocketTCP, Client>::const_iterator
i = m_players.begin(),
e = m_players.end();
@ -309,11 +311,11 @@ bool NetPlayServer::GetPadMapping(const int pid, int map[])
// called from ---GUI--- thread
bool NetPlayServer::SetPadMapping(const int pid, const int map[])
{
CritLocker game_lock(m_crit.game); // lock game
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
if (m_is_running)
return false;
CritLocker player_lock(m_crit.players); // lock players
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::map<sf::SocketTCP, Client>::iterator
i = m_players.begin(),
e = m_players.end();
@ -340,7 +342,7 @@ bool NetPlayServer::SetPadMapping(const int pid, const int map[])
i->second.pad_map[p] = -1;
}
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
UpdatePadMapping(); // sync pad mappings with everyone
m_dialog->Update();
@ -369,7 +371,7 @@ void NetPlayServer::UpdatePadMapping()
// called from ---GUI--- thread and ---NETPLAY--- thread
u64 NetPlayServer::CalculateMinimumBufferTime()
{
CritLocker player_lock(m_crit.players);
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::map<sf::SocketTCP, Client>::const_iterator
i = m_players.begin(),
@ -392,7 +394,7 @@ u64 NetPlayServer::CalculateMinimumBufferTime()
// called from ---GUI--- thread and ---NETPLAY--- thread
void NetPlayServer::AdjustPadBufferSize(unsigned int size)
{
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
m_target_buffer_size = size;
@ -401,8 +403,8 @@ void NetPlayServer::AdjustPadBufferSize(unsigned int size)
spac << (MessageId)NP_MSG_PAD_BUFFER;
spac << (u32)m_target_buffer_size;
CritLocker player_lock(m_crit.players); // lock players
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
}
@ -429,9 +431,10 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
spac << player.pid;
spac << msg;
m_crit.send.Enter(); // lock send
{
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac, player.pid);
m_crit.send.Leave();
}
// add to gui
std::ostringstream ss;
@ -471,7 +474,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
spac << map; // in game mapping
spac << np.nHi << np.nLo;
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac, player.pid);
}
break;
@ -510,7 +513,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
// called from ---GUI--- thread
void NetPlayServer::GetPlayerList(std::string& list, std::vector<int>& pid_list)
{
CritLocker player_lock(m_crit.players); // lock players
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::ostringstream ss;
@ -534,15 +537,15 @@ void NetPlayServer::SendChatMessage(const std::string& msg)
spac << (PlayerId)0; // server id always 0
spac << msg;
CritLocker player_lock(m_crit.players); // lock players
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
}
// called from ---GUI--- thread
bool NetPlayServer::ChangeGame(const std::string &game)
{
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
m_selected_game = game;
@ -551,8 +554,8 @@ bool NetPlayServer::ChangeGame(const std::string &game)
spac << (MessageId)NP_MSG_CHANGE_GAME;
spac << game;
CritLocker player_lock(m_crit.players); // lock players
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
return true;
@ -567,14 +570,14 @@ void NetPlayServer::SendPadState(const PadMapping local_nb, const NetPad& np)
spac << m_local_player->pad_map[local_nb]; // in-game pad num
spac << np.nHi << np.nLo;
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
}
// called from ---GUI--- thread
bool NetPlayServer::StartGame(const std::string &path)
{
CritLocker game_lock(m_crit.game); // lock game state
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
if (false == NetPlay::StartGame(path))
return false;
@ -590,8 +593,8 @@ bool NetPlayServer::StartGame(const std::string &path)
spac << (MessageId)NP_MSG_START_GAME;
spac << m_current_game;
CritLocker player_lock(m_crit.players); // lock players
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
return true;
@ -608,8 +611,8 @@ bool NetPlayServer::StopGame()
sf::Packet spac;
spac << (MessageId)NP_MSG_STOP_GAME;
CritLocker player_lock(m_crit.players); // lock players
CritLocker send_lock(m_crit.send); // lock send
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac);
return true;

View file

@ -36,7 +36,7 @@
#endif
#include "State.h"
Common::CriticalSection cs_frameSkip;
std::mutex cs_frameSkip;
namespace Frame {
@ -95,7 +95,7 @@ void FrameUpdate()
void SetFrameSkipping(unsigned int framesToSkip)
{
cs_frameSkip.Enter();
std::lock_guard<std::mutex> lk(cs_frameSkip);
g_framesToSkip = framesToSkip;
g_frameSkipCounter = 0;
@ -104,8 +104,6 @@ void SetFrameSkipping(unsigned int framesToSkip)
// as this won't be changed anymore when frameskip is turned off
if (framesToSkip == 0)
g_video_backend->Video_SetRendering(true);
cs_frameSkip.Leave();
}
int FrameSkippingFactor()
@ -138,15 +136,13 @@ void FrameSkipping()
// Frameskipping will desync movie playback
if (!IsPlayingInput() && !IsRecordingInput())
{
cs_frameSkip.Enter();
std::lock_guard<std::mutex> lk(cs_frameSkip);
g_frameSkipCounter++;
if (g_frameSkipCounter > g_framesToSkip || Core::report_slow(g_frameSkipCounter) == false)
g_frameSkipCounter = 0;
g_video_backend->Video_SetRendering(!g_frameSkipCounter);
cs_frameSkip.Leave();
}
}