Improvements

Also a "rewrite" of Texture.cpp but im not happy with it
This commit is contained in:
GabsPuNs
2026-05-29 15:23:34 -04:00
parent f4db952884
commit e01cd453fb
4 changed files with 322 additions and 653 deletions

View File

@@ -10,6 +10,11 @@ std::deque<DataOutputStream *> McRegionChunkStorage::s_chunkDataQueue;
int McRegionChunkStorage::s_runningThreadCount = 0;
C4JThread *McRegionChunkStorage::s_saveThreads[3];
static bool s_running = true;
static std::mutex s_queue;
static std::condition_variable s_queueC;
static std::condition_variable s_waitC;
static std::condition_variable s_allSavedC;
McRegionChunkStorage::McRegionChunkStorage(ConsoleSaveFile *saveFile, const wstring &prefix) : m_prefix( prefix )
{
@@ -65,9 +70,17 @@ McRegionChunkStorage::McRegionChunkStorage(ConsoleSaveFile *saveFile, const wstr
McRegionChunkStorage::~McRegionChunkStorage()
{
for(auto& it : m_entityData)
{
delete it.second.data;
}
{
std::lock_guard<std::mutex> lock(s_queue);
s_running = false;
}
s_queueC.notify_all();
s_waitC.notify_all();
s_allSavedC.notify_all();
WaitForAllSaves();
}
LevelChunk *McRegionChunkStorage::load(Level *level, int x, int z)
@@ -193,9 +206,12 @@ void McRegionChunkStorage::save(Level *level, LevelChunk *levelChunk)
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Updating chunk queue");
EnterCriticalSection(&cs_memory);
s_chunkDataQueue.push_back(output);
LeaveCriticalSection(&cs_memory);
{
std::lock_guard<std::mutex> lock(s_queue);
s_chunkDataQueue.push_back(output);
}
s_queueC.notify_one();
PIXEndNamedEvent();
}
else
@@ -333,7 +349,6 @@ void McRegionChunkStorage::staticCtor()
//saveThreads[j] = CreateThread(nullptr,0,runSaveThreadProc,&threadData[j],CREATE_SUSPENDED,&threadId[j]);
s_saveThreads[i] = new C4JThread(runSaveThreadProc,nullptr,threadName);
//app.DebugPrintf("Created new thread: %s\n",threadName);
// Threads 1,3 and 5 are generally idle so use them
@@ -356,43 +371,42 @@ int McRegionChunkStorage::runSaveThreadProc(LPVOID lpParam)
{
Compression::CreateNewThreadStorage();
bool running = true;
size_t lastQueueSize = 0;
DataOutputStream *dos = nullptr;
while(running)
while(s_running)
{
if( TryEnterCriticalSection(&cs_memory) )
{
lastQueueSize = s_chunkDataQueue.size();
if(lastQueueSize > 0)
{
dos = s_chunkDataQueue.front();
s_chunkDataQueue.pop_front();
}
s_runningThreadCount++;
LeaveCriticalSection(&cs_memory);
std::unique_lock<std::mutex> lock(s_queue);
s_queueC.wait(lock, []{return !s_chunkDataQueue.empty() || !s_running;});
if (!s_running && s_chunkDataQueue.empty())
break;
dos = s_chunkDataQueue.front();
s_chunkDataQueue.pop_front();
s_runningThreadCount++;
s_waitC.notify_all();
}
if(dos)
{
PIXBeginNamedEvent(0,"Saving chunk");
//app.DebugPrintf("Compressing chunk data (%d left)\n", lastQueueSize - 1);
dos->close();
dos->deleteChildStream();
PIXEndNamedEvent();
if(dos)
{
PIXBeginNamedEvent(0,"Saving chunk");
//app.DebugPrintf("Compressing chunk data (%d left)\n", lastQueueSize - 1);
dos->close();
dos->deleteChildStream();
PIXEndNamedEvent();
}
delete dos;
dos = nullptr;
EnterCriticalSection(&cs_memory);
s_runningThreadCount--;
LeaveCriticalSection(&cs_memory);
}
// If there was more than one thing in the queue last time we checked, then we want to spin round again soon
// Otherwise wait a bit longer
if( (lastQueueSize -1) > 0) Sleep(1); // Sleep 1 to yield
else Sleep(100);
{
std::lock_guard<std::mutex> lock(s_queue);
s_runningThreadCount--;
if (s_chunkDataQueue.empty() && s_runningThreadCount == 0)
s_allSavedC.notify_all();
}
}
Compression::ReleaseThreadStorage();
@@ -413,33 +427,10 @@ void McRegionChunkStorage::WaitIfTooManyQueuedChunks()
// Static
void McRegionChunkStorage::WaitForAllSaves()
{
// Wait for there to be no more tasks to be processed...
EnterCriticalSection(&cs_memory);
size_t queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
// Wait for there to be no more tasks or threads to be processed...
std::unique_lock<std::mutex> lock(s_queue);
while(queueSize > 0)
{
Sleep(10);
EnterCriticalSection(&cs_memory);
queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
}
// And then wait for there to be no running threads that are processing these tasks
EnterCriticalSection(&cs_memory);
int runningThreadCount = s_runningThreadCount;
LeaveCriticalSection(&cs_memory);
while(runningThreadCount > 0)
{
Sleep(10);
EnterCriticalSection(&cs_memory);
runningThreadCount = s_runningThreadCount;
LeaveCriticalSection(&cs_memory);
}
s_allSavedC.wait(lock, [] {return s_chunkDataQueue.empty() && (s_runningThreadCount == 0);});
}
// Static
@@ -449,19 +440,8 @@ void McRegionChunkStorage::WaitForSaves()
static const int DESIRED_QUEUE_SIZE = 6;
// Wait for the queue to reduce to a level where we should add more elements
EnterCriticalSection(&cs_memory);
size_t queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
std::unique_lock<std::mutex> lock(s_queue);
if( queueSize > MAX_QUEUE_SIZE )
{
while( queueSize > DESIRED_QUEUE_SIZE )
{
Sleep(10);
EnterCriticalSection(&cs_memory);
queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
}
}
if( s_chunkDataQueue.size() > MAX_QUEUE_SIZE )
s_waitC.wait(lock, [] {return s_chunkDataQueue.size() <= DESIRED_QUEUE_SIZE;});
}