From a378e307b3edff4056812d4a64ee51bea2efd0e1 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Fri, 14 Apr 2017 17:18:20 +0200 Subject: [PATCH] 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. --- common/build/Utilities/utilities.vcxproj | 1 - .../build/Utilities/utilities.vcxproj.filters | 3 - common/include/Utilities/Threading.h | 14 +- common/include/Utilities/TlsVariable.inl | 190 ------------------ common/src/Utilities/CMakeLists.txt | 1 - common/src/Utilities/Console.cpp | 1 - common/src/Utilities/Exceptions.cpp | 1 - pcsx2/System/SysCoreThread.cpp | 2 +- pcsx2/gui/AppAssert.cpp | 2 +- pcsx2/gui/AppCoreThread.cpp | 2 +- 10 files changed, 13 insertions(+), 204 deletions(-) delete mode 100644 common/include/Utilities/TlsVariable.inl diff --git a/common/build/Utilities/utilities.vcxproj b/common/build/Utilities/utilities.vcxproj index a94c324771..e58d4a4506 100644 --- a/common/build/Utilities/utilities.vcxproj +++ b/common/build/Utilities/utilities.vcxproj @@ -108,7 +108,6 @@ - diff --git a/common/build/Utilities/utilities.vcxproj.filters b/common/build/Utilities/utilities.vcxproj.filters index f60cbd81ad..0fbdf1ba3c 100644 --- a/common/build/Utilities/utilities.vcxproj.filters +++ b/common/build/Utilities/utilities.vcxproj.filters @@ -127,9 +127,6 @@ Header Files - - Header Files\Threading - diff --git a/common/include/Utilities/Threading.h b/common/include/Utilities/Threading.h index eb9e442c9f..8058ba4a3a 100644 --- a/common/include/Utilities/Threading.h +++ b/common/include/Utilities/Threading.h @@ -66,15 +66,21 @@ extern ConsoleLogSource_Threading pxConLog_Thread; // -------------------------------------------------------------------------------------- // 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 #define PCSX2_THREAD_LOCAL 1 #endif +#if PCSX2_THREAD_LOCAL +#define DeclareTls(x) thread_local x +#else +#define DeclareTls(x) x +#endif + class wxTimeSpan; namespace Threading diff --git a/common/include/Utilities/TlsVariable.inl b/common/include/Utilities/TlsVariable.inl deleted file mode 100644 index c83d21663f..0000000000 --- a/common/include/Utilities/TlsVariable.inl +++ /dev/null @@ -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 . - */ - -#pragma once - -#include "Threading.h" - -#if PCSX2_THREAD_LOCAL -#define DeclareTls(x) thread_local x -#else -#define DeclareTls(x) Threading::TlsVariable -#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 -class BaseTlsVariable -{ - DeclareNoncopyableObject(BaseTlsVariable); - -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 -class TlsVariable : public BaseTlsVariable -{ - DeclareNoncopyableObject(TlsVariable); - -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::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 &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 -Threading::BaseTlsVariable::BaseTlsVariable() -{ - m_IsDisposed = false; - CreateKey(); -} - -template -void Threading::BaseTlsVariable::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::_aligned_delete_and_free(pthread_getspecific(m_thread_key)); - - pthread_key_delete(m_thread_key); - m_thread_key = 0; -} - -template -T *Threading::BaseTlsVariable::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 -void Threading::BaseTlsVariable::CreateKey() -{ - if (0 != pthread_key_create(&m_thread_key, BaseTlsVariable::_aligned_delete_and_free)) { - pxFailRel("Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash."); - } -} diff --git a/common/src/Utilities/CMakeLists.txt b/common/src/Utilities/CMakeLists.txt index 3bfbc7340e..eeed998315 100644 --- a/common/src/Utilities/CMakeLists.txt +++ b/common/src/Utilities/CMakeLists.txt @@ -20,7 +20,6 @@ set(UtilitiesSources ../../include/Utilities/FixedPointTypes.inl ../../include/Utilities/EventSource.inl ../../include/Utilities/SafeArray.inl - ../../include/Utilities/TlsVariable.inl CheckedStaticBox.cpp Console.cpp EventSource.cpp diff --git a/common/src/Utilities/Console.cpp b/common/src/Utilities/Console.cpp index 1c7f57410a..bfa5bf3116 100644 --- a/common/src/Utilities/Console.cpp +++ b/common/src/Utilities/Console.cpp @@ -16,7 +16,6 @@ #include "PrecompiledHeader.h" #include "Threading.h" #include "TraceLog.h" -#include "TlsVariable.inl" #include "RedtapeWindows.h" // nneded for OutputDebugString diff --git a/common/src/Utilities/Exceptions.cpp b/common/src/Utilities/Exceptions.cpp index f61cf7dc45..2a6d43f544 100644 --- a/common/src/Utilities/Exceptions.cpp +++ b/common/src/Utilities/Exceptions.cpp @@ -17,7 +17,6 @@ #include #include "Threading.h" -#include "TlsVariable.inl" #if defined(__UNIX__) #include diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index 6a15299354..9b989da9d9 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -29,7 +29,7 @@ #include "../DebugTools/SymbolMap.h" #include "Utilities/PageFaultSource.h" -#include "Utilities/TlsVariable.inl" +#include "Utilities/Threading.h" #ifdef __WXMSW__ # include diff --git a/pcsx2/gui/AppAssert.cpp b/pcsx2/gui/AppAssert.cpp index 3fa30e4617..a282715c4e 100644 --- a/pcsx2/gui/AppAssert.cpp +++ b/pcsx2/gui/AppAssert.cpp @@ -15,7 +15,7 @@ #include "PrecompiledHeader.h" #include "App.h" -#include "Utilities/TlsVariable.inl" +#include "Utilities/Threading.h" #include diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 91efb7c224..63a464ea5a 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -22,7 +22,7 @@ #include "Debugger/DisassemblyDialog.h" -#include "Utilities/TlsVariable.inl" +#include "Utilities/Threading.h" #include "ps2/BiosTools.h" #include "GS.h"