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;
#ifdef _LARGE_WORLDS
unsigned int Chunk::tlsIdx = TlsAlloc();
thread_local uint8_t* Chunk::m_threadTileIds = nullptr;
void Chunk::CreateNewThreadStorage() {
unsigned char* tileIds = new unsigned char[16 * 16 * Level::maxBuildHeight];
TlsSetValue(tlsIdx, tileIds);
m_threadTileIds = new unsigned char[16 * 16 * Level::maxBuildHeight];
}
void Chunk::ReleaseThreadStorage() {
unsigned char* tileIds = (unsigned char*)TlsGetValue(tlsIdx);
delete tileIds;
delete m_threadTileIds;
}
unsigned char* Chunk::GetTileIdsStorage() {
unsigned char* tileIds = (unsigned char*)TlsGetValue(tlsIdx);
return tileIds;
uint8_t* Chunk::GetTileIdsStorage() {
return m_threadTileIds;
}
#else
// 4J Stu - Don't want this when multi-threaded

View file

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

View file

@ -20,37 +20,7 @@ const std::wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top";
const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f;
namespace {
#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
thread_local bool PistonBaseTile::m_threadIgnoreUpdate = false;
// 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
@ -62,12 +32,11 @@ PistonBaseTile::TlsKey PistonBaseTile::tlsIdx = CreatePistonTlsKey();
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make
// thread safe
bool PistonBaseTile::ignoreUpdate() {
return PistonTlsGetValue(tlsIdx) != NULL;
return m_threadIgnoreUpdate;
}
void PistonBaseTile::ignoreUpdate(bool set) {
PistonTlsSetValue(
tlsIdx, reinterpret_cast<void*>(static_cast<intptr_t>(set ? 1 : 0)));
m_threadIgnoreUpdate = set;
}
PistonBaseTile::PistonBaseTile(int id, bool isSticky)

View file

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

View file

@ -9,47 +9,16 @@
#include "../Headers/net.minecraft.world.h"
#include <cstdint>
namespace {
#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
thread_local bool TheEndPortal::m_threadAllowAnywhere = false;
// 4J - allowAnywhere is a static in java, implementing as TLS here to make
// thread safe
bool TheEndPortal::allowAnywhere() {
return TheEndPortalTlsGetValue(tlsIdx) != NULL;
return m_threadAllowAnywhere;
}
void TheEndPortal::allowAnywhere(bool set) {
TheEndPortalTlsSetValue(
tlsIdx, reinterpret_cast<void*>(static_cast<intptr_t>(set ? 1 : 0)));
m_threadAllowAnywhere = set;
}
TheEndPortal::TheEndPortal(int id, Material* material)

View file

@ -3,20 +3,10 @@
#include "BaseEntityTile.h"
#include <cstdint>
#if !defined(_WIN32)
#include <pthread.h>
#endif
class IconRegister;
class TheEndPortal : public BaseEntityTile {
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
static bool allowAnywhere();
static void allowAnywhere(bool set);
@ -43,4 +33,7 @@ public:
virtual void onPlace(Level* level, int x, int y, int z);
virtual int cloneTileId(Level* level, int x, int y, int z);
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"
#endif //__PS3__
unsigned int Compression::tlsIdx = 0;
Compression::ThreadStorage* Compression::tlsDefault = NULL;
thread_local Compression::ThreadStorage* Compression::m_threadCompression = nullptr;
Compression::ThreadStorage* Compression::m_threadCompressionDefault = nullptr;
Compression::ThreadStorage::ThreadStorage() { compression = new Compression(); }
@ -26,28 +26,24 @@ Compression::ThreadStorage::~ThreadStorage() { delete compression; }
void Compression::CreateNewThreadStorage() {
ThreadStorage* tls = new ThreadStorage();
if (tlsDefault == nullptr) {
pthread_key_create(&tlsIdx, nullptr);
tlsDefault = tls;
if (m_threadCompressionDefault == nullptr) {
m_threadCompressionDefault = tls;
}
pthread_setspecific(tlsIdx, tls);
m_threadCompression = tls;
}
void Compression::UseDefaultThreadStorage() {
pthread_setspecific(tlsIdx, tlsDefault);
m_threadCompression = m_threadCompressionDefault;
}
void Compression::ReleaseThreadStorage() {
ThreadStorage* tls =
(ThreadStorage*)pthread_getspecific(tlsIdx); // POSIX equivalent
if (tls != tlsDefault) {
delete tls;
if (m_threadCompression != m_threadCompressionDefault) {
delete m_threadCompression;
}
}
Compression* Compression::getCompression() {
ThreadStorage* tls = (ThreadStorage*)pthread_getspecific(tlsIdx);
return tls->compression;
return m_threadCompression->compression;
}
HRESULT Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize,

View file

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