Remove THREAD_LOCAL hack, use thread_local
We dropped support for the buggy toolchains that needed this hack.
This commit is contained in:
parent
bc9d43bb10
commit
5da4c04f35
@ -4,7 +4,6 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "common/tpt-thread-local.h"
|
|
||||||
#include "String.h"
|
#include "String.h"
|
||||||
|
|
||||||
ByteString ConversionError::formatError(ByteString::value_type const *at, ByteString::value_type const *upto)
|
ByteString ConversionError::formatError(ByteString::value_type const *at, ByteString::value_type const *upto)
|
||||||
@ -376,7 +375,7 @@ struct LocaleImpl
|
|||||||
|
|
||||||
static LocaleImpl *getLocaleImpl()
|
static LocaleImpl *getLocaleImpl()
|
||||||
{
|
{
|
||||||
static THREAD_LOCAL(LocaleImpl, li);
|
thread_local LocaleImpl li;
|
||||||
return &li;
|
return &li;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
common_files += files(
|
common_files += files(
|
||||||
'String.cpp',
|
'String.cpp',
|
||||||
'tpt-rand.cpp',
|
'tpt-rand.cpp',
|
||||||
'tpt-thread-local.cpp',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('clipboard')
|
subdir('clipboard')
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
#include "tpt-thread-local.h"
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
# include <pthread.h>
|
|
||||||
# include <cstdlib>
|
|
||||||
# include <cassert>
|
|
||||||
|
|
||||||
void *ThreadLocalCommon::Get() const
|
|
||||||
{
|
|
||||||
// https://stackoverflow.com/questions/16552710/how-do-you-get-the-start-and-end-addresses-of-a-custom-elf-section
|
|
||||||
extern ThreadLocalCommon __start_tpt_tls;
|
|
||||||
extern ThreadLocalCommon __stop_tpt_tls;
|
|
||||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
|
||||||
static pthread_key_t key;
|
|
||||||
|
|
||||||
struct ThreadLocalEntry
|
|
||||||
{
|
|
||||||
void *ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto *staticsBegin = &__start_tpt_tls;
|
|
||||||
auto *staticsEnd = &__stop_tpt_tls;
|
|
||||||
pthread_once(&once, []() -> void {
|
|
||||||
assert(!pthread_key_create(&key, [](void *opaque) -> void {
|
|
||||||
auto *staticsBegin = &__start_tpt_tls;
|
|
||||||
auto *staticsEnd = &__stop_tpt_tls;
|
|
||||||
auto staticsCount = staticsEnd - staticsBegin;
|
|
||||||
auto *liveObjects = reinterpret_cast<ThreadLocalEntry *>(opaque);
|
|
||||||
if (liveObjects)
|
|
||||||
{
|
|
||||||
for (auto i = 0; i < staticsCount; ++i)
|
|
||||||
{
|
|
||||||
if (liveObjects[i].ptr)
|
|
||||||
{
|
|
||||||
staticsBegin[i].dtor(liveObjects[i].ptr);
|
|
||||||
free(liveObjects[i].ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(liveObjects);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
auto *liveObjects = reinterpret_cast<ThreadLocalEntry *>(pthread_getspecific(key));
|
|
||||||
if (!liveObjects)
|
|
||||||
{
|
|
||||||
auto staticsCount = staticsEnd - staticsBegin;
|
|
||||||
liveObjects = reinterpret_cast<ThreadLocalEntry *>(calloc(staticsCount, sizeof(ThreadLocalEntry)));
|
|
||||||
assert(liveObjects);
|
|
||||||
assert(!pthread_setspecific(key, reinterpret_cast<void *>(liveObjects)));
|
|
||||||
}
|
|
||||||
auto idx = this - staticsBegin;
|
|
||||||
auto &entry = liveObjects[idx];
|
|
||||||
if (!entry.ptr)
|
|
||||||
{
|
|
||||||
entry.ptr = malloc(staticsBegin[idx].size);
|
|
||||||
assert(entry.ptr);
|
|
||||||
staticsBegin[idx].ctor(entry.ptr);
|
|
||||||
}
|
|
||||||
return entry.ptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
# include <cstddef>
|
|
||||||
|
|
||||||
class ThreadLocalCommon
|
|
||||||
{
|
|
||||||
ThreadLocalCommon(const ThreadLocalCommon &other) = delete;
|
|
||||||
ThreadLocalCommon &operator =(const ThreadLocalCommon &other) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t size;
|
|
||||||
void (*ctor)(void *);
|
|
||||||
void (*dtor)(void *);
|
|
||||||
size_t padding;
|
|
||||||
|
|
||||||
void *Get() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadLocalCommon() = default;
|
|
||||||
|
|
||||||
static constexpr size_t Alignment = 0x20;
|
|
||||||
};
|
|
||||||
// * If this fails, add or remove padding fields, possibly change Alignment to a larger power of 2.
|
|
||||||
static_assert(sizeof(ThreadLocalCommon) == ThreadLocalCommon::Alignment, "fix me");
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class ThreadLocal : public ThreadLocalCommon
|
|
||||||
{
|
|
||||||
static void Ctor(void *type)
|
|
||||||
{
|
|
||||||
new(type) Type();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Dtor(void *type)
|
|
||||||
{
|
|
||||||
reinterpret_cast<Type *>(type)->~Type();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadLocal()
|
|
||||||
{
|
|
||||||
// * If this fails, you're out of luck.
|
|
||||||
static_assert(sizeof(ThreadLocal<Type>) == sizeof(ThreadLocalCommon), "fix me");
|
|
||||||
size = sizeof(Type);
|
|
||||||
ctor = Ctor;
|
|
||||||
dtor = Dtor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *operator &() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<Type *>(Get());
|
|
||||||
}
|
|
||||||
|
|
||||||
operator Type &() const
|
|
||||||
{
|
|
||||||
return *(this->operator &());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
# define THREAD_LOCAL(Type, tl) const ThreadLocal<Type> tl __attribute__((section("tpt_tls"), aligned(ThreadLocalCommon::Alignment)))
|
|
||||||
#else
|
|
||||||
# define THREAD_LOCAL(Type, tl) thread_local Type tl
|
|
||||||
#endif
|
|
@ -7,7 +7,6 @@
|
|||||||
#include "client/GameSave.h"
|
#include "client/GameSave.h"
|
||||||
#include "common/tpt-compat.h"
|
#include "common/tpt-compat.h"
|
||||||
#include "common/tpt-rand.h"
|
#include "common/tpt-rand.h"
|
||||||
#include "common/tpt-thread-local.h"
|
|
||||||
#include "gui/game/Brush.h"
|
#include "gui/game/Brush.h"
|
||||||
#include "elements/EMP.h"
|
#include "elements/EMP.h"
|
||||||
#include "elements/LOLZ.h"
|
#include "elements/LOLZ.h"
|
||||||
@ -452,7 +451,7 @@ bool Simulation::FloodFillPmapCheck(int x, int y, int type) const
|
|||||||
CoordStack& Simulation::getCoordStackSingleton()
|
CoordStack& Simulation::getCoordStackSingleton()
|
||||||
{
|
{
|
||||||
// Future-proofing in case Simulation is later multithreaded
|
// Future-proofing in case Simulation is later multithreaded
|
||||||
static THREAD_LOCAL(CoordStack, cs);
|
thread_local CoordStack cs;
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user