From 420125debd3d010fcd3e7738c43f25c8f407ab63 Mon Sep 17 00:00:00 2001
From: est31 <MTest31@outlook.com>
Date: Sat, 27 Jun 2015 18:11:24 +0200
Subject: [PATCH] Remove busy polling inside minimap thread

---
 src/minimap.cpp | 45 ++++++++++++++++++++++++++++++++-------------
 src/minimap.h   | 13 ++++++++++---
 2 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/src/minimap.cpp b/src/minimap.cpp
index 61960ca1e..753468c32 100644
--- a/src/minimap.cpp
+++ b/src/minimap.cpp
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "minimap.h"
 #include "logoutputbuffer.h"
 #include "jthread/jmutexautolock.h"
+#include "jthread/jsemaphore.h"
 #include "clientmap.h"
 #include "settings.h"
 #include "nodedef.h"
@@ -47,16 +48,15 @@ MinimapUpdateQueue::~MinimapUpdateQueue()
 {
 	JMutexAutoLock lock(m_mutex);
 
-	for (std::vector<QueuedMinimapUpdate*>::iterator
+	for (std::list<QueuedMinimapUpdate*>::iterator
 			i = m_queue.begin();
-			i != m_queue.end(); i++)
-	{
+			i != m_queue.end(); ++i) {
 		QueuedMinimapUpdate *q = *i;
 		delete q;
 	}
 }
 
-void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
+bool MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
 {
 	DSTACK(__FUNCTION_NAME);
 
@@ -66,15 +66,14 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
 		Find if block is already in queue.
 		If it is, update the data and quit.
 	*/
-	for (std::vector<QueuedMinimapUpdate*>::iterator
+	for (std::list<QueuedMinimapUpdate*>::iterator
 			i = m_queue.begin();
-			i != m_queue.end(); i++)
-	{
+			i != m_queue.end(); ++i) {
 		QueuedMinimapUpdate *q = *i;
 		if (q->pos == pos) {
 			delete q->data;
 			q->data = data;
-			return;
+			return false;
 		}
 	}
 
@@ -85,16 +84,16 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
 	q->pos = pos;
 	q->data = data;
 	m_queue.push_back(q);
+	return true;
 }
 
 QueuedMinimapUpdate * MinimapUpdateQueue::pop()
 {
 	JMutexAutoLock lock(m_mutex);
 
-	for (std::vector<QueuedMinimapUpdate*>::iterator
+	for (std::list<QueuedMinimapUpdate*>::iterator
 			i = m_queue.begin();
-			i != m_queue.end(); i++)
-	{
+			i != m_queue.end(); i++) {
 		QueuedMinimapUpdate *q = *i;
 		m_queue.erase(i);
 		return q;
@@ -106,6 +105,22 @@ QueuedMinimapUpdate * MinimapUpdateQueue::pop()
 	Minimap update thread
 */
 
+void MinimapUpdateThread::Stop()
+{
+	JThread::Stop();
+
+	// give us a nudge
+	m_queue_sem.Post();
+}
+
+void MinimapUpdateThread::enqueue_Block(v3s16 pos, MinimapMapblock *data)
+{
+	if (m_queue.addBlock(pos, data))
+		// we had to allocate a new block
+		m_queue_sem.Post();
+}
+
+
 void *MinimapUpdateThread::Thread()
 {
 	ThreadStarted();
@@ -120,8 +135,13 @@ void *MinimapUpdateThread::Thread()
 
 	while (!StopRequested()) {
 
+		m_queue_sem.Wait();
+		if (StopRequested()) break;
+
 		while (m_queue.size()) {
 			QueuedMinimapUpdate *q = m_queue.pop();
+			if (!q)
+				break;
 			std::map<v3s16, MinimapMapblock *>::iterator it;
 			it = m_blocks_cache.find(q->pos);
 			if (q->data) {
@@ -138,7 +158,6 @@ void *MinimapUpdateThread::Thread()
 				data->map_invalidated = false;
 			}
 		}
-	//	sleep_ms(10);
 	}
 	END_DEBUG_EXCEPTION_HANDLER(errorstream)
 
@@ -266,7 +285,7 @@ Mapper::~Mapper()
 
 void Mapper::addBlock (v3s16 pos, MinimapMapblock *data)
 {
-	m_minimap_update_thread->m_queue.addBlock(pos, data);
+	m_minimap_update_thread->enqueue_Block(pos, data);
 }
 
 MinimapMode Mapper::getMinimapMode()
diff --git a/src/minimap.h b/src/minimap.h
index ebb74c4fb..1794da190 100644
--- a/src/minimap.h
+++ b/src/minimap.h
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client.h"
 #include "voxel.h"
 #include "jthread/jmutex.h"
+#include "jthread/jsemaphore.h"
 #include <map>
 #include <string>
 #include <vector>
@@ -93,8 +94,9 @@ class MinimapUpdateQueue
 
 	~MinimapUpdateQueue();
 
-	void addBlock(v3s16 pos, MinimapMapblock *data);
+	bool addBlock(v3s16 pos, MinimapMapblock *data);
 
+	// blocking!!
 	QueuedMinimapUpdate *pop();
 
 	u32 size()
@@ -104,13 +106,15 @@ class MinimapUpdateQueue
 	}
 
 private:
-	std::vector<QueuedMinimapUpdate*> m_queue;
+	std::list<QueuedMinimapUpdate*> m_queue;
 	JMutex m_mutex;
 };
 
 class MinimapUpdateThread : public JThread
 {
 private:
+	JSemaphore m_queue_sem;
+	MinimapUpdateQueue m_queue;
 
 public:
 	MinimapUpdateThread(IrrlichtDevice *device, Client *client)
@@ -124,13 +128,16 @@ class MinimapUpdateThread : public JThread
 	MinimapPixel *getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height);
 	s16 getAirCount (v3s16 pos, s16 height);
 	video::SColor getColorFromId(u16 id);
+
+	void enqueue_Block(v3s16 pos, MinimapMapblock *data);
+
 	IrrlichtDevice *device;
 	Client *client;
 	video::IVideoDriver *driver;
 	ITextureSource *tsrc;
+	void Stop();
 	void *Thread();
 	MinimapData *data;
-	MinimapUpdateQueue m_queue;
 	std::map<v3s16, MinimapMapblock *> m_blocks_cache;
 };
 
-- 
GitLab