From a82d76ca464481bbcaad012202aab32efd525018 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:43:41 -0500 Subject: [PATCH 01/12] refactor: `Tesselator` thread-local storage --- Minecraft.Client/Rendering/Tesselator.cpp | 7 +++---- Minecraft.Client/Rendering/Tesselator.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 35e472a45..25d9014b2 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -24,15 +24,14 @@ int normal; */ -unsigned int Tesselator::tlsIdx = TlsAlloc(); +thread_local Tesselator* Tesselator::m_thread_instance = nullptr; Tesselator* Tesselator::getInstance() { - return (Tesselator*)TlsGetValue(tlsIdx); + return m_thread_instance; } void Tesselator::CreateNewThreadStorage(int bytes) { - Tesselator* instance = new Tesselator(bytes / 4); - TlsSetValue(tlsIdx, instance); + Tesselator::m_thread_instance = new Tesselator(bytes / 4); } // she tessalate my vertices till i render diff --git a/Minecraft.Client/Rendering/Tesselator.h b/Minecraft.Client/Rendering/Tesselator.h index 02d43a12c..bd9edecc2 100644 --- a/Minecraft.Client/Rendering/Tesselator.h +++ b/Minecraft.Client/Rendering/Tesselator.h @@ -41,7 +41,7 @@ public: static void CreateNewThreadStorage(int bytes); private: - static unsigned int tlsIdx; + static thread_local Tesselator* m_thread_instance; public: static Tesselator* getInstance(); From 03f62dcb9ef8c12cd9dd68791a473a68a665b492 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:59:15 -0500 Subject: [PATCH 02/12] refactor: `FireworksRecipe` thread-local storage --- Minecraft.Client/Rendering/Tesselator.cpp | 6 ++--- Minecraft.Client/Rendering/Tesselator.h | 2 +- Minecraft.World/Recipes/FireworksRecipe.cpp | 27 +++++++++++---------- Minecraft.World/Recipes/FireworksRecipe.h | 4 +-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 25d9014b2..aac70dfaf 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -24,14 +24,14 @@ int normal; */ -thread_local Tesselator* Tesselator::m_thread_instance = nullptr; +thread_local Tesselator* Tesselator::m_threadInstance = nullptr; Tesselator* Tesselator::getInstance() { - return m_thread_instance; + return m_threadinstance; } void Tesselator::CreateNewThreadStorage(int bytes) { - Tesselator::m_thread_instance = new Tesselator(bytes / 4); + Tesselator::m_threadinstance = new Tesselator(bytes / 4); } // she tessalate my vertices till i render diff --git a/Minecraft.Client/Rendering/Tesselator.h b/Minecraft.Client/Rendering/Tesselator.h index bd9edecc2..ac3103b7d 100644 --- a/Minecraft.Client/Rendering/Tesselator.h +++ b/Minecraft.Client/Rendering/Tesselator.h @@ -41,7 +41,7 @@ public: static void CreateNewThreadStorage(int bytes); private: - static thread_local Tesselator* m_thread_instance; + static thread_local Tesselator* m_threadInstance; public: static Tesselator* getInstance(); diff --git a/Minecraft.World/Recipes/FireworksRecipe.cpp b/Minecraft.World/Recipes/FireworksRecipe.cpp index 60ec92d9b..21a4d8a8a 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.cpp +++ b/Minecraft.World/Recipes/FireworksRecipe.cpp @@ -2,34 +2,35 @@ #include "../Headers/net.minecraft.world.item.h" #include "FireworksRecipe.h" -DWORD FireworksRecipe::tlsIdx = 0; -FireworksRecipe::ThreadStorage* FireworksRecipe::tlsDefault = NULL; +thread_local FireworksRecipe::ThreadStorage* FireworksRecipe::m_threadStorage = + nullptr; +FireworksRecipe::ThreadStorage* FireworksRecipe::m_defaultThreadStorage = + nullptr; FireworksRecipe::ThreadStorage::ThreadStorage() { resultItem = nullptr; } void FireworksRecipe::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; + + if (m_defaultThreadStorage == nullptr) { + m_defaultThreadStorage = tls; } - TlsSetValue(tlsIdx, tls); + + m_threadStorage = tls; } void FireworksRecipe::UseDefaultThreadStorage() { - TlsSetValue(tlsIdx, tlsDefault); + m_threadStorage = m_defaultThreadStorage; } void FireworksRecipe::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; + if (m_threadStorage != m_defaultThreadStorage) { + delete m_threadStorage; + } } void FireworksRecipe::setResultItem(std::shared_ptr item) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - tls->resultItem = item; + m_threadStorage->resultItem = item; } FireworksRecipe::FireworksRecipe() { diff --git a/Minecraft.World/Recipes/FireworksRecipe.h b/Minecraft.World/Recipes/FireworksRecipe.h index a371a8360..34998fd68 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.h +++ b/Minecraft.World/Recipes/FireworksRecipe.h @@ -13,8 +13,8 @@ private: std::shared_ptr resultItem; ThreadStorage(); }; - static DWORD tlsIdx; - static ThreadStorage* tlsDefault; + static thread_local ThreadStorage* m_threadStorage; + static ThreadStorage* m_defaultThreadStorage; void setResultItem(std::shared_ptr item); From 625ce973857562c0e5383327974aac6fbefdf44f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:13:00 -0500 Subject: [PATCH 03/12] refactor: use thread_local in OldChunkStorage, FireworksRecipe, Level, Entity --- Minecraft.Client/Rendering/Tesselator.cpp | 4 +- Minecraft.World/Core/BehaviorRegistry.h | 2 +- Minecraft.World/Entities/Entity.cpp | 48 +++------------ Minecraft.World/Entities/Entity.h | 6 +- Minecraft.World/Level/Level.cpp | 51 +++------------- Minecraft.World/Level/Level.h | 15 ++--- .../Level/Storage/OldChunkStorage.cpp | 58 +++++-------------- .../Level/Storage/OldChunkStorage.h | 4 +- Minecraft.World/Recipes/FireworksRecipe.cpp | 6 +- 9 files changed, 44 insertions(+), 150 deletions(-) diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index aac70dfaf..661eb121b 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -27,11 +27,11 @@ int normal; thread_local Tesselator* Tesselator::m_threadInstance = nullptr; Tesselator* Tesselator::getInstance() { - return m_threadinstance; + return m_threadInstance; } void Tesselator::CreateNewThreadStorage(int bytes) { - Tesselator::m_threadinstance = new Tesselator(bytes / 4); + Tesselator::m_threadInstance = new Tesselator(bytes / 4); } // she tessalate my vertices till i render diff --git a/Minecraft.World/Core/BehaviorRegistry.h b/Minecraft.World/Core/BehaviorRegistry.h index f49d924f1..23b0161bc 100644 --- a/Minecraft.World/Core/BehaviorRegistry.h +++ b/Minecraft.World/Core/BehaviorRegistry.h @@ -1,6 +1,6 @@ #pragma once -class DispenseItemBehavior; +#include "DispenseItemBehavior.h" class BehaviorRegistry { private: diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index c0f4412ed..872e0c23c 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -26,40 +26,12 @@ #include "../../Minecraft.Client/Level/ServerLevel.h" #include "../../Minecraft.Client/Network/PlayerList.h" -namespace { -#if defined(_WIN32) -inline void* EntityTlsGetValue(Entity::TlsKey key) { return TlsGetValue(key); } - -inline void EntityTlsSetValue(Entity::TlsKey key, void* value) { - TlsSetValue(key, value); -} -#else -pthread_key_t CreateEntityTlsKey() { - pthread_key_t key; - const int result = pthread_key_create(&key, nullptr); - assert(result == 0); - return key; -} - -inline void* EntityTlsGetValue(pthread_key_t key) { - return pthread_getspecific(key); -} - -inline void EntityTlsSetValue(pthread_key_t key, void* value) { - pthread_setspecific(key, value); -} -#endif -} // namespace +thread_local bool Entity::m_threadUseSmallIds = false; const std::wstring Entity::RIDING_TAG = L"Riding"; int Entity::entityCounter = 2048; // 4J - changed initialiser to 2048, as we are using range 0 - 2047 // as special unique smaller ids for things that need network tracked -#if defined(_WIN32) -Entity::TlsKey Entity::tlsIdx = TlsAlloc(); -#else -Entity::TlsKey Entity::tlsIdx = CreateEntityTlsKey(); -#endif // 4J - added getSmallId & freeSmallId methods unsigned int Entity::entityIdUsedFlags[2048 / 32] = {0}; @@ -82,7 +54,7 @@ int Entity::getSmallId() { // telling the client that the entity has been removed After we have already // re-used its Id and created a new entity. This ends up with newly created // client-side entities being removed by accident, causing invisible mobs. - if (reinterpret_cast(EntityTlsGetValue(tlsIdx)) != 0) { + if (m_threadUseSmallIds) { MinecraftServer* server = MinecraftServer::getInstance(); if (server) { // In some attempt to optimise this, flagEntitiesToBeRemoved most of @@ -157,13 +129,13 @@ void Entity::countFlagsForPIX() { void Entity::resetSmallId() { freeSmallId(entityId); - if (reinterpret_cast(EntityTlsGetValue(tlsIdx)) != 0) { + if (m_threadUseSmallIds) { entityId = getSmallId(); } } void Entity::freeSmallId(int index) { - if (reinterpret_cast(EntityTlsGetValue(tlsIdx)) == 0) + if (!m_threadUseSmallIds) return; // Don't do anything with small ids if this isn't the server // thread if (index >= 2048) return; // Don't do anything if this isn't a short id @@ -176,10 +148,7 @@ void Entity::freeSmallId(int index) { entityIdWanderFlags[i] &= uiMask; } -void Entity::useSmallIds() { - EntityTlsSetValue(tlsIdx, - reinterpret_cast(static_cast(1))); -} +void Entity::useSmallIds() { m_threadUseSmallIds = true; } // Things also added here to be able to manage the concept of a number of extra // "wandering" entities - normally path finding entities aren't allowed to @@ -192,7 +161,7 @@ void Entity::useSmallIds() { // Let the management system here know whether or not to consider this // particular entity for some extra wandering void Entity::considerForExtraWandering(bool enable) { - if (reinterpret_cast(EntityTlsGetValue(tlsIdx)) == 0) + if (!m_threadUseSmallIds) return; // Don't do anything with small ids if this isn't the server // thread if (entityId >= 2048) return; // Don't do anything if this isn't a short id @@ -211,7 +180,7 @@ void Entity::considerForExtraWandering(bool enable) { // Should this entity do wandering in addition to what the java code would have // done? bool Entity::isExtraWanderingEnabled() { - if (reinterpret_cast(EntityTlsGetValue(tlsIdx)) == 0) + if (!m_threadUseSmallIds) return false; // Don't do anything with small ids if this isn't the // server thread if (entityId >= 2048) @@ -278,8 +247,7 @@ void Entity::_init(bool useSmallId, Level* level) { // rest of the range is used for anything we don't need to track like this, // currently particles. We only ever want to allocate this type of id from // the server thread, so using thread local storage to isolate this. - if (useSmallId && - reinterpret_cast(EntityTlsGetValue(tlsIdx)) != 0) { + if (useSmallId && m_threadUseSmallIds) { entityId = getSmallId(); } else { entityId = Entity::entityCounter++; diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index 3fceb64b6..9374fea4e 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -6,9 +6,6 @@ #include "../Util/Vec3.h" #include "../Util/Definitions.h" #include -#if !defined(_WIN32) -#include -#endif class LivingEntity; class LightningBolt; @@ -431,7 +428,8 @@ private: static int extraWanderIds[EXTRA_WANDER_MAX]; static int extraWanderCount; static int extraWanderTicks; - static TlsKey tlsIdx; + + static thread_local bool m_threadUseSmallIds; public: static void tickExtraWandering(); static void countFlagsForPIX(); diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index a4b36f98e..75c0a6c6d 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -41,38 +41,6 @@ #include "../../Minecraft.Client/MinecraftServer.h" #include -namespace { -#if defined(_WIN32) -inline void* LevelTlsGetValue(Level::TlsKey key) { return TlsGetValue(key); } - -inline void LevelTlsSetValue(Level::TlsKey key, void* value) { - TlsSetValue(key, value); -} -#else -pthread_key_t CreateLevelTlsKey() { - pthread_key_t key; - pthread_key_create(&key, NULL); - return key; -} - -inline void* LevelTlsGetValue(pthread_key_t key) { - return pthread_getspecific(key); -} - -inline void LevelTlsSetValue(pthread_key_t key, void* value) { - pthread_setspecific(key, value); -} -#endif -} // namespace - -#if defined(_WIN32) -Level::TlsKey Level::tlsIdx = TlsAlloc(); -Level::TlsKey Level::tlsIdxLightCache = TlsAlloc(); -#else -Level::TlsKey Level::tlsIdx = CreateLevelTlsKey(); -Level::TlsKey Level::tlsIdxLightCache = CreateLevelTlsKey(); -#endif - // 4J : WESTY : Added for time played stats. #include "../Headers/net.minecraft.stats.h" @@ -122,20 +90,20 @@ Level::TlsKey Level::tlsIdxLightCache = CreateLevelTlsKey(); // W - lighting value requires write #endif +thread_local bool Level::m_threadInstaTick = false; +thread_local Level::lightCache_t* Level::m_threadLightCache = nullptr; + void Level::enableLightingCache() { // Allocate 16K (needs 32K for large worlds) for a 16x16x16x4 byte cache of // results, plus 128K required for toCheck array. Rounding up to 256 to keep // as multiple of alignement - aligning to 128K boundary for possible cache // locking. - void* cache = (unsigned char*)XPhysicalAlloc( + m_threadLightCache = (lightCache_t*)XPhysicalAlloc( 256 * 1024, MAXULONG_PTR, 128 * 1024, PAGE_READWRITE | MEM_LARGE_PAGES); - LevelTlsSetValue(tlsIdxLightCache, cache); } void Level::destroyLightingCache() { - lightCache_t* cache = - static_cast(LevelTlsGetValue(tlsIdxLightCache)); - XPhysicalFree(cache); + delete m_threadLightCache; } inline int GetIndex(int x, int y, int z) { @@ -524,13 +492,11 @@ void Level::flushCache(lightCache_t* cache, uint64_t cacheUse, // 4J - added following 2 functions to move instaBuild flag from being a class // member, to TLS bool Level::getInstaTick() { - return reinterpret_cast(LevelTlsGetValue(tlsIdx)) != 0; + return m_threadInstaTick; } void Level::setInstaTick(bool enable) { - void* value = 0; - if (enable) value = (void*)1; - LevelTlsSetValue(tlsIdx, value); + m_threadInstaTick = enable; } // 4J - added @@ -3177,8 +3143,7 @@ int Level::getExpectedLight(lightCache_t* cache, int x, int y, int z, // this thread void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc, bool force, bool rootOnlyEmissive) { - lightCache_t* cache = - static_cast(LevelTlsGetValue(tlsIdxLightCache)); + lightCache_t* cache = m_threadLightCache; uint64_t cacheUse = 0; if (force) { diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index 2819d09f2..63c61b88e 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -54,10 +54,10 @@ class GameRules; class Level : public LevelSource { public: -#if defined(_WIN32) - using TlsKey = std::uint32_t; +#ifdef _LARGE_WORLDS + using lightCache_t = uint64_t; #else - using TlsKey = pthread_key_t; + using lightCache_t = unsigned int; #endif static const int MAX_TICK_TILES_PER_TICK = 1000; @@ -93,8 +93,8 @@ public: // 4J - added, making instaTick flag use TLS so we can set it in the chunk // rebuilding thread without upsetting the main game thread - static TlsKey tlsIdx; - static TlsKey tlsIdxLightCache; + static thread_local bool m_threadInstaTick; + static thread_local lightCache_t* m_threadLightCache; static void enableLightingCache(); static void destroyLightingCache(); static bool getCacheTestEnabled(); @@ -277,11 +277,6 @@ public: void setBrightnessNoUpdateOnClient(LightLayer::variety layer, int x, int y, int z, int brightness); // 4J added -#ifdef _LARGE_WORLDS - typedef uint64_t lightCache_t; -#else - typedef unsigned int lightCache_t; -#endif inline void setBrightnessCached(lightCache_t* cache, uint64_t* cacheUse, LightLayer::variety layer, int x, int y, int z, int brightness); diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.cpp b/Minecraft.World/Level/Storage/OldChunkStorage.cpp index ea8539b85..f13ad45a5 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/OldChunkStorage.cpp @@ -8,40 +8,11 @@ #include "../../Headers/net.minecraft.world.level.storage.h" #include "../../IO/Files/FileHeader.h" #include "OldChunkStorage.h" -#if defined(_WIN32) -namespace { -inline void* OldChunkStorageTlsGetValue(OldChunkStorage::TlsKey key) { - return TlsGetValue(key); -} -inline void OldChunkStorageTlsSetValue(OldChunkStorage::TlsKey key, - void* value) { - TlsSetValue(key, value); -} -} // namespace - -OldChunkStorage::TlsKey OldChunkStorage::tlsIdx = TlsAlloc(); -#else -namespace { -pthread_key_t CreateOldChunkStorageTlsKey() { - pthread_key_t key; - const int result = pthread_key_create(&key, nullptr); - assert(result == 0); - return key; -} - -inline void* OldChunkStorageTlsGetValue(pthread_key_t key) { - return pthread_getspecific(key); -} - -inline void OldChunkStorageTlsSetValue(pthread_key_t key, void* value) { - pthread_setspecific(key, value); -} -} // namespace - -OldChunkStorage::TlsKey OldChunkStorage::tlsIdx = CreateOldChunkStorageTlsKey(); -#endif -OldChunkStorage::ThreadStorage* OldChunkStorage::tlsDefault = NULL; +thread_local OldChunkStorage::ThreadStorage* OldChunkStorage::m_threadStorage = + nullptr; +OldChunkStorage::ThreadStorage* OldChunkStorage::m_defaultThreadStorage = + nullptr; OldChunkStorage::ThreadStorage::ThreadStorage() { blockData = byteArray(Level::CHUNK_TILE_COUNT); @@ -59,22 +30,22 @@ OldChunkStorage::ThreadStorage::~ThreadStorage() { void OldChunkStorage::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsDefault = tls; + + if (m_defaultThreadStorage == nullptr) { + m_defaultThreadStorage = tls; } - OldChunkStorageTlsSetValue(tlsIdx, tls); + + m_threadStorage = tls; } void OldChunkStorage::UseDefaultThreadStorage() { - OldChunkStorageTlsSetValue(tlsIdx, tlsDefault); + m_threadStorage = m_defaultThreadStorage; } void OldChunkStorage::ReleaseThreadStorage() { - ThreadStorage* tls = - static_cast(OldChunkStorageTlsGetValue(tlsIdx)); - if (tls == tlsDefault) return; - - delete tls; + if (m_threadStorage != m_defaultThreadStorage) { + delete m_threadStorage; + } } OldChunkStorage::OldChunkStorage(File dir, bool create) { @@ -348,8 +319,7 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level, CompoundTag* tag) { // 4J Stu - As we now save on multiple threads, the static data has been // moved to TLS - ThreadStorage* tls = - static_cast(OldChunkStorageTlsGetValue(tlsIdx)); + ThreadStorage* tls = m_threadStorage; PIXBeginNamedEvent(0, "Getting block data"); // static byteArray blockData = byteArray(32768); diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.h b/Minecraft.World/Level/Storage/OldChunkStorage.h index eb1a3cb7f..16e77ef2e 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.h +++ b/Minecraft.World/Level/Storage/OldChunkStorage.h @@ -31,8 +31,8 @@ private: ThreadStorage(); ~ThreadStorage(); }; - static TlsKey tlsIdx; - static ThreadStorage* tlsDefault; + static thread_local ThreadStorage* m_threadStorage; + static ThreadStorage* m_defaultThreadStorage; public: // Each new thread that needs to use Compression will need to call one of diff --git a/Minecraft.World/Recipes/FireworksRecipe.cpp b/Minecraft.World/Recipes/FireworksRecipe.cpp index 21a4d8a8a..e7db4cc52 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.cpp +++ b/Minecraft.World/Recipes/FireworksRecipe.cpp @@ -216,16 +216,14 @@ bool FireworksRecipe::matches(std::shared_ptr craftSlots, std::shared_ptr FireworksRecipe::assemble( std::shared_ptr craftSlots) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - return tls->resultItem->copy(); + return m_threadStorage->resultItem->copy(); // return resultItem->copy(); } int FireworksRecipe::size() { return 10; } const ItemInstance* FireworksRecipe::getResultItem() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - return tls->resultItem.get(); + return m_threadStorage->resultItem.get(); // return resultItem.get(); } From 4a1fb94600eee7f787db3f4c098376bb4c906728 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:20:08 -0500 Subject: [PATCH 04/12] refactor: convert Tile::tlsIdxShape to thread_local --- Minecraft.World/Blocks/ButtonTile.cpp | 3 +- Minecraft.World/Blocks/LiquidTile.cpp | 6 +- Minecraft.World/Blocks/PistonBaseTile.cpp | 2 +- .../Blocks/PistonMovingTileEntity.cpp | 2 +- Minecraft.World/Blocks/StemTile.cpp | 2 +- Minecraft.World/Blocks/Tile.cpp | 85 +++++-------------- Minecraft.World/Blocks/Tile.h | 2 +- Minecraft.World/Blocks/TopSnowTile.cpp | 2 +- Minecraft.World/Blocks/TripWireTile.cpp | 2 +- Minecraft.World/Blocks/WaterLilyTile.cpp | 2 +- Minecraft.World/Blocks/WoolCarpetTile.cpp | 2 +- 11 files changed, 30 insertions(+), 80 deletions(-) diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index fc2532ddb..a5ca9f809 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -260,8 +260,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { bool shouldBePressed; updateShape(data); - Tile::ThreadStorage* tls = - (Tile::ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + Tile::ThreadStorage* tls = m_threadShape; std::vector >* entities = level->getEntitiesOfClass( typeid(Arrow), AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index 214c8f62a..81c2cd9d4 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -13,8 +13,7 @@ const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water"; const std::wstring LiquidTile::TEXTURE_WATER_FLOW = L"water_flow"; const std::wstring LiquidTile::TEXTURE_LAVA_FLOW = L"lava_flow"; -LiquidTile::LiquidTile(int id, Material* material) - : Tile(id, material, false) { +LiquidTile::LiquidTile(int id, Material* material) : Tile(id, material, false) { float yo = 0; float e = 0; @@ -267,8 +266,7 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, if (level->getMaterial(x, y + 1, z) == Material::air && !level->isSolidRenderTile(x, y + 1, z)) { if (random->nextInt(100) == 0) { - ThreadStorage* tls = - (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; double xx = x + random->nextFloat(); double yy = y + tls->yy1; double zz = z + random->nextFloat(); diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 97b906927..d75a157ad 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -103,7 +103,7 @@ Icon* PistonBaseTile::getTexture(int face, int data) { // when the piston is extended, either normally // or because a piston arm animation, the top // texture is the furnace bottom - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 || tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1) { return iconInside; diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp index bc21314b8..bf3eaf77e 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp @@ -126,7 +126,7 @@ void PistonMovingPiece::updateShape( progress = 1.0f - progress; } int facing = entity->getFacing(); - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; tls->xx0 = tile->getShapeX0() - Facing::STEP_X[facing] * progress; tls->yy0 = tile->getShapeY0() - Facing::STEP_Y[facing] * progress; tls->zz0 = tile->getShapeZ0() - Facing::STEP_Z[facing] * progress; diff --git a/Minecraft.World/Blocks/StemTile.cpp b/Minecraft.World/Blocks/StemTile.cpp index 63321e872..be9a3d7dc 100644 --- a/Minecraft.World/Blocks/StemTile.cpp +++ b/Minecraft.World/Blocks/StemTile.cpp @@ -145,7 +145,7 @@ void StemTile::updateShape( std::shared_ptr forceEntity) // 4J added forceData, forceEntity param { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; tls->yy1 = (level->getData(x, y, z) * 2 + 2) / 16.0f; float ss = 0.125f; setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, (float)tls->yy1, 0.5f + ss); diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index a6f599fa7..f891f0499 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -17,31 +17,6 @@ #include "../Headers/net.minecraft.h" #include "Tile.h" -namespace { -#if defined(_WIN32) -inline void* TileTlsGetValue(Tile::TlsKey key) { return TlsGetValue(key); } - -inline void TileTlsSetValue(Tile::TlsKey key, void* value) { - TlsSetValue(key, value); -} -#else -pthread_key_t CreateTileTlsKey() { - pthread_key_t key; - const int result = pthread_key_create(&key, nullptr); - assert(result == 0); - return key; -} - -inline void* TileTlsGetValue(pthread_key_t key) { - return pthread_getspecific(key); -} - -inline void TileTlsSetValue(pthread_key_t key, void* value) { - pthread_setspecific(key, value); -} -#endif -} // namespace - std::wstring Tile::TILE_DESCRIPTION_PREFIX = L"Tile."; const float Tile::INDESTRUCTIBLE_DESTROY_TIME = -1.0f; @@ -247,11 +222,7 @@ Tile* Tile::woolCarpet = NULL; Tile* Tile::clayHardened = NULL; Tile* Tile::coalBlock = NULL; -#if defined(_WIN32) -Tile::TlsKey Tile::tlsIdxShape = TlsAlloc(); -#else -Tile::TlsKey Tile::tlsIdxShape = CreateTileTlsKey(); -#endif +thread_local Tile::ThreadStorage* Tile::m_threadShape = nullptr; Tile::ThreadStorage::ThreadStorage() { xx0 = yy0 = zz0 = xx1 = yy1 = zz1 = 0.0; @@ -259,14 +230,11 @@ Tile::ThreadStorage::ThreadStorage() { } void Tile::CreateNewThreadStorage() { - ThreadStorage* tls = new ThreadStorage(); - TileTlsSetValue(Tile::tlsIdxShape, tls); + m_threadShape = new ThreadStorage(); } void Tile::ReleaseThreadStorage() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); - delete tls; + delete m_threadShape; } void Tile::staticCtor() { @@ -1900,8 +1868,7 @@ Tile* Tile::disableMipmap() { void Tile::setShape(float x0, float y0, float z0, float x1, float y1, float z1) { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; tls->xx0 = x0; tls->yy0 = y0; tls->zz0 = z0; @@ -1952,7 +1919,7 @@ bool Tile::isFaceVisible(Level* level, int x, int y, int z, int f) { bool Tile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); if (face == 0 && tls->yy0 > 0) return true; @@ -1969,8 +1936,7 @@ bool Tile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { int Tile::getFaceFlags(LevelSource* level, int x, int y, int z) { int faceFlags = 0; - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); @@ -2043,8 +2009,7 @@ Icon* Tile::getTexture(int face, int data) { return icon; } Icon* Tile::getTexture(int face) { return getTexture(face, 0); } AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, @@ -2058,8 +2023,7 @@ void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, } AABB* Tile::getAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, @@ -2164,8 +2128,7 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { a = a->add(-xt, -yt, -zt); b = b->add(-xt, -yt, -zt); - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; Vec3* xh0 = a->clipX(b, tls->xx0); Vec3* xh1 = a->clipX(b, tls->xx1); @@ -2213,8 +2176,7 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { bool Tile::containsX(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->y >= tls->yy0 && v->y <= tls->yy1 && v->z >= tls->zz0 && @@ -2224,8 +2186,7 @@ bool Tile::containsX(Vec3* v) { bool Tile::containsY(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->x >= tls->xx0 && v->x <= tls->xx1 && v->z >= tls->zz0 && @@ -2235,8 +2196,7 @@ bool Tile::containsY(Vec3* v) { bool Tile::containsZ(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->x >= tls->xx0 && v->x <= tls->xx1 && v->y >= tls->yy0 && @@ -2300,55 +2260,48 @@ void Tile::updateShape( std::shared_ptr forceEntity) // 4J added forceData, forceEntity param { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); } double Tile::getShapeX0() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->xx0; } double Tile::getShapeX1() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->xx1; } double Tile::getShapeY0() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->yy0; } double Tile::getShapeY1() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->yy1; } double Tile::getShapeZ0() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->zz0; } double Tile::getShapeZ1() { - ThreadStorage* tls = - static_cast(TileTlsGetValue(Tile::tlsIdxShape)); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->zz1; diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index 3f347285d..b76e54975 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -66,7 +66,7 @@ protected: int tileId; ThreadStorage(); }; - static TlsKey tlsIdxShape; + static thread_local ThreadStorage* m_threadShape; public: // Each new thread that needs to use Vec3 pools will need to call one of the // following 2 functions, to either create its own local storage, or share diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index 198741cc1..1edb5c7f8 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -25,7 +25,7 @@ void TopSnowTile::registerIcons(IconRegister* iconRegister) { AABB* TopSnowTile::getAABB(Level* level, int x, int y, int z) { int height = level->getData(x, y, z) & HEIGHT_MASK; float offset = 2.0f / SharedConstants::WORLD_RESOLUTION; - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + (height * offset), z + tls->zz1); } diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index d33c3ea72..4d3fecbfb 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -132,7 +132,7 @@ void TripWireTile::checkPressed(Level* level, int x, int y, int z) { bool wasPressed = (data & MASK_POWERED) == MASK_POWERED; bool shouldBePressed = false; - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; std::vector >* entities = level->getEntities( nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); diff --git a/Minecraft.World/Blocks/WaterLilyTile.cpp b/Minecraft.World/Blocks/WaterLilyTile.cpp index 6ba33ba73..eb46acc94 100644 --- a/Minecraft.World/Blocks/WaterLilyTile.cpp +++ b/Minecraft.World/Blocks/WaterLilyTile.cpp @@ -24,7 +24,7 @@ void WaterlilyTile::addAABBs(Level* level, int x, int y, int z, AABB* box, } AABB* WaterlilyTile::getAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, diff --git a/Minecraft.World/Blocks/WoolCarpetTile.cpp b/Minecraft.World/Blocks/WoolCarpetTile.cpp index 0b1ead42c..7d8be8211 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.cpp +++ b/Minecraft.World/Blocks/WoolCarpetTile.cpp @@ -18,7 +18,7 @@ Icon* WoolCarpetTile::getTexture(int face, int data) { AABB* WoolCarpetTile::getAABB(Level* level, int x, int y, int z) { int height = 0; float offset = 1.0f / SharedConstants::WORLD_RESOLUTION; - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + ThreadStorage* tls = m_threadShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, From 9ff2fb4fef0b0b3bb4317e1a88730f718baf3e2a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:41:08 -0500 Subject: [PATCH 05/12] refactor: switch to thread_local in Chunk, PistonBaseTile, TheEndPortalTile, Compression --- Minecraft.Client/Rendering/Chunk.cpp | 13 +++----- Minecraft.Client/Rendering/Chunk.h | 4 +-- Minecraft.World/Blocks/PistonBaseTile.cpp | 37 ++------------------- Minecraft.World/Blocks/PistonBaseTile.h | 2 ++ Minecraft.World/Blocks/TheEndPortalTile.cpp | 37 ++------------------- Minecraft.World/Blocks/TheEndPortalTile.h | 13 ++------ Minecraft.World/IO/Streams/Compression.cpp | 22 +++++------- Minecraft.World/IO/Streams/Compression.h | 4 +-- 8 files changed, 29 insertions(+), 103 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index ccc786872..05a2b2d55 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -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 diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index 23d5ef532..7ba3c55fa 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -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: diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index d75a157ad..686c759c9 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -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(static_cast(set ? 1 : 0))); + m_threadIgnoreUpdate = set; } PistonBaseTile::PistonBaseTile(int id, bool isSticky) diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index eb038e6ae..d31527624 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -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(); diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index a2fa0a5ad..a8181c39b 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -9,47 +9,16 @@ #include "../Headers/net.minecraft.world.h" #include -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(static_cast(set ? 1 : 0))); + m_threadAllowAnywhere = set; } TheEndPortal::TheEndPortal(int id, Material* material) diff --git a/Minecraft.World/Blocks/TheEndPortalTile.h b/Minecraft.World/Blocks/TheEndPortalTile.h index 6e3531777..3e6e224be 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.h +++ b/Minecraft.World/Blocks/TheEndPortalTile.h @@ -3,20 +3,10 @@ #include "BaseEntityTile.h" #include -#if !defined(_WIN32) -#include -#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; }; \ No newline at end of file diff --git a/Minecraft.World/IO/Streams/Compression.cpp b/Minecraft.World/IO/Streams/Compression.cpp index 543f05296..edc2f068a 100644 --- a/Minecraft.World/IO/Streams/Compression.cpp +++ b/Minecraft.World/IO/Streams/Compression.cpp @@ -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, diff --git a/Minecraft.World/IO/Streams/Compression.h b/Minecraft.World/IO/Streams/Compression.h index 1b2529231..a8410a671 100644 --- a/Minecraft.World/IO/Streams/Compression.h +++ b/Minecraft.World/IO/Streams/Compression.h @@ -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 From 30170b8f9cca1453c4dfa819df8296064fcafbee Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:46:16 -0500 Subject: [PATCH 06/12] adjust naming scheme of private TLS members --- Minecraft.Client/Rendering/Chunk.cpp | 8 ++-- Minecraft.Client/Rendering/Chunk.h | 2 +- Minecraft.Client/Rendering/Tesselator.cpp | 6 +-- Minecraft.Client/Rendering/Tesselator.h | 2 +- Minecraft.World/Blocks/ButtonTile.cpp | 2 +- Minecraft.World/Blocks/LiquidTile.cpp | 2 +- Minecraft.World/Blocks/PistonBaseTile.cpp | 8 ++-- Minecraft.World/Blocks/PistonBaseTile.h | 2 +- .../Blocks/PistonMovingTileEntity.cpp | 2 +- Minecraft.World/Blocks/StemTile.cpp | 2 +- Minecraft.World/Blocks/TheEndPortalTile.cpp | 6 +-- Minecraft.World/Blocks/TheEndPortalTile.h | 2 +- Minecraft.World/Blocks/Tile.cpp | 38 +++++++++---------- Minecraft.World/Blocks/Tile.h | 2 +- Minecraft.World/Blocks/TopSnowTile.cpp | 2 +- Minecraft.World/Blocks/TripWireTile.cpp | 2 +- Minecraft.World/Blocks/WaterLilyTile.cpp | 2 +- Minecraft.World/Blocks/WoolCarpetTile.cpp | 2 +- Minecraft.World/Entities/Entity.cpp | 16 ++++---- Minecraft.World/Entities/Entity.h | 2 +- Minecraft.World/IO/Streams/Compression.cpp | 18 ++++----- Minecraft.World/IO/Streams/Compression.h | 2 +- Minecraft.World/Level/Level.cpp | 14 +++---- Minecraft.World/Level/Level.h | 4 +- .../Level/Storage/OldChunkStorage.cpp | 12 +++--- .../Level/Storage/OldChunkStorage.h | 2 +- Minecraft.World/Recipes/FireworksRecipe.cpp | 16 ++++---- Minecraft.World/Recipes/FireworksRecipe.h | 2 +- 28 files changed, 90 insertions(+), 90 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 05a2b2d55..f3074f407 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -20,18 +20,18 @@ int Chunk::updates = 0; #ifdef _LARGE_WORLDS -thread_local uint8_t* Chunk::m_threadTileIds = nullptr; +thread_local uint8_t* Chunk::m_tlsTileIds = nullptr; void Chunk::CreateNewThreadStorage() { - m_threadTileIds = new unsigned char[16 * 16 * Level::maxBuildHeight]; + m_tlsTileIds = new unsigned char[16 * 16 * Level::maxBuildHeight]; } void Chunk::ReleaseThreadStorage() { - delete m_threadTileIds; + delete m_tlsTileIds; } uint8_t* Chunk::GetTileIdsStorage() { - return m_threadTileIds; + return m_tlsTileIds; } #else // 4J Stu - Don't want this when multi-threaded diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index 7ba3c55fa..379b258ba 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -30,7 +30,7 @@ private: #ifndef _LARGE_WORLDS static Tesselator* t; #else - static thread_local uint8_t* m_threadTileIds; + static thread_local uint8_t* m_tlsTileIds; public: static void CreateNewThreadStorage(); diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 661eb121b..6135d75dc 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -24,14 +24,14 @@ int normal; */ -thread_local Tesselator* Tesselator::m_threadInstance = nullptr; +thread_local Tesselator* Tesselator::m_tlsInstance = nullptr; Tesselator* Tesselator::getInstance() { - return m_threadInstance; + return m_tlsInstance; } void Tesselator::CreateNewThreadStorage(int bytes) { - Tesselator::m_threadInstance = new Tesselator(bytes / 4); + Tesselator::m_tlsInstance = new Tesselator(bytes / 4); } // she tessalate my vertices till i render diff --git a/Minecraft.Client/Rendering/Tesselator.h b/Minecraft.Client/Rendering/Tesselator.h index ac3103b7d..8738c165a 100644 --- a/Minecraft.Client/Rendering/Tesselator.h +++ b/Minecraft.Client/Rendering/Tesselator.h @@ -41,7 +41,7 @@ public: static void CreateNewThreadStorage(int bytes); private: - static thread_local Tesselator* m_threadInstance; + static thread_local Tesselator* m_tlsInstance; public: static Tesselator* getInstance(); diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index a5ca9f809..73ac3122a 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -260,7 +260,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { bool shouldBePressed; updateShape(data); - Tile::ThreadStorage* tls = m_threadShape; + Tile::ThreadStorage* tls = m_tlsShape; std::vector >* entities = level->getEntitiesOfClass( typeid(Arrow), AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index 81c2cd9d4..e307e2125 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -266,7 +266,7 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, if (level->getMaterial(x, y + 1, z) == Material::air && !level->isSolidRenderTile(x, y + 1, z)) { if (random->nextInt(100) == 0) { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; double xx = x + random->nextFloat(); double yy = y + tls->yy1; double zz = z + random->nextFloat(); diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 686c759c9..489a4cbd2 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -20,7 +20,7 @@ const std::wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top"; const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f; -thread_local bool PistonBaseTile::m_threadIgnoreUpdate = false; +thread_local bool PistonBaseTile::m_tlsIgnoreUpdate = 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 @@ -32,11 +32,11 @@ thread_local bool PistonBaseTile::m_threadIgnoreUpdate = false; // 4J - ignoreUpdate is a static in java, implementing as TLS here to make // thread safe bool PistonBaseTile::ignoreUpdate() { - return m_threadIgnoreUpdate; + return m_tlsIgnoreUpdate; } void PistonBaseTile::ignoreUpdate(bool set) { - m_threadIgnoreUpdate = set; + m_tlsIgnoreUpdate = set; } PistonBaseTile::PistonBaseTile(int id, bool isSticky) @@ -72,7 +72,7 @@ Icon* PistonBaseTile::getTexture(int face, int data) { // when the piston is extended, either normally // or because a piston arm animation, the top // texture is the furnace bottom - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 || tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1) { return iconInside; diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index d31527624..cf7dab357 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -35,7 +35,7 @@ private: Icon* iconBack; Icon* iconPlatform; - static thread_local bool m_threadIgnoreUpdate; + static thread_local bool m_tlsIgnoreUpdate; static TlsKey tlsIdx; // 4J - was just a static but implemented with TLS for our version diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp index bf3eaf77e..b12d0dd7d 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp @@ -126,7 +126,7 @@ void PistonMovingPiece::updateShape( progress = 1.0f - progress; } int facing = entity->getFacing(); - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; tls->xx0 = tile->getShapeX0() - Facing::STEP_X[facing] * progress; tls->yy0 = tile->getShapeY0() - Facing::STEP_Y[facing] * progress; tls->zz0 = tile->getShapeZ0() - Facing::STEP_Z[facing] * progress; diff --git a/Minecraft.World/Blocks/StemTile.cpp b/Minecraft.World/Blocks/StemTile.cpp index be9a3d7dc..890a34be5 100644 --- a/Minecraft.World/Blocks/StemTile.cpp +++ b/Minecraft.World/Blocks/StemTile.cpp @@ -145,7 +145,7 @@ void StemTile::updateShape( std::shared_ptr forceEntity) // 4J added forceData, forceEntity param { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; tls->yy1 = (level->getData(x, y, z) * 2 + 2) / 16.0f; float ss = 0.125f; setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, (float)tls->yy1, 0.5f + ss); diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index a8181c39b..0bca60a44 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -9,16 +9,16 @@ #include "../Headers/net.minecraft.world.h" #include -thread_local bool TheEndPortal::m_threadAllowAnywhere = false; +thread_local bool TheEndPortal::m_tlsAllowAnywhere = false; // 4J - allowAnywhere is a static in java, implementing as TLS here to make // thread safe bool TheEndPortal::allowAnywhere() { - return m_threadAllowAnywhere; + return m_tlsAllowAnywhere; } void TheEndPortal::allowAnywhere(bool set) { - m_threadAllowAnywhere = set; + m_tlsAllowAnywhere = set; } TheEndPortal::TheEndPortal(int id, Material* material) diff --git a/Minecraft.World/Blocks/TheEndPortalTile.h b/Minecraft.World/Blocks/TheEndPortalTile.h index 3e6e224be..2cd4e99e7 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.h +++ b/Minecraft.World/Blocks/TheEndPortalTile.h @@ -35,5 +35,5 @@ public: void registerIcons(IconRegister* iconRegister); private: - static thread_local bool m_threadAllowAnywhere; + static thread_local bool m_tlsAllowAnywhere; }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index f891f0499..9b1693afd 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -222,7 +222,7 @@ Tile* Tile::woolCarpet = NULL; Tile* Tile::clayHardened = NULL; Tile* Tile::coalBlock = NULL; -thread_local Tile::ThreadStorage* Tile::m_threadShape = nullptr; +thread_local Tile::ThreadStorage* Tile::m_tlsShape = nullptr; Tile::ThreadStorage::ThreadStorage() { xx0 = yy0 = zz0 = xx1 = yy1 = zz1 = 0.0; @@ -230,11 +230,11 @@ Tile::ThreadStorage::ThreadStorage() { } void Tile::CreateNewThreadStorage() { - m_threadShape = new ThreadStorage(); + m_tlsShape = new ThreadStorage(); } void Tile::ReleaseThreadStorage() { - delete m_threadShape; + delete m_tlsShape; } void Tile::staticCtor() { @@ -1868,7 +1868,7 @@ Tile* Tile::disableMipmap() { void Tile::setShape(float x0, float y0, float z0, float x1, float y1, float z1) { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; tls->xx0 = x0; tls->yy0 = y0; tls->zz0 = z0; @@ -1919,7 +1919,7 @@ bool Tile::isFaceVisible(Level* level, int x, int y, int z, int f) { bool Tile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { ThreadStorage* tls = - m_threadShape; + m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); if (face == 0 && tls->yy0 > 0) return true; @@ -1936,7 +1936,7 @@ bool Tile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { int Tile::getFaceFlags(LevelSource* level, int x, int y, int z) { int faceFlags = 0; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); @@ -2009,7 +2009,7 @@ Icon* Tile::getTexture(int face, int data) { return icon; } Icon* Tile::getTexture(int face) { return getTexture(face, 0); } AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, @@ -2023,7 +2023,7 @@ void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, } AABB* Tile::getAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, @@ -2128,7 +2128,7 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { a = a->add(-xt, -yt, -zt); b = b->add(-xt, -yt, -zt); - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; Vec3* xh0 = a->clipX(b, tls->xx0); Vec3* xh1 = a->clipX(b, tls->xx1); @@ -2176,7 +2176,7 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { bool Tile::containsX(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->y >= tls->yy0 && v->y <= tls->yy1 && v->z >= tls->zz0 && @@ -2186,7 +2186,7 @@ bool Tile::containsX(Vec3* v) { bool Tile::containsY(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->x >= tls->xx0 && v->x <= tls->xx1 && v->z >= tls->zz0 && @@ -2196,7 +2196,7 @@ bool Tile::containsY(Vec3* v) { bool Tile::containsZ(Vec3* v) { if (v == NULL) return false; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return v->x >= tls->xx0 && v->x <= tls->xx1 && v->y >= tls->yy0 && @@ -2260,48 +2260,48 @@ void Tile::updateShape( std::shared_ptr forceEntity) // 4J added forceData, forceEntity param { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); } double Tile::getShapeX0() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->xx0; } double Tile::getShapeX1() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->xx1; } double Tile::getShapeY0() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->yy0; } double Tile::getShapeY1() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->yy1; } double Tile::getShapeZ0() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->zz0; } double Tile::getShapeZ1() { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return tls->zz1; diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index b76e54975..941da7ec0 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -66,7 +66,7 @@ protected: int tileId; ThreadStorage(); }; - static thread_local ThreadStorage* m_threadShape; + static thread_local ThreadStorage* m_tlsShape; public: // Each new thread that needs to use Vec3 pools will need to call one of the // following 2 functions, to either create its own local storage, or share diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index 1edb5c7f8..64401de87 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -25,7 +25,7 @@ void TopSnowTile::registerIcons(IconRegister* iconRegister) { AABB* TopSnowTile::getAABB(Level* level, int x, int y, int z) { int height = level->getData(x, y, z) & HEIGHT_MASK; float offset = 2.0f / SharedConstants::WORLD_RESOLUTION; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + (height * offset), z + tls->zz1); } diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 4d3fecbfb..217116c81 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -132,7 +132,7 @@ void TripWireTile::checkPressed(Level* level, int x, int y, int z) { bool wasPressed = (data & MASK_POWERED) == MASK_POWERED; bool shouldBePressed = false; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; std::vector >* entities = level->getEntities( nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); diff --git a/Minecraft.World/Blocks/WaterLilyTile.cpp b/Minecraft.World/Blocks/WaterLilyTile.cpp index eb46acc94..3ea6660a4 100644 --- a/Minecraft.World/Blocks/WaterLilyTile.cpp +++ b/Minecraft.World/Blocks/WaterLilyTile.cpp @@ -24,7 +24,7 @@ void WaterlilyTile::addAABBs(Level* level, int x, int y, int z, AABB* box, } AABB* WaterlilyTile::getAABB(Level* level, int x, int y, int z) { - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, diff --git a/Minecraft.World/Blocks/WoolCarpetTile.cpp b/Minecraft.World/Blocks/WoolCarpetTile.cpp index 7d8be8211..2800a94c0 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.cpp +++ b/Minecraft.World/Blocks/WoolCarpetTile.cpp @@ -18,7 +18,7 @@ Icon* WoolCarpetTile::getTexture(int face, int data) { AABB* WoolCarpetTile::getAABB(Level* level, int x, int y, int z) { int height = 0; float offset = 1.0f / SharedConstants::WORLD_RESOLUTION; - ThreadStorage* tls = m_threadShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 872e0c23c..1c4170040 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -26,7 +26,7 @@ #include "../../Minecraft.Client/Level/ServerLevel.h" #include "../../Minecraft.Client/Network/PlayerList.h" -thread_local bool Entity::m_threadUseSmallIds = false; +thread_local bool Entity::m_tlsUseSmallIds = false; const std::wstring Entity::RIDING_TAG = L"Riding"; int Entity::entityCounter = @@ -54,7 +54,7 @@ int Entity::getSmallId() { // telling the client that the entity has been removed After we have already // re-used its Id and created a new entity. This ends up with newly created // client-side entities being removed by accident, causing invisible mobs. - if (m_threadUseSmallIds) { + if (m_tlsUseSmallIds) { MinecraftServer* server = MinecraftServer::getInstance(); if (server) { // In some attempt to optimise this, flagEntitiesToBeRemoved most of @@ -129,13 +129,13 @@ void Entity::countFlagsForPIX() { void Entity::resetSmallId() { freeSmallId(entityId); - if (m_threadUseSmallIds) { + if (m_tlsUseSmallIds) { entityId = getSmallId(); } } void Entity::freeSmallId(int index) { - if (!m_threadUseSmallIds) + if (!m_tlsUseSmallIds) return; // Don't do anything with small ids if this isn't the server // thread if (index >= 2048) return; // Don't do anything if this isn't a short id @@ -148,7 +148,7 @@ void Entity::freeSmallId(int index) { entityIdWanderFlags[i] &= uiMask; } -void Entity::useSmallIds() { m_threadUseSmallIds = true; } +void Entity::useSmallIds() { m_tlsUseSmallIds = true; } // Things also added here to be able to manage the concept of a number of extra // "wandering" entities - normally path finding entities aren't allowed to @@ -161,7 +161,7 @@ void Entity::useSmallIds() { m_threadUseSmallIds = true; } // Let the management system here know whether or not to consider this // particular entity for some extra wandering void Entity::considerForExtraWandering(bool enable) { - if (!m_threadUseSmallIds) + if (!m_tlsUseSmallIds) return; // Don't do anything with small ids if this isn't the server // thread if (entityId >= 2048) return; // Don't do anything if this isn't a short id @@ -180,7 +180,7 @@ void Entity::considerForExtraWandering(bool enable) { // Should this entity do wandering in addition to what the java code would have // done? bool Entity::isExtraWanderingEnabled() { - if (!m_threadUseSmallIds) + if (!m_tlsUseSmallIds) return false; // Don't do anything with small ids if this isn't the // server thread if (entityId >= 2048) @@ -247,7 +247,7 @@ void Entity::_init(bool useSmallId, Level* level) { // rest of the range is used for anything we don't need to track like this, // currently particles. We only ever want to allocate this type of id from // the server thread, so using thread local storage to isolate this. - if (useSmallId && m_threadUseSmallIds) { + if (useSmallId && m_tlsUseSmallIds) { entityId = getSmallId(); } else { entityId = Entity::entityCounter++; diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index 9374fea4e..0a877b2f6 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -429,7 +429,7 @@ private: static int extraWanderCount; static int extraWanderTicks; - static thread_local bool m_threadUseSmallIds; + static thread_local bool m_tlsUseSmallIds; public: static void tickExtraWandering(); static void countFlagsForPIX(); diff --git a/Minecraft.World/IO/Streams/Compression.cpp b/Minecraft.World/IO/Streams/Compression.cpp index edc2f068a..9b5dcc8be 100644 --- a/Minecraft.World/IO/Streams/Compression.cpp +++ b/Minecraft.World/IO/Streams/Compression.cpp @@ -17,8 +17,8 @@ #include "../../../Minecraft.Client/Platform/PS3/PS3Extras/EdgeZLib.h" #endif //__PS3__ -thread_local Compression::ThreadStorage* Compression::m_threadCompression = nullptr; -Compression::ThreadStorage* Compression::m_threadCompressionDefault = nullptr; +thread_local Compression::ThreadStorage* Compression::m_tlsCompression = nullptr; +Compression::ThreadStorage* Compression::m_tlsCompressionDefault = nullptr; Compression::ThreadStorage::ThreadStorage() { compression = new Compression(); } @@ -26,24 +26,24 @@ Compression::ThreadStorage::~ThreadStorage() { delete compression; } void Compression::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (m_threadCompressionDefault == nullptr) { - m_threadCompressionDefault = tls; + if (m_tlsCompressionDefault == nullptr) { + m_tlsCompressionDefault = tls; } - m_threadCompression = tls; + m_tlsCompression = tls; } void Compression::UseDefaultThreadStorage() { - m_threadCompression = m_threadCompressionDefault; + m_tlsCompression = m_tlsCompressionDefault; } void Compression::ReleaseThreadStorage() { - if (m_threadCompression != m_threadCompressionDefault) { - delete m_threadCompression; + if (m_tlsCompression != m_tlsCompressionDefault) { + delete m_tlsCompression; } } Compression* Compression::getCompression() { - return m_threadCompression->compression; + return m_tlsCompression->compression; } HRESULT Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize, diff --git a/Minecraft.World/IO/Streams/Compression.h b/Minecraft.World/IO/Streams/Compression.h index a8410a671..0515f380b 100644 --- a/Minecraft.World/IO/Streams/Compression.h +++ b/Minecraft.World/IO/Streams/Compression.h @@ -25,7 +25,7 @@ private: ThreadStorage(); ~ThreadStorage(); }; - static thread_local ThreadStorage* m_threadCompression; + static thread_local ThreadStorage* m_tlsCompression; static ThreadStorage* m_threadCompressionDefault; public: diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index 75c0a6c6d..a87eee1af 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -90,20 +90,20 @@ // W - lighting value requires write #endif -thread_local bool Level::m_threadInstaTick = false; -thread_local Level::lightCache_t* Level::m_threadLightCache = nullptr; +thread_local bool Level::m_tlsInstaTick = false; +thread_local Level::lightCache_t* Level::m_tlsLightCache = nullptr; void Level::enableLightingCache() { // Allocate 16K (needs 32K for large worlds) for a 16x16x16x4 byte cache of // results, plus 128K required for toCheck array. Rounding up to 256 to keep // as multiple of alignement - aligning to 128K boundary for possible cache // locking. - m_threadLightCache = (lightCache_t*)XPhysicalAlloc( + m_tlsLightCache = (lightCache_t*)XPhysicalAlloc( 256 * 1024, MAXULONG_PTR, 128 * 1024, PAGE_READWRITE | MEM_LARGE_PAGES); } void Level::destroyLightingCache() { - delete m_threadLightCache; + delete m_tlsLightCache; } inline int GetIndex(int x, int y, int z) { @@ -492,11 +492,11 @@ void Level::flushCache(lightCache_t* cache, uint64_t cacheUse, // 4J - added following 2 functions to move instaBuild flag from being a class // member, to TLS bool Level::getInstaTick() { - return m_threadInstaTick; + return m_tlsInstaTick; } void Level::setInstaTick(bool enable) { - m_threadInstaTick = enable; + m_tlsInstaTick = enable; } // 4J - added @@ -3143,7 +3143,7 @@ int Level::getExpectedLight(lightCache_t* cache, int x, int y, int z, // this thread void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc, bool force, bool rootOnlyEmissive) { - lightCache_t* cache = m_threadLightCache; + lightCache_t* cache = m_tlsLightCache; uint64_t cacheUse = 0; if (force) { diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index 63c61b88e..fa820f3d4 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -93,8 +93,8 @@ public: // 4J - added, making instaTick flag use TLS so we can set it in the chunk // rebuilding thread without upsetting the main game thread - static thread_local bool m_threadInstaTick; - static thread_local lightCache_t* m_threadLightCache; + static thread_local bool m_tlsInstaTick; + static thread_local lightCache_t* m_tlsLightCache; static void enableLightingCache(); static void destroyLightingCache(); static bool getCacheTestEnabled(); diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.cpp b/Minecraft.World/Level/Storage/OldChunkStorage.cpp index f13ad45a5..02fddf092 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/OldChunkStorage.cpp @@ -9,7 +9,7 @@ #include "../../IO/Files/FileHeader.h" #include "OldChunkStorage.h" -thread_local OldChunkStorage::ThreadStorage* OldChunkStorage::m_threadStorage = +thread_local OldChunkStorage::ThreadStorage* OldChunkStorage::m_tlsStorage = nullptr; OldChunkStorage::ThreadStorage* OldChunkStorage::m_defaultThreadStorage = nullptr; @@ -35,16 +35,16 @@ void OldChunkStorage::CreateNewThreadStorage() { m_defaultThreadStorage = tls; } - m_threadStorage = tls; + m_tlsStorage = tls; } void OldChunkStorage::UseDefaultThreadStorage() { - m_threadStorage = m_defaultThreadStorage; + m_tlsStorage = m_defaultThreadStorage; } void OldChunkStorage::ReleaseThreadStorage() { - if (m_threadStorage != m_defaultThreadStorage) { - delete m_threadStorage; + if (m_tlsStorage != m_defaultThreadStorage) { + delete m_tlsStorage; } } @@ -319,7 +319,7 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level, CompoundTag* tag) { // 4J Stu - As we now save on multiple threads, the static data has been // moved to TLS - ThreadStorage* tls = m_threadStorage; + ThreadStorage* tls = m_tlsStorage; PIXBeginNamedEvent(0, "Getting block data"); // static byteArray blockData = byteArray(32768); diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.h b/Minecraft.World/Level/Storage/OldChunkStorage.h index 16e77ef2e..5a7ce83ff 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.h +++ b/Minecraft.World/Level/Storage/OldChunkStorage.h @@ -31,7 +31,7 @@ private: ThreadStorage(); ~ThreadStorage(); }; - static thread_local ThreadStorage* m_threadStorage; + static thread_local ThreadStorage* m_tlsStorage; static ThreadStorage* m_defaultThreadStorage; public: diff --git a/Minecraft.World/Recipes/FireworksRecipe.cpp b/Minecraft.World/Recipes/FireworksRecipe.cpp index e7db4cc52..e14c08c33 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.cpp +++ b/Minecraft.World/Recipes/FireworksRecipe.cpp @@ -2,7 +2,7 @@ #include "../Headers/net.minecraft.world.item.h" #include "FireworksRecipe.h" -thread_local FireworksRecipe::ThreadStorage* FireworksRecipe::m_threadStorage = +thread_local FireworksRecipe::ThreadStorage* FireworksRecipe::m_tlsStorage = nullptr; FireworksRecipe::ThreadStorage* FireworksRecipe::m_defaultThreadStorage = nullptr; @@ -16,21 +16,21 @@ void FireworksRecipe::CreateNewThreadStorage() { m_defaultThreadStorage = tls; } - m_threadStorage = tls; + m_tlsStorage = tls; } void FireworksRecipe::UseDefaultThreadStorage() { - m_threadStorage = m_defaultThreadStorage; + m_tlsStorage = m_defaultThreadStorage; } void FireworksRecipe::ReleaseThreadStorage() { - if (m_threadStorage != m_defaultThreadStorage) { - delete m_threadStorage; + if (m_tlsStorage != m_defaultThreadStorage) { + delete m_tlsStorage; } } void FireworksRecipe::setResultItem(std::shared_ptr item) { - m_threadStorage->resultItem = item; + m_tlsStorage->resultItem = item; } FireworksRecipe::FireworksRecipe() { @@ -216,14 +216,14 @@ bool FireworksRecipe::matches(std::shared_ptr craftSlots, std::shared_ptr FireworksRecipe::assemble( std::shared_ptr craftSlots) { - return m_threadStorage->resultItem->copy(); + return m_tlsStorage->resultItem->copy(); // return resultItem->copy(); } int FireworksRecipe::size() { return 10; } const ItemInstance* FireworksRecipe::getResultItem() { - return m_threadStorage->resultItem.get(); + return m_tlsStorage->resultItem.get(); // return resultItem.get(); } diff --git a/Minecraft.World/Recipes/FireworksRecipe.h b/Minecraft.World/Recipes/FireworksRecipe.h index 34998fd68..bb52b6842 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.h +++ b/Minecraft.World/Recipes/FireworksRecipe.h @@ -13,7 +13,7 @@ private: std::shared_ptr resultItem; ThreadStorage(); }; - static thread_local ThreadStorage* m_threadStorage; + static thread_local ThreadStorage* m_tlsStorage; static ThreadStorage* m_defaultThreadStorage; void setResultItem(std::shared_ptr item); From 28816876a1ab9ef8e211a759348cc0fe4327f3b5 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:52:37 -0500 Subject: [PATCH 07/12] chore: remove unneeded pthread includes --- Minecraft.World/Blocks/PistonBaseTile.h | 4 ---- Minecraft.World/Blocks/Tile.h | 3 --- Minecraft.World/Level/Level.h | 3 --- Minecraft.World/Level/Storage/OldChunkStorage.h | 3 --- 4 files changed, 13 deletions(-) diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index cf7dab357..48c420010 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -2,10 +2,6 @@ #include "Tile.h" #include -#if !defined(_WIN32) -#include -#endif - class PistonBaseTile : public Tile { public: #if defined(_WIN32) diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index 941da7ec0..925fd477c 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -4,9 +4,6 @@ #include "../Util/Definitions.h" #include "../Util/SoundTypes.h" #include -#if !defined(_WIN32) -#include -#endif class GrassTile; class LeafTile; diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index fa820f3d4..03370e96c 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -10,9 +10,6 @@ #include "../WorldGen/Biomes/Biome.h" #include "../Util/C4JThread.h" #include -#if !defined(_WIN32) -#include -#endif #ifdef __PSVITA__ #include "../../Minecraft.Client/Platform/PSVita/PSVitaExtras/CustomSet.h" diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.h b/Minecraft.World/Level/Storage/OldChunkStorage.h index 5a7ce83ff..0b40872bd 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.h +++ b/Minecraft.World/Level/Storage/OldChunkStorage.h @@ -5,9 +5,6 @@ #include "../../IO/NBT/CompoundTag.h" #include "../../Headers/com.mojang.nbt.h" #include -#if !defined(_WIN32) -#include -#endif class Level; From e5414bf871cc01650e838711f4aa52d4ac724b74 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:55:37 -0500 Subject: [PATCH 08/12] refactor: remove unneeded TlsKey typedefs --- Minecraft.World/Blocks/PistonBaseTile.h | 6 ------ Minecraft.World/Blocks/Tile.h | 6 ------ Minecraft.World/Entities/Entity.h | 6 ------ Minecraft.World/Level/Storage/OldChunkStorage.h | 7 ------- 4 files changed, 25 deletions(-) diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index 48c420010..9dd9e0e15 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -4,12 +4,6 @@ class PistonBaseTile : public Tile { public: -#if defined(_WIN32) - using TlsKey = std::uint32_t; -#else - using TlsKey = pthread_key_t; -#endif - static const int EXTENDED_BIT = 8; static const int UNDEFINED_FACING = 7; diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index 925fd477c..b46748ff5 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -50,12 +50,6 @@ class Tile { friend class WallTile; protected: -#if defined(_WIN32) - using TlsKey = std::uint32_t; -#else - using TlsKey = pthread_key_t; -#endif - // 4J added so we can have separate shapes for different threads class ThreadStorage { public: diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index 0a877b2f6..e7aede835 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -36,12 +36,6 @@ class Entity : public std::enable_shared_from_this { friend class Gui; // 4J Stu - Added to be able to access the shared flag // functions and constants, without making them publicly // available to everything -public: -#if defined(_WIN32) - using TlsKey = std::uint32_t; -#else - using TlsKey = pthread_key_t; -#endif // 4J-PB - added to replace (e instanceof Type), avoiding dynamic casts virtual eINSTANCEOF GetType() = 0; diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.h b/Minecraft.World/Level/Storage/OldChunkStorage.h index 0b40872bd..c451d6ffd 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.h +++ b/Minecraft.World/Level/Storage/OldChunkStorage.h @@ -9,13 +9,6 @@ class Level; class OldChunkStorage : public ChunkStorage { -public: -#if defined(_WIN32) - using TlsKey = std::uint32_t; -#else - using TlsKey = pthread_key_t; -#endif - private: // 4J added so we can have separate storage arrays for different threads class ThreadStorage { From 29c0185553b65b5976b47d1665f38999e119d36b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:56:08 -0500 Subject: [PATCH 09/12] fix: remove PistonBaseTile::tlsIdx --- Minecraft.World/Blocks/PistonBaseTile.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index 9dd9e0e15..272b44e81 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -27,7 +27,6 @@ private: static thread_local bool m_tlsIgnoreUpdate; - static TlsKey tlsIdx; // 4J - was just a static but implemented with TLS for our version static bool ignoreUpdate(); static void ignoreUpdate(bool set); From 22671562cad2be55ba264b7d22d540de6444b9c1 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:00:13 -0500 Subject: [PATCH 10/12] fix: add back `public` visibility specifier for `Entity` --- Minecraft.World/Entities/Entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index e7aede835..ea827e28f 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -36,7 +36,7 @@ class Entity : public std::enable_shared_from_this { friend class Gui; // 4J Stu - Added to be able to access the shared flag // functions and constants, without making them publicly // available to everything - +public: // 4J-PB - added to replace (e instanceof Type), avoiding dynamic casts virtual eINSTANCEOF GetType() = 0; From 73392fa06a6eae349abdc6f1560d05d4ca41d7a8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:02:26 -0500 Subject: [PATCH 11/12] fix: use correct name for default `Compression` thread storage --- Minecraft.World/IO/Streams/Compression.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.World/IO/Streams/Compression.h b/Minecraft.World/IO/Streams/Compression.h index 0515f380b..833925108 100644 --- a/Minecraft.World/IO/Streams/Compression.h +++ b/Minecraft.World/IO/Streams/Compression.h @@ -26,7 +26,7 @@ private: ~ThreadStorage(); }; static thread_local ThreadStorage* m_tlsCompression; - static ThreadStorage* m_threadCompressionDefault; + static ThreadStorage* m_tlsCompressionDefault; public: // Each new thread that needs to use Compression will need to call one of From aff677a995c73b292446a55529d3dbdf0b83f5ef Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:08:00 -0500 Subject: [PATCH 12/12] chore: fmt --- Minecraft.Client/Rendering/Chunk.cpp | 8 ++----- Minecraft.Client/Rendering/Tesselator.cpp | 24 ++++++++++----------- Minecraft.World/Blocks/PistonBaseTile.cpp | 8 ++----- Minecraft.World/Blocks/TheEndPortalTile.cpp | 8 ++----- Minecraft.World/Blocks/Tile.cpp | 14 +++++------- Minecraft.World/Blocks/TopSnowTile.cpp | 3 +-- Minecraft.World/Blocks/TripWireTile.cpp | 3 +-- Minecraft.World/Level/Level.cpp | 16 +++++--------- Minecraft.World/Level/Level.h | 4 ++-- Minecraft.World/Recipes/FireworksRecipe.cpp | 4 ++-- Minecraft.World/Recipes/FireworksRecipe.h | 10 ++------- 11 files changed, 36 insertions(+), 66 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index f3074f407..fa311aed4 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -26,13 +26,9 @@ void Chunk::CreateNewThreadStorage() { m_tlsTileIds = new unsigned char[16 * 16 * Level::maxBuildHeight]; } -void Chunk::ReleaseThreadStorage() { - delete m_tlsTileIds; -} +void Chunk::ReleaseThreadStorage() { delete m_tlsTileIds; } -uint8_t* Chunk::GetTileIdsStorage() { - return m_tlsTileIds; -} +uint8_t* Chunk::GetTileIdsStorage() { return m_tlsTileIds; } #else // 4J Stu - Don't want this when multi-threaded Tesselator* Chunk::t = Tesselator::getInstance(); diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 6135d75dc..a08a9f9b9 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -26,9 +26,7 @@ int normal; */ thread_local Tesselator* Tesselator::m_tlsInstance = nullptr; -Tesselator* Tesselator::getInstance() { - return m_tlsInstance; -} +Tesselator* Tesselator::getInstance() { return m_tlsInstance; } void Tesselator::CreateNewThreadStorage(int bytes) { Tesselator::m_tlsInstance = new Tesselator(bytes / 4); @@ -349,7 +347,7 @@ void Tesselator::vertexUV(float x, float y, float z, float u, float v) { // where: cccc is a 15-bit (5 bits per x/y/z) origin position / offset // for the whole quad. Each // component is unsigned, and offset by 16 -//so has a range 0 to 31 actually representing -16 to 15 +// so has a range 0 to 31 actually representing -16 to 15 // xx,yy,zz are 8-bit deltas from this origin to each vertex. These are // unsigned 1.7 fixed point, ie // representing a range of 0 to 1.9921875 @@ -358,14 +356,16 @@ void Tesselator::vertexUV(float x, float y, float z, float u, float v) { // v required by the quad ud,vd are 8-bit unsigned fixed pont // UV deltas, which can be added to umin/vmin to get umax, vmax // and therefore define the 4 corners of -//an axis aligned UV mapping +// an axis aligned UV mapping // i is a code per vertex that indicates which of umin/umax // should be used for u, and which // of vmin/vmax should be used for v for -//this vertex. The coding is: 0 - u = umin, v = vmin 1 - u = umin, v = vmax 2 - -//u = umax, v = vmin 3 - u = umax, v = vmax 4 - not axis aligned, use uv stored -//in the vertex data 4 on from this one ll is an 8-bit (4 bit per -//u/v) index into the current lighting texture +// this vertex. The coding is: 0 - u = +// umin, v = vmin 1 - u = umin, v +// = vmax 2 - u = umax, v = vmin +// 3 - u = umax, v = vmax 4 - not +// axis aligned, use uv stored in the vertex data 4 on from this one ll +// is an 8-bit (4 bit per u/v) index into the current lighting texture // // For quads that don't have axis aligned UVs (ie have a code for 4 in i as // described above) the 8 byte vertex is followed by a further 8 bytes which @@ -747,7 +747,8 @@ void packLinuxLightmapCoords(int tex2, std::int16_t& u, std::int16_t& v) { v = static_cast((tex2 >> 16) & 0xffff); // Linux 4jlibs consumes packed UV2 values by dividing them by 256 directly - // for chunk and other non-scaleLight draws, so offset to texel centers here. + // for chunk and other non-scaleLight draws, so offset to texel centers + // here. u += 8; v += 8; } @@ -853,8 +854,7 @@ void Tesselator::vertex(float x, float y, float z) { pShortData[4] = (((int)(uu * 8192.0f)) & 0xffff); pShortData[5] = (((int)(v * 8192.0f)) & 0xffff); std::int16_t u2 = static_cast(_tex2 & 0xffff); - std::int16_t v2 = - static_cast((_tex2 >> 16) & 0xffff); + std::int16_t v2 = static_cast((_tex2 >> 16) & 0xffff); #ifdef __linux__ packLinuxLightmapCoords(_tex2, u2, v2); logLinuxPackedLightmapCoords("compact", _tex2, u2, v2); diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 489a4cbd2..de8c30b23 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -31,13 +31,9 @@ thread_local bool PistonBaseTile::m_tlsIgnoreUpdate = false; // leaving the piston in a bad (simultaneously extended & not extended) state. // 4J - ignoreUpdate is a static in java, implementing as TLS here to make // thread safe -bool PistonBaseTile::ignoreUpdate() { - return m_tlsIgnoreUpdate; -} +bool PistonBaseTile::ignoreUpdate() { return m_tlsIgnoreUpdate; } -void PistonBaseTile::ignoreUpdate(bool set) { - m_tlsIgnoreUpdate = set; -} +void PistonBaseTile::ignoreUpdate(bool set) { m_tlsIgnoreUpdate = set; } PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, false) { diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index 0bca60a44..89a41c0dc 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -13,13 +13,9 @@ thread_local bool TheEndPortal::m_tlsAllowAnywhere = false; // 4J - allowAnywhere is a static in java, implementing as TLS here to make // thread safe -bool TheEndPortal::allowAnywhere() { - return m_tlsAllowAnywhere; -} +bool TheEndPortal::allowAnywhere() { return m_tlsAllowAnywhere; } -void TheEndPortal::allowAnywhere(bool set) { - m_tlsAllowAnywhere = set; -} +void TheEndPortal::allowAnywhere(bool set) { m_tlsAllowAnywhere = set; } TheEndPortal::TheEndPortal(int id, Material* material) : BaseEntityTile(id, material, false) { diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index 9b1693afd..73dc4a523 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -229,13 +229,9 @@ Tile::ThreadStorage::ThreadStorage() { tileId = 0; } -void Tile::CreateNewThreadStorage() { - m_tlsShape = new ThreadStorage(); -} +void Tile::CreateNewThreadStorage() { m_tlsShape = new ThreadStorage(); } -void Tile::ReleaseThreadStorage() { - delete m_tlsShape; -} +void Tile::ReleaseThreadStorage() { delete m_tlsShape; } void Tile::staticCtor() { Tile::SOUND_NORMAL = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1); @@ -1918,8 +1914,7 @@ bool Tile::isFaceVisible(Level* level, int x, int y, int z, int f) { } bool Tile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { - ThreadStorage* tls = - m_tlsShape; + ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); if (face == 0 && tls->yy0 > 0) return true; @@ -2595,7 +2590,8 @@ int Tile::SoundType::getPlaceSound() const { return iPlaceSound; } 4J: These are necessary on the PS3. (and 4 and Vita). */ -#if (defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined __linux__) +#if (defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || \ + defined __linux__) const int Tile::stone_Id; const int Tile::grass_Id; const int Tile::dirt_Id; diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index 64401de87..8ba44c61b 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -11,8 +11,7 @@ const int TopSnowTile::MAX_HEIGHT = 6; const int TopSnowTile::HEIGHT_MASK = 7; // max 8 steps -TopSnowTile::TopSnowTile(int id) - : Tile(id, Material::topSnow, false) { +TopSnowTile::TopSnowTile(int id) : Tile(id, Material::topSnow, false) { setShape(0, 0, 0, 1, 2 / 16.0f, 1); setTicking(true); updateShape(0); diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 217116c81..0118aa0a1 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -5,8 +5,7 @@ #include "../Headers/net.minecraft.world.phys.h" #include "TripWireTile.h" -TripWireTile::TripWireTile(int id) - : Tile(id, Material::decoration, false) { +TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, false) { setShape(0, 0, 0, 1, 2.5f / 16.0f, 1); this->setTicking(true); } diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index a87eee1af..bf7c95ad7 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -102,9 +102,7 @@ void Level::enableLightingCache() { 256 * 1024, MAXULONG_PTR, 128 * 1024, PAGE_READWRITE | MEM_LARGE_PAGES); } -void Level::destroyLightingCache() { - delete m_tlsLightCache; -} +void Level::destroyLightingCache() { delete m_tlsLightCache; } inline int GetIndex(int x, int y, int z) { return ((x & 15) << 8) | ((y & 15) << 4) | (z & 15); @@ -491,13 +489,9 @@ void Level::flushCache(lightCache_t* cache, uint64_t cacheUse, // 4J - added following 2 functions to move instaBuild flag from being a class // member, to TLS -bool Level::getInstaTick() { - return m_tlsInstaTick; -} +bool Level::getInstaTick() { return m_tlsInstaTick; } -void Level::setInstaTick(bool enable) { - m_tlsInstaTick = enable; -} +void Level::setInstaTick(bool enable) { m_tlsInstaTick = enable; } // 4J - added bool Level::hasEntitiesToRemove() { return !entitiesToRemove.empty(); } @@ -1569,8 +1563,8 @@ void Level::playStreamingMusic(const std::wstring& name, int x, int y, int z) { } } -void Level::playMusic(double x, double y, double z, - const std::wstring& string, float volume) {} +void Level::playMusic(double x, double y, double z, const std::wstring& string, + float volume) {} // 4J removed - /* diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index 03370e96c..840e3ae1d 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -332,8 +332,8 @@ public: float fClipSoundDist = 16.0f); void playStreamingMusic(const std::wstring& name, int x, int y, int z); - void playMusic(double x, double y, double z, - const std::wstring& string, float volume); + void playMusic(double x, double y, double z, const std::wstring& string, + float volume); // 4J removed - void addParticle(const std::wstring& id, double x, double y, // double z, double xd, double yd, double zd); void addParticle(ePARTICLE_TYPE id, double x, double y, double z, double xd, diff --git a/Minecraft.World/Recipes/FireworksRecipe.cpp b/Minecraft.World/Recipes/FireworksRecipe.cpp index e14c08c33..7039e6b25 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.cpp +++ b/Minecraft.World/Recipes/FireworksRecipe.cpp @@ -11,11 +11,11 @@ FireworksRecipe::ThreadStorage::ThreadStorage() { resultItem = nullptr; } void FireworksRecipe::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - + if (m_defaultThreadStorage == nullptr) { m_defaultThreadStorage = tls; } - + m_tlsStorage = tls; } diff --git a/Minecraft.World/Recipes/FireworksRecipe.h b/Minecraft.World/Recipes/FireworksRecipe.h index bb52b6842..ecc61ddcc 100644 --- a/Minecraft.World/Recipes/FireworksRecipe.h +++ b/Minecraft.World/Recipes/FireworksRecipe.h @@ -38,14 +38,8 @@ public: virtual const int getGroup() { return 0; } // 4J-PB - virtual bool - requiresRecipe(int iRecipe) - { - return false; - }; - virtual void - collectRequirements(INGREDIENTS_REQUIRED* pIngReq) - {}; + virtual bool requiresRecipe(int iRecipe) { return false; }; + virtual void collectRequirements(INGREDIENTS_REQUIRED* pIngReq) {}; // 4J Added static void updatePossibleRecipes(