refactor: switch to thread_local in Chunk, PistonBaseTile, TheEndPortalTile, Compression

This commit is contained in:
Tropical 2026-03-25 14:41:08 -05:00
parent 4a1fb94600
commit 9ff2fb4fef
8 changed files with 29 additions and 103 deletions

View file

@ -20,21 +20,18 @@
int Chunk::updates = 0; int Chunk::updates = 0;
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
unsigned int Chunk::tlsIdx = TlsAlloc(); thread_local uint8_t* Chunk::m_threadTileIds = nullptr;
void Chunk::CreateNewThreadStorage() { void Chunk::CreateNewThreadStorage() {
unsigned char* tileIds = new unsigned char[16 * 16 * Level::maxBuildHeight]; m_threadTileIds = new unsigned char[16 * 16 * Level::maxBuildHeight];
TlsSetValue(tlsIdx, tileIds);
} }
void Chunk::ReleaseThreadStorage() { void Chunk::ReleaseThreadStorage() {
unsigned char* tileIds = (unsigned char*)TlsGetValue(tlsIdx); delete m_threadTileIds;
delete tileIds;
} }
unsigned char* Chunk::GetTileIdsStorage() { uint8_t* Chunk::GetTileIdsStorage() {
unsigned char* tileIds = (unsigned char*)TlsGetValue(tlsIdx); return m_threadTileIds;
return tileIds;
} }
#else #else
// 4J Stu - Don't want this when multi-threaded // 4J Stu - Don't want this when multi-threaded

View file

@ -30,12 +30,12 @@ private:
#ifndef _LARGE_WORLDS #ifndef _LARGE_WORLDS
static Tesselator* t; static Tesselator* t;
#else #else
static unsigned int tlsIdx; static thread_local uint8_t* m_threadTileIds;
public: public:
static void CreateNewThreadStorage(); static void CreateNewThreadStorage();
static void ReleaseThreadStorage(); static void ReleaseThreadStorage();
static unsigned char* GetTileIdsStorage(); static uint8_t* GetTileIdsStorage();
#endif #endif
public: public:

View file

@ -20,37 +20,7 @@ const std::wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top";
const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f; const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f;
namespace { thread_local bool PistonBaseTile::m_threadIgnoreUpdate = false;
#if defined(_WIN32)
inline void* PistonTlsGetValue(PistonBaseTile::TlsKey key) {
return TlsGetValue(key);
}
inline void PistonTlsSetValue(PistonBaseTile::TlsKey key, void* value) {
TlsSetValue(key, value);
}
#else
pthread_key_t CreatePistonTlsKey() {
pthread_key_t key;
pthread_key_create(&key, NULL);
return key;
}
inline void* PistonTlsGetValue(pthread_key_t key) {
return pthread_getspecific(key);
}
inline void PistonTlsSetValue(pthread_key_t key, void* value) {
pthread_setspecific(key, value);
}
#endif
} // namespace
#if defined(_WIN32)
PistonBaseTile::TlsKey PistonBaseTile::tlsIdx = TlsAlloc();
#else
PistonBaseTile::TlsKey PistonBaseTile::tlsIdx = CreatePistonTlsKey();
#endif
// 4J - NOTE - this ignoreUpdate stuff has been removed from the java version, // 4J - NOTE - this ignoreUpdate stuff has been removed from the java version,
// but I'm not currently sure how the java version does without it... there must // but I'm not currently sure how the java version does without it... there must
@ -62,12 +32,11 @@ PistonBaseTile::TlsKey PistonBaseTile::tlsIdx = CreatePistonTlsKey();
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make // 4J - ignoreUpdate is a static in java, implementing as TLS here to make
// thread safe // thread safe
bool PistonBaseTile::ignoreUpdate() { bool PistonBaseTile::ignoreUpdate() {
return PistonTlsGetValue(tlsIdx) != NULL; return m_threadIgnoreUpdate;
} }
void PistonBaseTile::ignoreUpdate(bool set) { void PistonBaseTile::ignoreUpdate(bool set) {
PistonTlsSetValue( m_threadIgnoreUpdate = set;
tlsIdx, reinterpret_cast<void*>(static_cast<intptr_t>(set ? 1 : 0)));
} }
PistonBaseTile::PistonBaseTile(int id, bool isSticky) PistonBaseTile::PistonBaseTile(int id, bool isSticky)

View file

@ -35,6 +35,8 @@ private:
Icon* iconBack; Icon* iconBack;
Icon* iconPlatform; Icon* iconPlatform;
static thread_local bool m_threadIgnoreUpdate;
static TlsKey tlsIdx; static TlsKey tlsIdx;
// 4J - was just a static but implemented with TLS for our version // 4J - was just a static but implemented with TLS for our version
static bool ignoreUpdate(); static bool ignoreUpdate();

View file

