From 7c6c6d3df72ff04fd2f88552847fcc67370ead71 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:22:02 -0500 Subject: [PATCH 1/4] refactor: replace winapi TLS functions in Vec3 and AABB --- Minecraft.World/Util/AABB.cpp | 23 ++++++++++------------- Minecraft.World/Util/AABB.h | 4 ++-- Minecraft.World/Util/Vec3.cpp | 22 ++++++++++------------ Minecraft.World/Util/Vec3.h | 5 +++-- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index c4a8bff2e..3dff9c23d 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -7,8 +7,8 @@ #include "AABB.h" #include "HitResult.h" -unsigned int AABB::tlsIdx = 0; -AABB::ThreadStorage* AABB::tlsDefault = NULL; +thread_local AABB::ThreadStorage* AABB::m_tlsPool = nullptr; +AABB::ThreadStorage* AABB::m_tlsPoolDefault = nullptr; AABB::ThreadStorage::ThreadStorage() { pool = new AABB[POOL_SIZE]; // 4jcraft, needs to be deleted with delete[] @@ -21,21 +21,18 @@ AABB::ThreadStorage::~ThreadStorage() { void AABB::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; + if (m_tlsPoolDefault == nullptr) { + m_tlsPoolDefault = tls; } - - TlsSetValue(tlsIdx, tls); + m_tlsPool = m_tlsPoolDefault; } -void AABB::UseDefaultThreadStorage() { TlsSetValue(tlsIdx, tlsDefault); } +void AABB::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } void AABB::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; + if (m_tlsPool != m_tlsPoolDefault) { + delete m_tlsPool; + } } AABB* AABB::newPermanent(double x0, double y0, double z0, double x1, double y1, @@ -49,7 +46,7 @@ void AABB::resetPool() {} AABB* AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); + ThreadStorage* tls = m_tlsPool; AABB* thisAABB = &tls->pool[tls->poolPointer]; thisAABB->set(x0, y0, z0, x1, y1, z1); tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index bcd941f39..205d5ac98 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -15,8 +15,8 @@ class AABB { ThreadStorage(); ~ThreadStorage(); }; - static unsigned int tlsIdx; - static ThreadStorage* tlsDefault; + static thread_local ThreadStorage* m_tlsPool; + static ThreadStorage* m_tlsPoolDefault; public: // Each new thread that needs to use Vec3 pools will need to call one of the diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 4e42b99a3..7796aba16 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -2,8 +2,8 @@ #include "Vec3.h" #include "AABB.h" -unsigned int Vec3::tlsIdx = 0; -Vec3::ThreadStorage* Vec3::tlsDefault = NULL; +thread_local Vec3::ThreadStorage* Vec3::m_tlsPool = nullptr; +Vec3::ThreadStorage* Vec3::m_tlsPoolDefault = nullptr; Vec3::ThreadStorage::ThreadStorage() { pool = new Vec3[POOL_SIZE]; @@ -14,20 +14,18 @@ Vec3::ThreadStorage::~ThreadStorage() { delete[] pool; } void Vec3::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; + if (m_tlsPoolDefault == nullptr) { + m_tlsPoolDefault = tls; } - TlsSetValue(tlsIdx, tls); + m_tlsPool = m_tlsPoolDefault; } -void Vec3::UseDefaultThreadStorage() { TlsSetValue(tlsIdx, tlsDefault); } +void Vec3::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } void Vec3::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; + if (m_tlsPool != m_tlsPoolDefault) { + delete m_tlsPool; + } } Vec3* Vec3::newPermanent(double x, double y, double z) { @@ -39,7 +37,7 @@ void Vec3::clearPool() {} void Vec3::resetPool() {} Vec3* Vec3::newTemp(double x, double y, double z) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); + ThreadStorage* tls = m_tlsPool; Vec3* thisVec = &tls->pool[tls->poolPointer]; thisVec->set(x, y, z); tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index bc1239d81..da9fcc73b 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -12,8 +12,9 @@ class Vec3 { ThreadStorage(); ~ThreadStorage(); }; - static unsigned int tlsIdx; - static ThreadStorage* tlsDefault; + + static thread_local ThreadStorage* m_tlsPool; + static ThreadStorage* m_tlsPoolDefault; public: // Each new thread that needs to use Vec3 pools will need to call one of the From 7b18641f7006984ccf26e406f36862a501ab1e0f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:24:45 -0500 Subject: [PATCH 2/4] chore: clean up unused code from Linux_Minecraft.cpp --- Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp index 852dbb58c..4daca7e16 100644 --- a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp @@ -5,7 +5,6 @@ #include // #include -#include #if defined(__linux__) && defined(__GLIBC__) #include #include @@ -710,16 +709,6 @@ void CleanupDevice() { } #endif -int StartMinecraftThreadProc(void* lpParameter) { - Vec3::UseDefaultThreadStorage(); - AABB::UseDefaultThreadStorage(); - Tesselator::CreateNewThreadStorage(1024 * 1024); - RenderManager.InitialiseContext(); - Minecraft::start(std::wstring(), std::wstring()); - delete Tesselator::getInstance(); - return 0; -} - int main(int argc, const char* argv[]) { #if defined(__linux__) && defined(__GLIBC__) struct sigaction sa; @@ -1202,7 +1191,7 @@ void FreeRichPresenceStrings() { vRichPresenceStrings.clear(); } -#ifdef MEMORY_TRACKING +#if 0 // #ifdef MEMORY_TRACKING int totalAllocGen = 0; std::unordered_map allocCounts; From 9fec342554f3c8d7dc9d418071d9b0951352c81b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:32:06 -0500 Subject: [PATCH 3/4] remove TlsAlloc, TlsFree, TlsGetValue, TlsSetValue --- .../Platform/Linux/Stubs/winapi_stubs.h | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h index 452562fad..78fe936b2 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h @@ -306,28 +306,6 @@ static inline ULONG TryEnterCriticalSection( return pthread_mutex_trylock(CriticalSection) == 0; } -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc -static inline DWORD TlsAlloc(VOID) { - pthread_key_t key; - if (pthread_key_create(&key, NULL) == 0) return key; - return TLS_OUT_OF_INDEXES; -} - -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree -static inline BOOL TlsFree(DWORD dwTlsIndex) { - return pthread_key_delete(dwTlsIndex) == 0; -} - -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsgetvalue -static inline LPVOID TlsGetValue(DWORD dwTlsIndex) { - return pthread_getspecific(dwTlsIndex); -} - -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlssetvalue -static inline BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) { - return pthread_setspecific(dwTlsIndex, lpTlsValue) == 0; -} - // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalmemorystatus static inline VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { // TODO: Parse /proc/meminfo and set lpBuffer based on that. Probably will From 06a4096cf6a904f822ee0456cbe813b33f570422 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 18:43:10 -0500 Subject: [PATCH 4/4] fix: properly assign new pool to m_tlsPool --- Minecraft.World/Util/AABB.cpp | 2 +- Minecraft.World/Util/Vec3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index 3dff9c23d..f09dbc6f0 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -24,7 +24,7 @@ void AABB::CreateNewThreadStorage() { if (m_tlsPoolDefault == nullptr) { m_tlsPoolDefault = tls; } - m_tlsPool = m_tlsPoolDefault; + m_tlsPool = tls; } void AABB::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 7796aba16..fcc922af2 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -17,7 +17,7 @@ void Vec3::CreateNewThreadStorage() { if (m_tlsPoolDefault == nullptr) { m_tlsPoolDefault = tls; } - m_tlsPool = m_tlsPoolDefault; + m_tlsPool = tls; } void Vec3::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; }