Remove busy polling inside minimap thread

This commit is contained in:
est31 2015-06-27 18:11:24 +02:00
parent 36163d9653
commit 420125debd
2 changed files with 42 additions and 16 deletions

View File

@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "minimap.h" #include "minimap.h"
#include "logoutputbuffer.h" #include "logoutputbuffer.h"
#include "jthread/jmutexautolock.h" #include "jthread/jmutexautolock.h"
#include "jthread/jsemaphore.h"
#include "clientmap.h" #include "clientmap.h"
#include "settings.h" #include "settings.h"
#include "nodedef.h" #include "nodedef.h"
@ -47,16 +48,15 @@ MinimapUpdateQueue::~MinimapUpdateQueue()
{ {
JMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
for (std::vector<QueuedMinimapUpdate*>::iterator for (std::list<QueuedMinimapUpdate*>::iterator
i = m_queue.begin(); i = m_queue.begin();
i != m_queue.end(); i++) i != m_queue.end(); ++i) {
{
QueuedMinimapUpdate *q = *i; QueuedMinimapUpdate *q = *i;
delete q; delete q;
} }
} }
void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data) bool MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -66,15 +66,14 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
Find if block is already in queue. Find if block is already in queue.
If it is, update the data and quit. 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.begin();
i != m_queue.end(); i++) i != m_queue.end(); ++i) {
{
QueuedMinimapUpdate *q = *i; QueuedMinimapUpdate *q = *i;
if (q->pos == pos) { if (q->pos == pos) {
delete q->data; delete q->data;
q->data = data; q->data = data;
return; return false;
} }
} }
@ -85,16 +84,16 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data)
q->pos = pos; q->pos = pos;
q->data = data; q->data = data;
m_queue.push_back(q); m_queue.push_back(q);
return true;
} }
QueuedMinimapUpdate * MinimapUpdateQueue::pop() QueuedMinimapUpdate * MinimapUpdateQueue::pop()
{ {
JMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
for (std::vector<QueuedMinimapUpdate*>::iterator for (std::list<QueuedMinimapUpdate*>::iterator
i = m_queue.begin(); i = m_queue.begin();
i != m_queue.end(); i++) i != m_queue.end(); i++) {
{
QueuedMinimapUpdate *q = *i; QueuedMinimapUpdate *q = *i;
m_queue.erase(i); m_queue.erase(i);
return q; return q;
@ -106,6 +105,22 @@ QueuedMinimapUpdate * MinimapUpdateQueue::pop()
Minimap update thread 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() void *MinimapUpdateThread::Thread()
{ {
ThreadStarted(); ThreadStarted();
@ -120,8 +135,13 @@ void *MinimapUpdateThread::Thread()
while (!StopRequested()) { while (!StopRequested()) {
m_queue_sem.Wait();
if (StopRequested()) break;
while (m_queue.size()) { while (m_queue.size()) {
QueuedMinimapUpdate *q = m_queue.pop(); QueuedMinimapUpdate *q = m_queue.pop();
if (!q)
break;
std::map<v3s16, MinimapMapblock *>::iterator it; std::map<v3s16, MinimapMapblock *>::iterator it;
it = m_blocks_cache.find(q->pos); it = m_blocks_cache.find(q->pos);
if (q->data) { if (q->data) {
@ -138,7 +158,6 @@ void *MinimapUpdateThread::Thread()
data->map_invalidated = false; data->map_invalidated = false;
} }
} }
// sleep_ms(10);
} }
END_DEBUG_EXCEPTION_HANDLER(errorstream) END_DEBUG_EXCEPTION_HANDLER(errorstream)
@ -266,7 +285,7 @@ Mapper::~Mapper()
void Mapper::addBlock (v3s16 pos, MinimapMapblock *data) 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() MinimapMode Mapper::getMinimapMode()

View File

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client.h" #include "client.h"
#include "voxel.h" #include "voxel.h"
#include "jthread/jmutex.h" #include "jthread/jmutex.h"
#include "jthread/jsemaphore.h"
#include <map> #include <map>
#include <string> #include <string>
#include <vector> #include <vector>
@ -93,8 +94,9 @@ public:
~MinimapUpdateQueue(); ~MinimapUpdateQueue();
void addBlock(v3s16 pos, MinimapMapblock *data); bool addBlock(v3s16 pos, MinimapMapblock *data);
// blocking!!
QueuedMinimapUpdate *pop(); QueuedMinimapUpdate *pop();
u32 size() u32 size()
@ -104,13 +106,15 @@ public:
} }
private: private:
std::vector<QueuedMinimapUpdate*> m_queue; std::list<QueuedMinimapUpdate*> m_queue;
JMutex m_mutex; JMutex m_mutex;
}; };
class MinimapUpdateThread : public JThread class MinimapUpdateThread : public JThread
{ {
private: private:
JSemaphore m_queue_sem;
MinimapUpdateQueue m_queue;
public: public:
MinimapUpdateThread(IrrlichtDevice *device, Client *client) MinimapUpdateThread(IrrlichtDevice *device, Client *client)
@ -124,13 +128,16 @@ public:
MinimapPixel *getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height); MinimapPixel *getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height);
s16 getAirCount (v3s16 pos, s16 height); s16 getAirCount (v3s16 pos, s16 height);
video::SColor getColorFromId(u16 id); video::SColor getColorFromId(u16 id);
void enqueue_Block(v3s16 pos, MinimapMapblock *data);
IrrlichtDevice *device; IrrlichtDevice *device;
Client *client; Client *client;
video::IVideoDriver *driver; video::IVideoDriver *driver;
ITextureSource *tsrc; ITextureSource *tsrc;
void Stop();
void *Thread(); void *Thread();
MinimapData *data; MinimapData *data;
MinimapUpdateQueue m_queue;
std::map<v3s16, MinimapMapblock *> m_blocks_cache; std::map<v3s16, MinimapMapblock *> m_blocks_cache;
}; };