@ -9,47 +9,16 @@
#include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.world.h"
#include <cstdint> #include <cstdint>
namespace { thread_local bool TheEndPortal::m_threadAllowAnywhere = false;
#if defined(_WIN32)
inline void* TheEndPortalTlsGetValue(TheEndPortal::TlsKey key) {
return TlsGetValue(key);
}
inline void TheEndPortalTlsSetValue(TheEndPortal::TlsKey key, void* value) {
TlsSetValue(key, value);
}
#else
pthread_key_t CreateTheEndPortalTlsKey() {
pthread_key_t key;
pthread_key_create(&key, NULL);
return key;
}
inline void* TheEndPortalTlsGetValue(pthread_key_t key) {
return pthread_getspecific(key);
}
inline void TheEndPortalTlsSetValue(pthread_key_t key, void* value) {
pthread_setspecific(key, value);
}
#endif
} // namespace
#if defined(_WIN32)
TheEndPortal::TlsKey TheEndPortal::tlsIdx = TlsAlloc();
#else
TheEndPortal::TlsKey TheEndPortal::tlsIdx = CreateTheEndPortalTlsKey();
#endif
// 4J - allowAnywhere is a static in java, implementing as TLS here to make // 4J - allowAnywhere is a static in java, implementing as TLS here to make
// thread safe // thread safe
bool TheEndPortal::allowAnywhere() { bool TheEndPortal::allowAnywhere() {
return TheEndPortalTlsGetValue(tlsIdx) != NULL; return m_threadAllowAnywhere;
} }
void TheEndPortal::allowAnywhere(bool set) { void TheEndPortal::allowAnywhere(bool set) {
TheEndPortalTlsSetValue( m_threadAllowAnywhere = set;
tlsIdx, reinterpret_cast<void*>(static_cast<intptr_t>(set ? 1 : 0)));
} }
TheEndPortal::TheEndPortal(int id, Material* material) TheEndPortal::TheEndPortal(int id, Material* material)

View file

@ -3,20 +3,10 @@
#include "BaseEntityTile.h" #include "BaseEntityTile.h"
#include <cstdint> #include <cstdint>
#if !defined(_WIN32)
#include <pthread.h>
#endif
class IconRegister; class IconRegister;
class TheEndPortal : public BaseEntityTile { class TheEndPortal : public BaseEntityTile {
public: public:
#if defined(_WIN32)
using TlsKey = std::uint32_t;
#else
using TlsKey = pthread_key_t;
#endif
static TlsKey tlsIdx;
// 4J - was just a static but implemented with TLS for our version // 4J - was just a static but implemented with TLS for our version
static bool allowAnywhere(); static bool allowAnywhere();
static void allowAnywhere(bool set); static void allowAnywhere(bool set);
@ -43,4 +33,7 @@ public:
virtual void onPlace(Level* level, int x, int y, int z); virtual void onPlace(Level* level, int x, int y, int z);
virtual int cloneTileId(Level* level, int x, int y, int z); virtual int cloneTileId(Level* level, int x, int y, int z);
void registerIcons(IconRegister* iconRegister); void registerIcons(IconRegister* iconRegister);
private:
static thread_local bool m_threadAllowAnywhere;
}; };

View file

@ -17,8 +17,8 @@
#include "../../../Minecraft.Client/Platform/PS3/PS3Extras/EdgeZLib.h" #include "../../../Minecraft.Client/Platform/PS3/PS3Extras/EdgeZLib.h"
#endif //__PS3__ #endif //__PS3__
unsigned int Compression::tlsIdx = 0; thread_local Compression::ThreadStorage* Compression::m_threadCompression = nullptr;
Compression::ThreadStorage* Compression::tlsDefault = NULL; Compression::ThreadStorage* Compression::m_threadCompressionDefault = nullptr;
Compression::ThreadStorage::ThreadStorage() { compression = new Compression(); } Compression::ThreadStorage::ThreadStorage() { compression = new Compression(); }
@ -26,28 +26,24 @@ Compression::ThreadStorage::~ThreadStorage() { delete compression; }
void Compression::CreateNewThreadStorage() { void Compression::CreateNewThreadStorage() {
ThreadStorage* tls = new ThreadStorage(); ThreadStorage* tls = new ThreadStorage();
if (tlsDefault == nullptr) { if (m_threadCompressionDefault == nullptr) {
pthread_key_create(&tlsIdx, nullptr); m_threadCompressionDefault = tls;
tlsDefault = tls;
} }
pthread_setspecific(tlsIdx, tls); m_threadCompression = tls;
} }
void Compression::UseDefaultThreadStorage() { void Compression::UseDefaultThreadStorage() {
pthread_setspecific(tlsIdx, tlsDefault); m_threadCompression = m_threadCompressionDefault;
} }
void Compression::ReleaseThreadStorage() { void Compression::ReleaseThreadStorage() {
ThreadStorage* tls = if (m_threadCompression != m_threadCompressionDefault) {
(ThreadStorage*)pthread_getspecific(tlsIdx); // POSIX equivalent delete m_threadCompression;
if (tls != tlsDefault) {
delete tls;
} }
} }
Compression* Compression::getCompression() { Compression* Compression::getCompression() {
ThreadStorage* tls = (ThreadStorage*)pthread_getspecific(tlsIdx); return m_threadCompression->compression;
return tls->compression;
} }
HRESULT Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize, HRESULT Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize,

View file

@ -25,8 +25,8 @@ private:
ThreadStorage(); ThreadStorage();
~ThreadStorage(); ~ThreadStorage();
}; };
static unsigned int tlsIdx; static thread_local ThreadStorage* m_threadCompression;
static ThreadStorage* tlsDefault; static ThreadStorage* m_threadCompressionDefault;
public: public:
// Each new thread that needs to use Compression will need to call one of // Each new thread that needs to use Compression will need to call one of