mirror of https://github.com/PCSX2/pcsx2.git
common: drop pthread TLS emulation
thread_local is supported by all C++11 compliant compiler Keep a way to disable TLS for shared object to avoid issue of DTV slot shortage.
This commit is contained in:
parent
11aebe465f
commit
a378e307b3
|
@ -108,7 +108,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\include\Utilities\EventSource.inl" />
|
<None Include="..\..\include\Utilities\EventSource.inl" />
|
||||||
<None Include="..\..\include\Utilities\TlsVariable.inl" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\include\Utilities\EmbeddedImage.h" />
|
<ClInclude Include="..\..\include\Utilities\EmbeddedImage.h" />
|
||||||
|
|
|
@ -127,9 +127,6 @@
|
||||||
<None Include="..\..\include\Utilities\EventSource.inl">
|
<None Include="..\..\include\Utilities\EventSource.inl">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\..\include\Utilities\TlsVariable.inl">
|
|
||||||
<Filter>Header Files\Threading</Filter>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\Utilities\ThreadingInternal.h">
|
<ClInclude Include="..\..\src\Utilities\ThreadingInternal.h">
|
||||||
|
|
|
@ -66,15 +66,21 @@ extern ConsoleLogSource_Threading pxConLog_Thread;
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// PCSX2_THREAD_LOCAL - Defines platform/operating system support for Thread Local Storage
|
// PCSX2_THREAD_LOCAL - Defines platform/operating system support for Thread Local Storage
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// For complimentary support for TLS, include Utilities/TlsVariable.inl, and use the
|
|
||||||
// DeclareTls macro in the place of __threadlocal.
|
|
||||||
//
|
//
|
||||||
//#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux)
|
// TLS is enabled by default. It will be disabled at compile time for Linux plugin.
|
||||||
|
// If you link SPU2X/ZZOGL with a TLS library, you will consume a DVT slots. Slots
|
||||||
|
// are rather limited and it ends up to "impossible to dlopen the library"
|
||||||
|
// None of the above plugin uses TLS variable in a multithread context
|
||||||
#ifndef PCSX2_THREAD_LOCAL
|
#ifndef PCSX2_THREAD_LOCAL
|
||||||
#define PCSX2_THREAD_LOCAL 1
|
#define PCSX2_THREAD_LOCAL 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PCSX2_THREAD_LOCAL
|
||||||
|
#define DeclareTls(x) thread_local x
|
||||||
|
#else
|
||||||
|
#define DeclareTls(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
class wxTimeSpan;
|
class wxTimeSpan;
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
|
|
|
@ -1,190 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Threading.h"
|
|
||||||
|
|
||||||
#if PCSX2_THREAD_LOCAL
|
|
||||||
#define DeclareTls(x) thread_local x
|
|
||||||
#else
|
|
||||||
#define DeclareTls(x) Threading::TlsVariable<x>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Threading
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// TlsVariable - Thread local storage
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// Wrapper class for pthread_getspecific, which is pthreads language for "thread local
|
|
||||||
// storage." This class enables code to act as a drop-in replacement for compiler-native
|
|
||||||
// thread local storage (typically specified via __threadlocal). Mac OS/X (Darwin) does
|
|
||||||
// not have TLS, which is the main reason for this class existing.
|
|
||||||
//
|
|
||||||
// Performance considerations: While certainly convenient, performance of this class can
|
|
||||||
// be sub-optimal when the operator overloads are used, since each one will most likely
|
|
||||||
// result in repeated calls to pthread_getspecific. (if the function inlines then it
|
|
||||||
// should actually optimize well enough, but I doubt it does).
|
|
||||||
//
|
|
||||||
template <typename T>
|
|
||||||
class BaseTlsVariable
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(BaseTlsVariable<T>);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
pthread_key_t m_thread_key;
|
|
||||||
bool m_IsDisposed;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BaseTlsVariable();
|
|
||||||
|
|
||||||
virtual ~BaseTlsVariable() throw()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
T *GetPtr() const;
|
|
||||||
T &GetRef() const { return *GetPtr(); }
|
|
||||||
|
|
||||||
operator T &() const { return GetRef(); }
|
|
||||||
T *operator->() const { return GetPtr(); }
|
|
||||||
|
|
||||||
void Dispose()
|
|
||||||
{
|
|
||||||
if (!m_IsDisposed) {
|
|
||||||
m_IsDisposed = true;
|
|
||||||
KillKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void CreateKey();
|
|
||||||
void KillKey();
|
|
||||||
|
|
||||||
virtual void CreateInstance(T *result) const
|
|
||||||
{
|
|
||||||
new (result) T();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _aligned_delete_and_free(void *ptr)
|
|
||||||
{
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
((T *)ptr)->~T();
|
|
||||||
_aligned_free(ptr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class TlsVariable : public BaseTlsVariable<T>
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(TlsVariable<T>);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
T m_initval;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TlsVariable() {}
|
|
||||||
TlsVariable(const T &initval)
|
|
||||||
: m_initval(initval)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is needed; The C++ standard likes making life suck for programmers.
|
|
||||||
using BaseTlsVariable<T>::GetRef;
|
|
||||||
|
|
||||||
virtual ~TlsVariable() throw()
|
|
||||||
{
|
|
||||||
// disable the parent cleanup. This leaks memory blocks, but its necessary because
|
|
||||||
// TLS is expected to be persistent until the very end of execution on the main thread.
|
|
||||||
// Killing the pthread_key at all will lead to the console logger death, etc.
|
|
||||||
|
|
||||||
// DON'T REMOVE this->, the "official"[ly stupid] C++ standard requires it because of its
|
|
||||||
// insistence that variables be looked up during initial template parsing and not during
|
|
||||||
// instantiation.
|
|
||||||
this->m_IsDisposed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TlsVariable<T> &operator=(const T &src)
|
|
||||||
{
|
|
||||||
GetRef() = src;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const T &src) const { return GetRef() == src; }
|
|
||||||
bool operator!=(const T &src) const { return GetRef() != src; }
|
|
||||||
bool operator>(const T &src) const { return GetRef() > src; }
|
|
||||||
bool operator<(const T &src) const { return GetRef() < src; }
|
|
||||||
bool operator>=(const T &src) const { return GetRef() >= src; }
|
|
||||||
bool operator<=(const T &src) const { return GetRef() <= src; }
|
|
||||||
|
|
||||||
T operator+(const T &src) const { return GetRef() + src; }
|
|
||||||
T operator-(const T &src) const { return GetRef() - src; }
|
|
||||||
|
|
||||||
void operator+=(const T &src) { GetRef() += src; }
|
|
||||||
void operator-=(const T &src) { GetRef() -= src; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void CreateInstance(T *result) const
|
|
||||||
{
|
|
||||||
new (result) T(m_initval);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Threading::BaseTlsVariable<T>::BaseTlsVariable()
|
|
||||||
{
|
|
||||||
m_IsDisposed = false;
|
|
||||||
CreateKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Threading::BaseTlsVariable<T>::KillKey()
|
|
||||||
{
|
|
||||||
if (!m_thread_key)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Delete the handle for the current thread (which should always be the main/UI thread!)
|
|
||||||
// This is needed because pthreads does *not* clean up the dangling objects when you delete
|
|
||||||
// the key. The TLS for the process main thread will only be deleted when the process
|
|
||||||
// ends; which is too damn late (it shows up int he leaked memory blocks).
|
|
||||||
|
|
||||||
BaseTlsVariable<T>::_aligned_delete_and_free(pthread_getspecific(m_thread_key));
|
|
||||||
|
|
||||||
pthread_key_delete(m_thread_key);
|
|
||||||
m_thread_key = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T *Threading::BaseTlsVariable<T>::GetPtr() const
|
|
||||||
{
|
|
||||||
T *result = (T *)pthread_getspecific(m_thread_key);
|
|
||||||
if (result == NULL) {
|
|
||||||
pthread_setspecific(m_thread_key, result = (T *)_aligned_malloc(sizeof(T), 16));
|
|
||||||
CreateInstance(result);
|
|
||||||
if (result == NULL)
|
|
||||||
throw Exception::OutOfMemory(L"thread local storage variable instance");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Threading::BaseTlsVariable<T>::CreateKey()
|
|
||||||
{
|
|
||||||
if (0 != pthread_key_create(&m_thread_key, BaseTlsVariable<T>::_aligned_delete_and_free)) {
|
|
||||||
pxFailRel("Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash.");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,6 @@ set(UtilitiesSources
|
||||||
../../include/Utilities/FixedPointTypes.inl
|
../../include/Utilities/FixedPointTypes.inl
|
||||||
../../include/Utilities/EventSource.inl
|
../../include/Utilities/EventSource.inl
|
||||||
../../include/Utilities/SafeArray.inl
|
../../include/Utilities/SafeArray.inl
|
||||||
../../include/Utilities/TlsVariable.inl
|
|
||||||
CheckedStaticBox.cpp
|
CheckedStaticBox.cpp
|
||||||
Console.cpp
|
Console.cpp
|
||||||
EventSource.cpp
|
EventSource.cpp
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Threading.h"
|
#include "Threading.h"
|
||||||
#include "TraceLog.h"
|
#include "TraceLog.h"
|
||||||
#include "TlsVariable.inl"
|
|
||||||
|
|
||||||
#include "RedtapeWindows.h" // nneded for OutputDebugString
|
#include "RedtapeWindows.h" // nneded for OutputDebugString
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include "Threading.h"
|
#include "Threading.h"
|
||||||
#include "TlsVariable.inl"
|
|
||||||
|
|
||||||
#if defined(__UNIX__)
|
#if defined(__UNIX__)
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "../DebugTools/SymbolMap.h"
|
#include "../DebugTools/SymbolMap.h"
|
||||||
|
|
||||||
#include "Utilities/PageFaultSource.h"
|
#include "Utilities/PageFaultSource.h"
|
||||||
#include "Utilities/TlsVariable.inl"
|
#include "Utilities/Threading.h"
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
# include <wx/msw/wrapwin.h>
|
# include <wx/msw/wrapwin.h>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "Utilities/TlsVariable.inl"
|
#include "Utilities/Threading.h"
|
||||||
|
|
||||||
#include <wx/stackwalk.h>
|
#include <wx/stackwalk.h>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "Debugger/DisassemblyDialog.h"
|
#include "Debugger/DisassemblyDialog.h"
|
||||||
|
|
||||||
#include "Utilities/TlsVariable.inl"
|
#include "Utilities/Threading.h"
|
||||||
|
|
||||||
#include "ps2/BiosTools.h"
|
#include "ps2/BiosTools.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
|
|
Loading…
Reference in New Issue