From 5d0da9a2c04673eaceb630c7d38dddf4b80d2183 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 28 Feb 2012 16:59:59 +0000 Subject: Improved threading performance by reducing thread-hopping in queue locks (cs unlocked before event set) git-svn-id: http://mc-server.googlecode.com/svn/trunk@341 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/WorldStorage.cpp | 32 ++++++++++++++++++++------------ source/cChunkGenerator.cpp | 30 ++++++++++++++++-------------- source/cServer.cpp | 8 +++++--- 3 files changed, 41 insertions(+), 29 deletions(-) (limited to 'source') diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp index 2bebbbad5..a3d9b50b2 100644 --- a/source/WorldStorage.cpp +++ b/source/WorldStorage.cpp @@ -199,17 +199,20 @@ int cWorldStorage::GetSaveQueueLength(void) void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) { // Queues the chunk for loading; if not loaded, the chunk will be generated - cCSLock Lock(m_CSQueues); - - // Check if already in the queue: - for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate)) + cCSLock Lock(m_CSQueues); + + // Check if already in the queue: + for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) { - return; + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate)) + { + return; + } } + m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); } - m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); + m_Event.Set(); } @@ -219,9 +222,11 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, boo void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { - cCSLock Lock(m_CSQueues); - m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice - m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice + m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } m_Event.Set(); } @@ -239,6 +244,7 @@ void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) continue; } m_LoadQueue.erase(itr); + Lock.Unlock(); m_evtRemoved.Set(); return; } // for itr - m_LoadQueue[] @@ -250,8 +256,10 @@ void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk) { - cCSLock Lock(m_CSQueues); - m_SaveQueue.remove(a_Chunk); + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove(a_Chunk); + } m_evtRemoved.Set(); } diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp index 072326eb6..83375fc5b 100644 --- a/source/cChunkGenerator.cpp +++ b/source/cChunkGenerator.cpp @@ -84,24 +84,26 @@ void cChunkGenerator::Stop(void) void cChunkGenerator::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { - cCSLock Lock(m_CS); - - // Check if it is already in the queue: - for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + cCSLock Lock(m_CS); + + // Check if it is already in the queue: + for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) { - // Already in the queue, bail out - return; + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Already in the queue, bail out + return; + } + } // for itr - m_Queue[] + + // Add to queue, issue a warning if too many: + if (m_Queue.size() >= QUEUE_WARNING_LIMIT) + { + LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); } - } // for itr - m_Queue[] - - // Add to queue, issue a warning if too many: - if (m_Queue.size() >= QUEUE_WARNING_LIMIT) - { - LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); + m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); } - m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); m_Event.Set(); } diff --git a/source/cServer.cpp b/source/cServer.cpp index ab4698f3f..3b85a45c4 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -714,9 +714,11 @@ void cServer::cNotifyWriteThread::Execute(void) void cServer::cNotifyWriteThread::NotifyClientWrite(const cClientHandle * a_Client) { - cCSLock Lock(m_CS); - m_Clients.remove(const_cast(a_Client)); // Put it there only once - m_Clients.push_back(const_cast(a_Client)); + { + cCSLock Lock(m_CS); + m_Clients.remove(const_cast(a_Client)); // Put it there only once + m_Clients.push_back(const_cast(a_Client)); + } m_Event.Set(); } -- cgit v1.2.3