This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
The-Powder-Toy/src/common/tpt-thread-local.h
Tamás Bálint Misius 4f0c365e05
Preprocessor purge round 19: Split and minimize usage of Config.h
Also mostly banish it from other headers, and shuffle standard header includes to minimize cross-contamination between headers.
2023-01-27 09:27:32 +01:00

64 lines
1.3 KiB
C++

#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