summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2011-01-27 20:47:58 +0000
committerJordan Woyak <jordan.woyak@gmail.com>2011-01-27 20:47:58 +0000
commit2c05c49a04aa838047417825c289958efb59ee3c (patch)
tree2731699f2223276c60b6b403d3a080d75f99bf74 /Source/Core
parent0371f15c23bf9fb64941e3adbc72b80f955e2ff5 (diff)
Replaced Common::Thread with a partial implementation of std::thread. (rvalue references are used if available, <thread> is used if possible) Eliminates the need to use dynamic memory allocation for threads, so it's impossible to forget to delete a thread or set a pointer to NULL. Enables use of type-safe thread functions, no need to cast to and from void*. I've made sure the code compiles in vs08 and tested the functionality of "StdThread.h" on Linux so I'm hoping everything will work :p. In the future "StdThread.h" can be removed (maybe when OS X ships with gcc 4.4 and vs2015 is released :p).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6933 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/AudioCommon/Src/AOSoundStream.cpp10
-rw-r--r--Source/Core/AudioCommon/Src/AOSoundStream.h2
-rw-r--r--Source/Core/AudioCommon/Src/DSoundStream.cpp10
-rw-r--r--Source/Core/AudioCommon/Src/DSoundStream.h2
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.cpp11
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.h4
-rw-r--r--Source/Core/Common/Common.vcproj4
-rw-r--r--Source/Core/Common/Common.vcxproj1
-rw-r--r--Source/Core/Common/Src/StdThread.h298
-rw-r--r--Source/Core/Common/Src/Thread.cpp175
-rw-r--r--Source/Core/Common/Src/Thread.h90
-rw-r--r--Source/Core/Core/Src/Core.cpp44
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceGecko.cpp35
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceGecko.h6
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp32
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h2
-rw-r--r--Source/Core/Core/Src/HW/SI_DeviceGBA.cpp16
-rw-r--r--Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp38
-rw-r--r--Source/Core/Core/Src/State.cpp15
-rw-r--r--Source/Core/DolphinWX/Src/NetPlay.cpp5
-rw-r--r--Source/Core/DolphinWX/Src/NetPlay.h7
-rw-r--r--Source/Core/DolphinWX/Src/NetPlayClient.cpp5
-rw-r--r--Source/Core/DolphinWX/Src/NetPlayServer.cpp5
-rw-r--r--Source/Core/InputCommon/Src/UDPWiimote.cpp19
-rw-r--r--Source/Core/InputCommon/Src/UDPWiimote.h2
25 files changed, 468 insertions, 370 deletions
diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.cpp b/Source/Core/AudioCommon/Src/AOSoundStream.cpp
index cff38d1c7f..a1bc0e0a76 100644
--- a/Source/Core/AudioCommon/Src/AOSoundStream.cpp
+++ b/Source/Core/AudioCommon/Src/AOSoundStream.cpp
@@ -54,10 +54,9 @@ void AOSound::SoundLoop()
}
}
-void *soundThread(void *args)
+void soundThread(AOSound *aosound)
{
- ((AOSound *)args)->SoundLoop();
- return NULL;
+ aosound->SoundLoop();
}
bool AOSound::Start()
@@ -66,7 +65,7 @@ bool AOSound::Start()
soundSyncEvent.Init();
- thread = new Common::Thread(soundThread, (void *)this);
+ thread = std::thread(soundThread, this);
return true;
}
@@ -81,8 +80,7 @@ void AOSound::Stop()
soundSyncEvent.Set();
soundCriticalSection.Enter();
- delete thread;
- thread = NULL;
+ thread.join();
if (device)
ao_close(device);
diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.h b/Source/Core/AudioCommon/Src/AOSoundStream.h
index afba7b363f..57a883aa83 100644
--- a/Source/Core/AudioCommon/Src/AOSoundStream.h
+++ b/Source/Core/AudioCommon/Src/AOSoundStream.h
@@ -29,7 +29,7 @@
class AOSound : public SoundStream
{
#if defined(HAVE_AO) && HAVE_AO
- Common::Thread *thread;
+ std::thread thread;
Common::CriticalSection soundCriticalSection;
Common::Event soundSyncEvent;
diff --git a/Source/Core/AudioCommon/Src/DSoundStream.cpp b/Source/Core/AudioCommon/Src/DSoundStream.cpp
index 3ebfa15659..7b17431cbc 100644
--- a/Source/Core/AudioCommon/Src/DSoundStream.cpp
+++ b/Source/Core/AudioCommon/Src/DSoundStream.cpp
@@ -91,10 +91,9 @@ bool DSound::WriteDataToBuffer(DWORD dwOffset, // Our own write
}
// The audio thread.
-THREAD_RETURN soundThread(void* args)
+void soundThread(DSound* dsound)
{
- (reinterpret_cast<DSound *>(args))->SoundLoop();
- return 0;
+ dsound->SoundLoop();
}
void DSound::SoundLoop()
@@ -138,7 +137,7 @@ bool DSound::Start()
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
memset(p1, 0, num1);
dsBuffer->Unlock(p1, num1, 0, 0);
- thread = new Common::Thread(soundThread, (void *)this);
+ thread = std::thread(soundThread, this);
return true;
}
@@ -179,8 +178,7 @@ void DSound::Stop()
// kick the thread if it's waiting
soundSyncEvent.Set();
- delete thread;
- thread = NULL;
+ thread.join();
dsBuffer->Stop();
dsBuffer->Release();
ds->Release();
diff --git a/Source/Core/AudioCommon/Src/DSoundStream.h b/Source/Core/AudioCommon/Src/DSoundStream.h
index adbeaeb468..73d6fcbae3 100644
--- a/Source/Core/AudioCommon/Src/DSoundStream.h
+++ b/Source/Core/AudioCommon/Src/DSoundStream.h
@@ -31,7 +31,7 @@
class DSound : public SoundStream
{
#ifdef _WIN32
- Common::Thread *thread;
+ std::thread thread;
Common::EventEx soundSyncEvent;
void *hWnd;
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp
index e92d1cdc27..908f1c0099 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp
@@ -44,8 +44,7 @@ bool OpenALStream::Start()
if (pContext)
{
alcMakeContextCurrent(pContext);
- thread = new Common::Thread(
- OpenALStream::ThreadFunc, (void *)this);
+ thread = std::thread(OpenALStream::ThreadFunc, this);
bReturn = true;
}
else
@@ -75,8 +74,7 @@ void OpenALStream::Stop()
// kick the thread if it's waiting
soundSyncEvent.Set();
- delete thread;
- thread = NULL;
+ thread.join();
alSourceStop(uiSource);
alSourcei(uiSource, AL_BUFFER, 0);
@@ -123,10 +121,9 @@ void OpenALStream::Clear(bool mute)
}
}
-THREAD_RETURN OpenALStream::ThreadFunc(void* args)
+void OpenALStream::ThreadFunc(OpenALStream* alstream)
{
- (reinterpret_cast<OpenALStream *>(args))->SoundLoop();
- return 0;
+ alstream->SoundLoop();
}
void OpenALStream::SoundLoop()
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.h b/Source/Core/AudioCommon/Src/OpenALStream.h
index 82a1eca1eb..7475fcfe83 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.h
+++ b/Source/Core/AudioCommon/Src/OpenALStream.h
@@ -58,10 +58,10 @@ public:
virtual bool usesMixer() const { return true; }
virtual void Update();
- static THREAD_RETURN ThreadFunc(void* args);
+ static void ThreadFunc(OpenALStream* args);
private:
- Common::Thread *thread;
+ std::thread thread;
Common::EventEx soundSyncEvent;
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj
index 1b2b05a32b..1667d5711f 100644
--- a/Source/Core/Common/Common.vcproj
+++ b/Source/Core/Common/Common.vcproj
@@ -846,6 +846,10 @@
>
</File>
<File
+ RelativePath=".\Src\StdThread.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\StringUtil.cpp"
>
</File>
diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index 5bc6c63a10..4a15c7d641 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -322,6 +322,7 @@
<ClInclude Include="Src\SDCardUtil.h" />
<ClInclude Include="Src\Setup.h" />
<ClInclude Include="Src\stdafx.h" />
+ <ClInclude Include="Src\StdThread.h" />
<ClInclude Include="Src\StringUtil.h" />
<ClInclude Include="Src\svnrev.h" />
<ClInclude Include="Src\svnrev_template.h" />
diff --git a/Source/Core/Common/Src/StdThread.h b/Source/Core/Common/Src/StdThread.h
new file mode 100644
index 0000000000..859c66902c
--- /dev/null
+++ b/Source/Core/Common/Src/StdThread.h
@@ -0,0 +1,298 @@
+
+#ifndef STD_THREAD_H_
+#define STD_THREAD_H_
+
+#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
+#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+
+#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
+// GCC 4.4 provides <thread>
+#include <thread>
+#else
+
+// partial std::thread implementation for win32/pthread
+
+#include <algorithm>
+
+#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
+#define USE_RVALUE_REFERENCES
+#endif
+
+#if defined(_WIN32)
+// WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#if defined(_MSC_VER) && defined(_MT)
+// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
+// using _beginthreadex instead of CreateThread.
+#define USE_BEGINTHREADEX
+#include <process.h>
+#endif
+
+#ifdef USE_BEGINTHREADEX
+#define THREAD_ID unsigned
+#define THREAD_RETURN unsigned __stdcall
+#else
+#define THREAD_ID DWORD
+#define THREAD_RETURN DWORD WINAPI
+#endif
+#define THREAD_HANDLE HANDLE
+
+#else
+// PTHREAD
+
+#include <unistd.h>
+
+#ifndef _POSIX_THREADS
+#error unsupported platform (no pthreads?)
+#endif
+
+#include <pthread.h>
+
+#define THREAD_ID pthread_t
+#define THREAD_HANDLE pthread_t
+#define THREAD_RETURN void*
+
+#endif
+
+namespace std
+{
+
+class thread
+{
+public:
+ typedef THREAD_HANDLE native_handle_type;
+
+ class id
+ {
+ friend class thread;
+ public:
+ id() : m_thread(0) {}
+ id(THREAD_ID _id) : m_thread(_id) {}
+
+ bool operator==(const id& rhs) const
+ {
+ return m_thread == rhs.m_thread;
+ }
+
+ bool operator!=(const id& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ bool operator<(const id& rhs) const
+ {
+ return m_thread < rhs.m_thread;
+ }
+
+ private:
+ THREAD_ID m_thread;
+ };
+
+ // no variadic template support in msvc
+ //template <typename C, typename... A>
+ //thread(C&& func, A&&... args);
+
+ template <typename C>
+ thread(C func)
+ {
+ StartThread(new Func<C>(func));
+ }
+
+ template <typename C, typename A>
+ thread(C func, A arg)
+ {
+ StartThread(new FuncArg<C, A>(func, arg));
+ }
+
+ thread() /*= default;*/ {}
+
+#ifdef USE_RVALUE_REFERENCES
+ thread(const thread&) /*= delete*/;
+
+ thread(thread&& other)
+ {
+#else
+ thread(const thread& t)
+ {
+ // ugly const_cast to get around lack of rvalue references
+ thread& other = const_cast<thread&>(t);
+#endif
+ swap(other);
+ }
+
+#ifdef USE_RVALUE_REFERENCES
+ thread& operator=(const thread&) /*= delete*/;
+
+ thread& operator=(thread&& other)
+ {
+#else
+ thread& operator=(const thread& t)
+ {
+ // ugly const_cast to get around lack of rvalue references
+ thread& other = const_cast<thread&>(t);
+#endif
+ if (joinable())
+ detach();
+ swap(other);
+ return *this;
+ }
+
+ ~thread()
+ {
+ if (joinable())
+ detach();
+ }
+
+ bool joinable() const
+ {
+ return m_id != id();
+ }
+
+ id get_id() const
+ {
+ return m_id;
+ }
+
+ native_handle_type native_handle()
+ {
+#ifdef _WIN32
+ return m_handle;
+#else
+ return m_id.m_thread;
+#endif
+ }
+
+ void join()
+ {
+#ifdef _WIN32
+ WaitForSingleObject(m_handle, INFINITE);
+ detach();
+#else
+ pthread_join(m_id.m_thread, NULL);
+ m_id = id();
+#endif
+ }
+
+ void detach()
+ {
+#ifdef _WIN32
+ CloseHandle(m_handle);
+#else
+ pthread_detach(m_id.m_thread);
+#endif
+ m_id = id();
+ }
+
+ void swap(thread& other)
+ {
+ std::swap(m_id, other.m_id);
+#ifdef _WIN32
+ std::swap(m_handle, other.m_handle);
+#endif
+ }
+
+ static unsigned hardware_concurrency()
+ {
+#ifdef _WIN32
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
+#else
+ return 0;
+#endif
+ }
+
+private:
+ id m_id;
+
+#ifdef _WIN32
+ native_handle_type m_handle;
+#endif
+
+ template <typename F>
+ void StartThread(F* param)
+ {
+#ifdef USE_BEGINTHREADEX
+ m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
+#elif defined(_WIN32)
+ m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
+#else
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 1024 * 1024);
+ if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
+ m_id = id();
+#endif
+ }
+
+ template <typename C>
+ class Func
+ {
+ public:
+ Func(C _func) : func(_func) {}
+
+ void Run() { func(); }
+
+ private:
+ C const func;
+ };
+
+ template <typename C, typename A>
+ class FuncArg
+ {
+ public:
+ FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
+
+ void Run() { func(arg); }
+
+ private:
+ C const func;
+ A arg;
+ };
+
+ template <typename F>
+ static THREAD_RETURN RunAndDelete(void* param)
+ {
+ static_cast<F*>(param)->Run();
+ delete static_cast<F*>(param);
+
+ return 0;
+ }
+};
+
+namespace this_thread
+{
+
+inline void yield()
+{
+#ifdef _WIN32
+ Sleep(1);
+#else
+ usleep(1000 * 1);
+#endif
+}
+
+inline thread::id get_id()
+{
+#ifdef _WIN32
+ return GetCurrentThreadId();
+#else
+ return pthread_self();
+#endif
+}
+
+} // namespace this_thread
+
+} // namespace std
+
+#undef USE_RVALUE_REFERENCES
+#undef USE_BEGINTHREADEX
+#undef THREAD_ID
+#undef THREAD_RETURN
+#undef THREAD_HANDLE
+
+#endif
+#endif
diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp
index 16624b6388..0238b14008 100644
--- a/Source/Core/Common/Src/Thread.cpp
+++ b/Source/Core/Common/Src/Thread.cpp
@@ -25,18 +25,28 @@
namespace Common
{
-
- int Thread::CurrentId()
- {
+
+int CurrentThreadId()
+{
#ifdef _WIN32
- return GetCurrentThreadId();
+ return GetCurrentThreadId();
#else
- return 0;
+ return 0;
#endif
- }
+}
#ifdef _WIN32
-
+
+void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
+{
+ SetThreadAffinityMask(thread, mask);
+}
+
+void SetCurrentThreadAffinity(u32 mask)
+{
+ SetThreadAffinityMask(GetCurrentThread(), mask);
+}
+
CriticalSection::CriticalSection(int spincount)
{
if (spincount)
@@ -70,54 +80,6 @@ namespace Common
LeaveCriticalSection(&section);
}
- Thread::Thread(ThreadFunc function, void* arg)
- : m_hThread(NULL), m_threadId(0)
- {
-#ifdef USE_BEGINTHREADEX
- m_hThread = (HANDLE)_beginthreadex(NULL, 0, function, arg, 0, &m_threadId);
-#else
- m_hThread = CreateThread(NULL, 0, function, arg, 0, &m_threadId);
-#endif
- }
-
- Thread::~Thread()
- {
- WaitForDeath();
- }
-
- DWORD Thread::WaitForDeath(const int iWait)
- {
- if (m_hThread)
- {
- DWORD Wait = WaitForSingleObject(m_hThread, iWait);
- CloseHandle(m_hThread);
- m_hThread = NULL;
- return Wait;
- }
- return NULL;
- }
-
- void Thread::SetAffinity(int mask)
- {
- SetThreadAffinityMask(m_hThread, mask);
- }
-
- void Thread::SetPriority(int priority)
- {
- SetThreadPriority(m_hThread, priority);
- }
-
- void Thread::SetCurrentThreadAffinity(int mask)
- {
- SetThreadAffinityMask(GetCurrentThread(), mask);
- }
-
- bool Thread::IsCurrentThread()
- {
- return GetCurrentThreadId() == m_threadId;
- }
-
-
EventEx::EventEx()
{
InterlockedExchange(&m_Lock, 1);
@@ -300,7 +262,32 @@ namespace Common
}
#else // !WIN32, so must be POSIX threads
-
+
+void LinuxSetThreadAffinity(pthread_t thread, u32 mask)
+{
+ // This is non-standard
+#ifdef __linux__
+ cpu_set_t cpu_set;
+ CPU_ZERO(&cpu_set);
+
+ for (int i = 0; i != sizeof(mask) * 8; ++i)
+ if ((mask >> i) & 1)
+ CPU_SET(i, &cpu_set);
+
+ pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set);
+#endif
+}
+
+void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
+{
+ LinuxSetThreadAffinity(thread, mask);
+}
+
+void SetCurrentThreadAffinity(u32 mask)
+{
+ LinuxSetThreadAffinity(pthread_self(), mask);
+}
+
static pthread_key_t threadname_key;
static pthread_once_t threadname_key_once = PTHREAD_ONCE_INIT;
@@ -344,82 +331,6 @@ namespace Common
pthread_mutex_unlock(&mutex);
#endif
}
-
-
- Thread::Thread(ThreadFunc function, void* arg)
- : thread_id(0)
- {
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, 1024 * 1024);
- int ret = pthread_create(&thread_id, &attr, function, arg);
- if (ret) ERROR_LOG(COMMON, "%s: pthread_create(%p, %p, %p, %p) failed: %s\n",
- __FUNCTION__, &thread_id, &attr, function, arg, strerror(ret));
-
- INFO_LOG(COMMON, "created new thread %lu (func=%p, arg=%p)\n",
- (unsigned long)thread_id, function, arg);
- }
-
-
- Thread::~Thread()
- {
- WaitForDeath();
- }
-
-
- void Thread::WaitForDeath()
- {
- if (thread_id)
- {
- void* exit_status;
- int ret = pthread_join(thread_id, &exit_status);
- if (ret) ERROR_LOG(COMMON,
- "error joining thread %lu: %s\n",
- (unsigned long)thread_id, strerror(ret));
- if (exit_status)
- ERROR_LOG(COMMON,
- "thread %lu exited with status %d\n",
- (unsigned long)thread_id, *(int *)exit_status);
- thread_id = 0;
- }
- }
-
-
- void Thread::SetAffinity(int mask)
- {
- // This is non-standard
-#ifdef __linux__
- cpu_set_t cpu_set;
- CPU_ZERO(&cpu_set);
-
- for (unsigned int i = 0; i < sizeof(mask) * 8; i++)
- {
- if ((mask >> i) & 1){CPU_SET(i, &cpu_set);}
- }
-
- pthread_setaffinity_np(thread_id, sizeof(cpu_set), &cpu_set);
-#endif
- }
-
- void Thread::SetCurrentThreadAffinity(int mask)
- {
-#ifdef __linux__
- cpu_set_t cpu_set;
- CPU_ZERO(&cpu_set);
-
- for (size_t i = 0; i < sizeof(mask) * 8; i++)
- {
- if ((mask >> i) & 1){CPU_SET(i, &cpu_set);}
- }
-
- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
-#endif
- }
-
- bool Thread::IsCurrentThread()
- {
- return pthread_equal(pthread_self(), thread_id) != 0;
- }
void SleepCurrentThread(int ms)
{
diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h
index 5d4182f5e4..a11e1abf2c 100644
--- a/Source/Core/Common/Src/Thread.h
+++ b/Source/Core/Common/Src/Thread.h
@@ -18,37 +18,7 @@
#ifndef _THREAD_H_
#define _THREAD_H_
-#ifdef _WIN32
-
-#if defined(_MSC_VER) && defined(_MT)
-// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
-// using _beginthreadex instead of CreateThread.
-#define USE_BEGINTHREADEX
-#endif
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#ifdef USE_BEGINTHREADEX
-#define THREAD_RETURN unsigned __stdcall
-#else
-#define THREAD_RETURN DWORD WINAPI
-#endif
-
-#else
-
-#include <xmmintrin.h>
-#define THREAD_RETURN void*
-#include <unistd.h>
-#ifdef _POSIX_THREADS
-#include <pthread.h>
-#elif GEKKO
-#include <ogc/lwp_threads.h>
-#else
-#error unsupported platform (no pthreads?)
-#endif
-
-#endif
+#include "StdThread.h"
// Don't include common.h here as it will break LogManager
#include "CommonTypes.h"
@@ -61,6 +31,8 @@
#define INFINITE 0xffffffff
#endif
+#include <xmmintrin.h>
+
//for gettimeofday and struct time(spec|val)
#include <time.h>
#include <sys/time.h>
@@ -69,6 +41,11 @@
namespace Common
{
+
+int CurrentThreadId();
+
+void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask);
+void SetCurrentThreadAffinity(u32 mask);
class CriticalSection
{
@@ -89,57 +66,6 @@ namespace Common
};
#ifdef _WIN32
-
-#ifdef USE_BEGINTHREADEX
- typedef unsigned (__stdcall *ThreadFunc)(void* arg);
-#else
- typedef DWORD (WINAPI *ThreadFunc)(void* arg);
-#endif
-
-#else
-
- typedef void* (*ThreadFunc)(void* arg);
-
-#endif
-
- class Thread
- {
- public:
- Thread(ThreadFunc entry, void* arg);
- ~Thread();
-
- void SetAffinity(int mask);
- static void SetCurrentThreadAffinity(int mask);
- static int CurrentId();
- bool IsCurrentThread();
-#ifdef _WIN32
- void SetPriority(int priority);
- DWORD WaitForDeath(const int iWait = INFINITE);
-#else
- void WaitForDeath();
-#endif
-
- private:
-
-#ifdef _WIN32
-
- HANDLE m_hThread;
-#ifdef USE_BEGINTHREADEX
- unsigned m_threadId;
-#else
- DWORD m_threadId;
-#endif
-
-#else
-
-#ifdef _POSIX_THREADS
- pthread_t thread_id;
-#endif
-
-#endif
- };
-
-#ifdef _WIN32
// Event(WaitForSingleObject) is too expensive
// as it always enters Ring0 regardless of the state of lock
// This EventEx will try to stay in Ring3 as much as possible
diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp
index 2c6c104856..f375e65c19 100644
--- a/Source/Core/Core/Src/Core.cpp
+++ b/Source/Core/Core/Src/Core.cpp
@@ -95,7 +95,7 @@ TPeekMessages Callback_PeekMessages = NULL;
TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
// Function declarations
-THREAD_RETURN EmuThread(void *pArg);
+void EmuThread();
void Stop();
@@ -104,9 +104,9 @@ bool g_bHwInit = false;
bool g_bRealWiimote = false;
void *g_pWindowHandle = NULL;
-Common::Thread* g_EmuThread = NULL;
+std::thread g_EmuThread;
-static Common::Thread* cpuThread = NULL;
+static std::thread cpuThread;
SCoreStartupParameter g_CoreStartupParameter;
@@ -122,7 +122,7 @@ Common::Event cpuRunloopQuit;
std::string StopMessage(bool bMainThread, std::string Message)
{
return StringFromFormat("Stop [%s %i]\t%s\t%s",
- bMainThread ? "Main Thread" : "Video Thread", Common::Thread::CurrentId(), MemUsage().c_str(), Message.c_str());
+ bMainThread ? "Main Thread" : "Video Thread", Common::CurrentThreadId(), MemUsage().c_str(), Message.c_str());
}
//
@@ -166,14 +166,14 @@ bool isRunning()
bool IsRunningInCurrentThread()
{
- return isRunning() && ((cpuThread == NULL) || cpuThread->IsCurrentThread());
+ return isRunning() && ((cpuThread.joinable()) || cpuThread.get_id() == std::this_thread::get_id());
}
// This is called from the GUI thread. See the booting call schedule in
// BootManager.cpp
bool Init()
{
- if (g_EmuThread != NULL)
+ if (g_EmuThread.joinable())
{
PanicAlertT("Emu Thread already running");
return false;
@@ -195,7 +195,7 @@ bool Init()
emuThreadGoing.Init();
// Start the emu thread
- g_EmuThread = new Common::Thread(EmuThread, NULL);
+ g_EmuThread = std::thread(EmuThread);
// Wait until the emu thread is running
emuThreadGoing.MsgWait();
@@ -242,14 +242,12 @@ void Stop() // - Hammertime!
Host_SetWaitCursor(false);
WARN_LOG(CONSOLE, "%s", StopMessage(true, "Stopping Emu thread ...").c_str());
- g_EmuThread->WaitForDeath();
- delete g_EmuThread; // Wait for emuthread to close.
- g_EmuThread = 0;
+ g_EmuThread.join(); // Wait for emuthread to close.
}
// Create the CPU thread. which would be a CPU + Video thread in Single Core mode.
-THREAD_RETURN CpuThread(void *pArg)
+void CpuThread()
{
#ifdef __APPLE__
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -269,7 +267,7 @@ THREAD_RETURN CpuThread(void *pArg)
}
if (_CoreParameter.bLockThreads)
- Common::Thread::SetCurrentThreadAffinity(1); // Force to first core
+ Common::SetCurrentThreadAffinity(1); // Force to first core
if (_CoreParameter.bUseFastMem)
{
@@ -296,13 +294,13 @@ THREAD_RETURN CpuThread(void *pArg)
#ifdef __APPLE__
[pool release];
#endif
- return 0;
+ return;
}
// Initalize plugins and create emulation thread
// Call browser: Init():g_EmuThread(). See the BootManager.cpp file description for a complete call schedule.
-THREAD_RETURN EmuThread(void *pArg)
+void EmuThread()
{
#ifdef __APPLE__
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -319,9 +317,9 @@ THREAD_RETURN EmuThread(void *pArg)
if (_CoreParameter.bLockThreads)
{
if (cpu_info.num_cores > 3)
- Common::Thread::SetCurrentThreadAffinity(4); // Force to third, non-HT core
+ Common::SetCurrentThreadAffinity(4); // Force to third, non-HT core
else
- Common::Thread::SetCurrentThreadAffinity(2); // Force to second core
+ Common::SetCurrentThreadAffinity(2); // Force to second core
}
INFO_LOG(OSREPORT, "Starting core = %s mode", _CoreParameter.bWii ? "Wii" : "Gamecube");
@@ -420,7 +418,7 @@ THREAD_RETURN EmuThread(void *pArg)
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
// Spawn the CPU thread
- _dbg_assert_(OSHLE, cpuThread == NULL);
+ _dbg_assert_(OSHLE, !cpuThread.joinable());
// ENTER THE VIDEO THREAD LOOP
if (_CoreParameter.bCPUThread)
{
@@ -428,7 +426,7 @@ THREAD_RETURN EmuThread(void *pArg)
// and then takes over and becomes the video thread
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
- cpuThread = new Common::Thread(CpuThread, pArg);
+ cpuThread = std::thread(CpuThread);
Common::SetCurrentThreadName("Video thread");
// Update the window again because all stuff is initialized
@@ -444,7 +442,7 @@ THREAD_RETURN EmuThread(void *pArg)
// Without this extra thread, the video plugin window hangs in single
// core mode since noone is pumping messages.
- cpuThread = new Common::Thread(CpuThread, pArg);
+ cpuThread = std::thread(CpuThread);
Common::SetCurrentThreadName("Emuthread - Idle");
// Update the window again because all stuff is initialized
@@ -475,13 +473,10 @@ THREAD_RETURN EmuThread(void *pArg)
// At this point, the CpuThread has already returned in SC mode.
// But it may still be waiting in Dual Core mode.
- if (cpuThread)
+ if (cpuThread.joinable())
{
// There is a CPU thread - join it.
- cpuThread->WaitForDeath();
- delete cpuThread;
- // Returns after game exited
- cpuThread = NULL;
+ cpuThread.join();
}
VolumeHandler::EjectVolume();
@@ -517,7 +512,6 @@ THREAD_RETURN EmuThread(void *pArg)
#ifdef __APPLE__
[pool release];
#endif
- return 0;
}
// Set or get the running state
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceGecko.cpp b/Source/Core/Core/Src/HW/EXI_DeviceGecko.cpp
index 40a7bec838..a6d5df1d47 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceGecko.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceGecko.cpp
@@ -19,45 +19,41 @@
#include "EXI_DeviceGecko.h"
#include "../Core.h"
-THREAD_RETURN ClientThreadFunc(void *arg)
+void ClientThreadFunc(GeckoSockServer *arg)
{
- ((GeckoSockServer*)arg)->ClientThread();
- return 0;
+ arg->ClientThread();
}
u16 GeckoSockServer::server_port;
int GeckoSockServer::client_count;
-Common::Thread *GeckoSockServer::connectionThread = NULL;
+std::thread GeckoSockServer::connectionThread;
volatile bool GeckoSockServer::server_running;
std::queue<sf::SocketTCP> GeckoSockServer::waiting_socks;
Common::CriticalSection GeckoSockServer::connection_lock;
GeckoSockServer::GeckoSockServer()
- : clientThread(NULL)
- , client_running(false)
+ : client_running(false)
{
- if (!connectionThread)
- connectionThread = new Common::Thread(&GeckoConnectionWaiter, (void*)0);
+ if (!connectionThread.joinable())
+ connectionThread = std::thread(GeckoConnectionWaiter);
}
GeckoSockServer::~GeckoSockServer()
{
- if (clientThread)
+ if (clientThread.joinable())
--client_count;
client_running = false;
- delete clientThread;
- clientThread = NULL;
+ clientThread.join();
if (client_count <= 0)
{
server_running = false;
- delete connectionThread;
- connectionThread = NULL;
+ connectionThread.join();
}
}
-THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
+void GeckoSockServer::GeckoConnectionWaiter()
{
Common::SetCurrentThreadName("Gecko Connection Waiter");
@@ -70,7 +66,7 @@ THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
}
if (!server_running)
- return 0;
+ return;
Core::DisplayMessage(
StringFromFormat("USBGecko: Listening on TCP port %u", server_port),
@@ -90,7 +86,6 @@ THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
SLEEP(1);
}
server.Close();
- return 0;
}
bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
@@ -101,15 +96,15 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
if (waiting_socks.size())
{
sock_to_fill = waiting_socks.front();
- if (clientThread)
+ if (clientThread.joinable())
{
client_running = false;
- delete clientThread;
- clientThread = NULL;
+ clientThread.join();
+
recv_fifo = std::queue<u8>();
send_fifo = std::queue<u8>();
}
- clientThread = new Common::Thread(ClientThreadFunc, this);
+ clientThread = std::thread(ClientThreadFunc, this);
client_count++;
waiting_socks.pop();
sock_filled = true;
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceGecko.h b/Source/Core/Core/Src/HW/EXI_DeviceGecko.h
index 7c62fc1dfa..af4642b83d 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceGecko.h
+++ b/Source/Core/Core/Src/HW/EXI_DeviceGecko.h
@@ -33,7 +33,7 @@ public:
// Client for this server object
sf::SocketTCP client;
void ClientThread();
- Common::Thread *clientThread;
+ std::thread clientThread;
Common::CriticalSection transfer_lock;
std::queue<u8> send_fifo;
@@ -44,11 +44,11 @@ private:
volatile bool client_running;
// Only ever one server thread
- static THREAD_RETURN GeckoConnectionWaiter(void*);
+ static void GeckoConnectionWaiter();
static u16 server_port;
static volatile bool server_running;
- static Common::Thread *connectionThread;
+ static std::thread connectionThread;
static std::queue<sf::SocketTCP> waiting_socks;
static Common::CriticalSection connection_lock;
};
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
index 967b11a8cf..bcb3c5d59a 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
@@ -46,8 +46,7 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate)
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
m_strFilename(_rFilename),
card_index(_card_index),
- m_bDirty(false),
- flushThread(NULL)
+ m_bDirty(false)
{
cards[_card_index] = this;
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
@@ -103,9 +102,8 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
}
}
-THREAD_RETURN innerFlush(void *pArgs)
+void innerFlush(flushStruct* data)
{
- flushStruct *data = ((flushStruct *)pArgs);
FILE* pFile = NULL;
pFile = fopen(data->filename.c_str(), "wb");
@@ -123,7 +121,7 @@ THREAD_RETURN innerFlush(void *pArgs)
PanicAlertT("Could not write memory card file %s.\n\n"
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", data->filename.c_str());
delete data;
- return 0;
+ return;
}
fwrite(data->memcardContent, data->memcardSize, 1, pFile);
@@ -134,7 +132,7 @@ THREAD_RETURN innerFlush(void *pArgs)
data->filename.c_str()).c_str(), 4000);
delete data;
- return 0;
+ return;
}
// Flush memory card contents to disc
@@ -143,10 +141,9 @@ void CEXIMemoryCard::Flush(bool exiting)
if(!m_bDirty)
return;
- if(flushThread)
+ if (flushThread.joinable())
{
- delete flushThread;
- flushThread = NULL;
+ flushThread.join();
}
if(!exiting)
@@ -159,9 +156,9 @@ void CEXIMemoryCard::Flush(bool exiting)
fs->memcardSize = memory_card_size;
fs->bExiting = exiting;
- flushThread = new Common::Thread(innerFlush, fs);
- if(exiting)
- flushThread->WaitForDeath();
+ flushThread = std::thread(innerFlush, fs);
+ if (exiting)
+ flushThread.join();
m_bDirty = false;
}
@@ -171,10 +168,10 @@ CEXIMemoryCard::~CEXIMemoryCard()
Flush(true);
delete[] memory_card_content;
memory_card_content = NULL;
- if(flushThread)
+
+ if (flushThread.joinable())
{
- delete flushThread;
- flushThread = NULL;
+ flushThread.join();
}
}
@@ -186,10 +183,9 @@ bool CEXIMemoryCard::IsPresent()
void CEXIMemoryCard::SetCS(int cs)
{
// So that memory card won't be invalidated during flushing
- if(flushThread)
+ if (flushThread.joinable())
{
- delete flushThread;
- flushThread = NULL;
+ flushThread.join();
}
if (cs) // not-selected to selected
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
index 2acc4d7577..127dfa2b15 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
+++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
@@ -90,7 +90,7 @@ private:
int memory_card_size; //! in bytes, must be power of 2.
u8 *memory_card_content;
- Common::Thread *flushThread;
+ std::thread flushThread;
protected:
virtual void TransferByte(u8 &byte);
diff --git a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp
index 999a861c22..1940be4bdb 100644
--- a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp
+++ b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp
@@ -22,14 +22,14 @@
#include "Thread.h"
#include <queue>
-static Common::Thread *connectionThread = NULL;
+static std::thread connectionThread;
static std::queue<sf::SocketTCP> waiting_socks;
static Common::CriticalSection cs_gba;
namespace { volatile bool server_running; }
// --- GameBoy Advance "Link Cable" ---
-THREAD_RETURN GBAConnectionWaiter(void*)
+void GBAConnectionWaiter()
{
server_running = true;
@@ -38,7 +38,7 @@ THREAD_RETURN GBAConnectionWaiter(void*)
sf::SocketTCP server;
// "dolphin gba"
if (!server.Listen(0xd6ba))
- return 0;
+ return;
server.SetBlocking(false);
@@ -54,14 +54,14 @@ THREAD_RETURN GBAConnectionWaiter(void*)
SLEEP(1);
}
server.Close();
- return 0;
+ return;
}
void GBAConnectionWaiter_Shutdown()
{
server_running = false;
- delete connectionThread;
- connectionThread = NULL;
+ if (connectionThread.joinable())
+ connectionThread.join();
}
bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
@@ -82,8 +82,8 @@ bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
GBASockServer::GBASockServer()
{
- if (!connectionThread)
- connectionThread = new Common::Thread(GBAConnectionWaiter, (void*)0);
+ if (!connectionThread.joinable())
+ connectionThread = std::thread(GBAConnectionWaiter);
}
GBASockServer::~GBASockServer()
diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp
index f167a741f2..53cc8019ab 100644
--- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp
+++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp
@@ -41,10 +41,10 @@ bool g_real_wiimotes_initialized = false;
unsigned int g_wiimotes_found = 0;
volatile bool g_run_wiimote_thread = false;
-Common::Thread *g_wiimote_threads[MAX_WIIMOTES] = {};
+std::thread g_wiimote_threads[MAX_WIIMOTES] = {};
Common::CriticalSection g_refresh_critsec;
-THREAD_RETURN WiimoteThreadFunc(void* arg);
+void WiimoteThreadFunc(Wiimote& arg);
void StartWiimoteThreads();
void StopWiimoteThreads();
@@ -433,10 +433,10 @@ void Refresh()
if (g_wiimotes[i] && (!(WIIMOTE_SRC_REAL & g_wiimote_sources[i]) ||
!g_wiimotes[i]->IsConnected()))
{
+ // TODO: this looks broken
delete g_wiimotes[i];
g_wiimotes[i] = NULL;
- delete g_wiimote_threads[i];
- g_wiimote_threads[i] = NULL;
+ g_wiimote_threads[i].join();
--g_wiimotes_found;
}
@@ -510,57 +510,51 @@ void StartWiimoteThreads()
{
g_run_wiimote_thread = true;
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
- if (g_wiimotes[i] && !g_wiimote_threads[i])
- g_wiimote_threads[i] = new Common::Thread(WiimoteThreadFunc, g_wiimotes[i]);
+ if (g_wiimotes[i])
+ g_wiimote_threads[i] = std::thread(WiimoteThreadFunc, *g_wiimotes[i]);
}
void StopWiimoteThreads()
{
g_run_wiimote_thread = false;
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
- if (g_wiimote_threads[i])
- {
- delete g_wiimote_threads[i];
- g_wiimote_threads[i] = NULL;
- }
+ if (g_wiimote_threads[i].joinable())
+ g_wiimote_threads[i].join();
}
-THREAD_RETURN WiimoteThreadFunc(void* arg)
+void WiimoteThreadFunc(Wiimote& wiimote)
{
#ifdef __APPLE__
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
#endif
- Wiimote* const wiimote = (Wiimote*)arg;
-
char thname[] = "Wiimote # Thread";
- thname[8] = (char)('1' + wiimote->index);
+ thname[8] = (char)('1' + wiimote.index);
Common::SetCurrentThreadName(thname);
// rumble briefly
- wiimote->Rumble();
+ wiimote.Rumble();
- Host_ConnectWiimote(wiimote->index, true);
+ Host_ConnectWiimote(wiimote.index, true);
// main loop
- while (g_run_wiimote_thread && wiimote->IsConnected())
+ while (g_run_wiimote_thread && wiimote.IsConnected())
{
// hopefully this is alright
- while (wiimote->Write()) {}
+ while (wiimote.Write()) {}
#ifndef __APPLE__
// sleep if there was nothing to read
- if (false == wiimote->Read())
+ if (false == wiimote.Read())
#endif
Common::SleepCurrentThread(1);
}
- Host_ConnectWiimote(wiimote->index, false);
+ Host_ConnectWiimote(wiimote.index, false);
#ifdef __APPLE__
[pool release];
#endif
- return 0;
}
}; // end of namespace
diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp
index 2f68db0feb..85f27e19cf 100644
--- a/Source/Core/Core/Src/State.cpp
+++ b/Source/Core/Core/Src/State.cpp
@@ -69,7 +69,7 @@ static u8 *undoLoad = NULL;
static bool const bCompressed = true;
-static Common::Thread *saveThread = NULL;
+static std::thread saveThread;
// Don't forget to increase this after doing changes on the savestate system
@@ -159,9 +159,8 @@ void VerifyBufferStateCallback(u64 userdata, int cyclesLate)
state_op_in_progress = false;
}
-THREAD_RETURN CompressAndDumpState(void *pArgs)
+void CompressAndDumpState(saveStruct* saveArg)
{
- saveStruct *saveArg = (saveStruct *)pArgs;
u8 *buffer = saveArg->buffer;
size_t sz = saveArg->size;
lzo_uint out_len = 0;
@@ -185,7 +184,7 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
{
Core::DisplayMessage("Could not save state", 2000);
delete[] buffer;
- return 0;
+ return;
}
// Setting up the header
@@ -229,7 +228,6 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
filename.c_str()).c_str(), 2000);
state_op_in_progress = false;
- return 0;
}
void SaveStateCallback(u64 userdata, int cyclesLate)
@@ -263,7 +261,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
Core::DisplayMessage("Saving State...", 1000);
- saveThread = new Common::Thread(CompressAndDumpState, saveData);
+ saveThread = std::thread(CompressAndDumpState, saveData);
// Resume the clock
PowerPC::Start();
@@ -592,10 +590,9 @@ void State_VerifyBuffer(u8 **buffer)
void State_Flush()
{
// If already saving state, wait for it to finish
- if (saveThread)
+ if (saveThread.joinable())
{
- delete saveThread;
- saveThread = NULL;
+ saveThread.join();
}
}
diff --git a/Source/Core/DolphinWX/Src/NetPlay.cpp b/Source/Core/DolphinWX/Src/NetPlay.cpp
index 62b00c9439..179ea3e3a1 100644
--- a/Source/Core/DolphinWX/Src/NetPlay.cpp
+++ b/Source/Core/DolphinWX/Src/NetPlay.cpp
@@ -38,10 +38,9 @@ extern CFrame* main_frame;
DEFINE_EVENT_TYPE(wxEVT_THREAD)
-THREAD_RETURN NetPlayThreadFunc(void* arg)
+void NetPlayThreadFunc(NetPlay* np)
{
- ((NetPlay*)arg)->Entry();
- return 0;
+ np->Entry();
}
// called from ---GUI--- thread
diff --git a/Source/Core/DolphinWX/Src/NetPlay.h b/Source/Core/DolphinWX/Src/NetPlay.h
index cdc6305c67..dcdd8bdd2e 100644
--- a/Source/Core/DolphinWX/Src/NetPlay.h
+++ b/Source/Core/DolphinWX/Src/NetPlay.h
@@ -76,8 +76,6 @@ enum
CON_ERR_VERSION_MISMATCH
};
-THREAD_RETURN NetPlayThreadFunc(void* arg);
-
// something like this should be in Common stuff
class CritLocker
{
@@ -116,7 +114,6 @@ public:
u8 GetPadNum(u8 numPAD);
protected:
- //NetPlay(Common::ThreadFunc entry, void* arg) : m_thread(entry, arg) {}
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
void ClearBuffers();
void UpdateGUI();
@@ -149,7 +146,7 @@ protected:
NetPlayDiag* m_dialog;
sf::SocketTCP m_socket;
- Common::Thread* m_thread;
+ std::thread m_thread;
sf::Selector<sf::SocketTCP> m_selector;
std::string m_selected_game;
@@ -166,6 +163,8 @@ private:
};
+void NetPlayThreadFunc(NetPlay* arg);
+
void NetPlay_Enable(NetPlay* const np);
void NetPlay_Disable();
diff --git a/Source/Core/DolphinWX/Src/NetPlayClient.cpp b/Source/Core/DolphinWX/Src/NetPlayClient.cpp
index a685d1ee4f..639dee80ef 100644
--- a/Source/Core/DolphinWX/Src/NetPlayClient.cpp
+++ b/Source/Core/DolphinWX/Src/NetPlayClient.cpp
@@ -7,8 +7,7 @@ NetPlayClient::~NetPlayClient()
if (is_connected)
{
m_do_loop = false;
- m_thread->WaitForDeath();
- delete m_thread;
+ m_thread.join();
}
}
@@ -73,7 +72,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, const s
is_connected = true;
m_selector.Add(m_socket);
- m_thread = new Common::Thread(NetPlayThreadFunc, this);
+ m_thread = std::thread(NetPlayThreadFunc, this);
}
}
else
diff --git a/Source/Core/DolphinWX/Src/NetPlayServer.cpp b/Source/Core/DolphinWX/Src/NetPlayServer.cpp
index 70992630e7..f6c6de5de9 100644
--- a/Source/Core/DolphinWX/Src/NetPlayServer.cpp
+++ b/Source/Core/DolphinWX/Src/NetPlayServer.cpp
@@ -7,8 +7,7 @@ NetPlayServer::~NetPlayServer()
if (is_connected)
{
m_do_loop = false;
- m_thread->WaitForDeath();
- delete m_thread;
+ m_thread.join();
}
}
@@ -41,7 +40,7 @@ NetPlayServer::NetPlayServer(const u16 port, const std::string& name, NetPlayDia
is_connected = true;
m_selector.Add(m_socket);
- m_thread = new Common::Thread(NetPlayThreadFunc, this);
+ m_thread = std::thread(NetPlayThreadFunc, this);
}
else
is_connected = false;
diff --git a/Source/Core/InputCommon/Src/UDPWiimote.cpp b/Source/Core/InputCommon/Src/UDPWiimote.cpp
index 6fde1732d9..558e4d902d 100644
--- a/Source/Core/InputCommon/Src/UDPWiimote.cpp
+++ b/Source/Core/InputCommon/Src/UDPWiimote.cpp
@@ -47,7 +47,7 @@
struct UDPWiimote::_d
{
- Common::Thread * thread;
+ std::thread thread;
std::list<sock_t> sockfds;
Common::CriticalSection termLock,mutex,nameMutex;
volatile bool exit;
@@ -56,15 +56,9 @@ struct UDPWiimote::_d
int UDPWiimote::noinst=0;
-void _UDPWiiThread(void* arg)
+void UDPWiiThread(UDPWiimote* arg)
{
- ((UDPWiimote*)arg)->mainThread();
-}
-
-THREAD_RETURN UDPWiiThread(void* arg)
-{
- _UDPWiiThread(arg);
- return 0;
+ arg->mainThread();
}
UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
@@ -86,7 +80,6 @@ UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
#endif
struct addrinfo hints, *servinfo, *p;
int rv;
- d->thread=NULL;
#ifdef _WIN32
if (noinst==0)
@@ -142,7 +135,7 @@ UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
initBroadcastIPv4();
initBroadcastIPv6();
d->termLock.Enter();
- d->thread = new Common::Thread(UDPWiiThread,this);
+ d->thread = std::thread(UDPWiiThread, this);
d->termLock.Leave();
return;
}
@@ -226,8 +219,8 @@ void UDPWiimote::mainThread()
UDPWiimote::~UDPWiimote()
{
- d->exit=true;
- d->thread->WaitForDeath();
+ d->exit = true;
+ d->thread.join();
d->termLock.Enter();
d->termLock.Leave();
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
diff --git a/Source/Core/InputCommon/Src/UDPWiimote.h b/Source/Core/InputCommon/Src/UDPWiimote.h
index c1c39b2887..02fa4f66bc 100644
--- a/Source/Core/InputCommon/Src/UDPWiimote.h
+++ b/Source/Core/InputCommon/Src/UDPWiimote.h
@@ -21,6 +21,7 @@
class UDPWiimote
{
+ friend void UDPWiiThread(UDPWiimote* arg);
public:
UDPWiimote(const char * port, const char * name, int index);
virtual ~UDPWiimote();
@@ -49,7 +50,6 @@ private:
int index;
int int_port;
static int noinst;
- friend void _UDPWiiThread(void* arg);
void broadcastPresence();
void broadcastIPv4(const void * data, size_t size);
void broadcastIPv6(const void * data, size_t size);