Skip to content

Commit 29dda9f

Browse files
committedJun 29, 2015
Add UpdateThread and use it for minimap and mesh threads
1 parent 4e28c8d commit 29dda9f

File tree

5 files changed

+113
-97
lines changed

5 files changed

+113
-97
lines changed
 

Diff for: ‎src/client.cpp

+12-25
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se
139139

140140
// Returned pointer must be deleted
141141
// Returns NULL if queue is empty
142-
QueuedMeshUpdate * MeshUpdateQueue::pop()
142+
QueuedMeshUpdate *MeshUpdateQueue::pop()
143143
{
144144
JMutexAutoLock lock(m_mutex);
145145

@@ -162,26 +162,17 @@ QueuedMeshUpdate * MeshUpdateQueue::pop()
162162
MeshUpdateThread
163163
*/
164164

165-
void * MeshUpdateThread::Thread()
165+
void MeshUpdateThread::enqueueUpdate(v3s16 p, MeshMakeData *data,
166+
bool ack_block_to_server, bool urgent)
166167
{
167-
ThreadStarted();
168-
169-
log_register_thread("MeshUpdateThread");
170-
171-
DSTACK(__FUNCTION_NAME);
172-
173-
BEGIN_DEBUG_EXCEPTION_HANDLER
174-
175-
porting::setThreadName("MeshUpdateThread");
168+
m_queue_in.addBlock(p, data, ack_block_to_server, urgent);
169+
deferUpdate();
170+
}
176171

177-
while(!StopRequested())
178-
{
179-
QueuedMeshUpdate *q = m_queue_in.pop();
180-
if(q == NULL)
181-
{
182-
sleep_ms(3);
183-
continue;
184-
}
172+
void MeshUpdateThread::doUpdate()
173+
{
174+
QueuedMeshUpdate *q;
175+
while ((q = m_queue_in.pop())) {
185176

186177
ScopeProfiler sp(g_profiler, "Client: Mesh making");
187178

@@ -196,10 +187,6 @@ void * MeshUpdateThread::Thread()
196187

197188
delete q;
198189
}
199-
200-
END_DEBUG_EXCEPTION_HANDLER(errorstream)
201-
202-
return NULL;
203190
}
204191

205192
/*
@@ -230,7 +217,7 @@ Client::Client(
230217
m_nodedef(nodedef),
231218
m_sound(sound),
232219
m_event(event),
233-
m_mesh_update_thread(this),
220+
m_mesh_update_thread(),
234221
m_env(
235222
new ClientMap(this, this, control,
236223
device->getSceneManager()->getRootSceneNode(),
@@ -1600,7 +1587,7 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
16001587
}
16011588

16021589
// Add task to queue
1603-
m_mesh_update_thread.m_queue_in.addBlock(p, data, ack_to_server, urgent);
1590+
m_mesh_update_thread.enqueueUpdate(p, data, ack_to_server, urgent);
16041591
}
16051592

16061593
void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent)

Diff for: ‎src/client.h

+12-8
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,27 @@ struct MeshUpdateResult
113113
}
114114
};
115115

116-
class MeshUpdateThread : public JThread
116+
class MeshUpdateThread : public UpdateThread
117117
{
118+
private:
119+
MeshUpdateQueue m_queue_in;
120+
121+
protected:
122+
const char *getName()
123+
{ return "MeshUpdateThread"; }
124+
virtual void doUpdate();
125+
118126
public:
119127

120-
MeshUpdateThread(IGameDef *gamedef):
121-
m_gamedef(gamedef)
128+
MeshUpdateThread()
122129
{
123130
}
124131

125-
void * Thread();
126-
127-
MeshUpdateQueue m_queue_in;
132+
void enqueueUpdate(v3s16 p, MeshMakeData *data,
133+
bool ack_block_to_server, bool urgent);
128134

129135
MutexedQueue<MeshUpdateResult> m_queue_out;
130136

131-
IGameDef *m_gamedef;
132-
133137
v3s16 m_camera_offset;
134138
};
135139

Diff for: ‎src/minimap.cpp

+22-58
Original file line numberDiff line numberDiff line change
@@ -105,67 +105,31 @@ QueuedMinimapUpdate * MinimapUpdateQueue::pop()
105105
Minimap update thread
106106
*/
107107

108-
void MinimapUpdateThread::Stop()
109-
{
110-
JThread::Stop();
111-
112-
// give us a nudge
113-
m_queue_sem.Post();
114-
}
115-
116108
void MinimapUpdateThread::enqueue_Block(v3s16 pos, MinimapMapblock *data)
117109
{
118-
if (m_queue.addBlock(pos, data))
119-
// we had to allocate a new block
120-
m_queue_sem.Post();
110+
m_queue.addBlock(pos, data);
111+
deferUpdate();
121112
}
122113

123-
void MinimapUpdateThread::forceUpdate()
114+
void MinimapUpdateThread::doUpdate()
124115
{
125-
m_queue_sem.Post();
126-
}
127-
128-
void *MinimapUpdateThread::Thread()
129-
{
130-
ThreadStarted();
131-
132-
log_register_thread("MinimapUpdateThread");
133-
134-
DSTACK(__FUNCTION_NAME);
135-
136-
BEGIN_DEBUG_EXCEPTION_HANDLER
137-
138-
porting::setThreadName("MinimapUpdateThread");
139-
140-
while (!StopRequested()) {
141-
142-
m_queue_sem.Wait();
143-
if (StopRequested()) break;
144-
145-
while (m_queue.size()) {
146-
QueuedMinimapUpdate *q = m_queue.pop();
147-
if (!q)
148-
break;
149-
std::map<v3s16, MinimapMapblock *>::iterator it;
150-
it = m_blocks_cache.find(q->pos);
151-
if (q->data) {
152-
m_blocks_cache[q->pos] = q->data;
153-
} else if (it != m_blocks_cache.end()) {
154-
delete it->second;
155-
m_blocks_cache.erase(it);
156-
}
116+
while (m_queue.size()) {
117+
QueuedMinimapUpdate *q = m_queue.pop();
118+
std::map<v3s16, MinimapMapblock *>::iterator it;
119+
it = m_blocks_cache.find(q->pos);
120+
if (q->data) {
121+
m_blocks_cache[q->pos] = q->data;
122+
} else if (it != m_blocks_cache.end()) {
123+
delete it->second;
124+
m_blocks_cache.erase(it);
157125
}
158-
159-
if (data->map_invalidated) {
160-
if (data->mode != MINIMAP_MODE_OFF) {
161-
getMap(data->pos, data->map_size, data->scan_height, data->radar);
162-
data->map_invalidated = false;
163-
}
126+
}
127+
if (data->map_invalidated) {
128+
if (data->mode != MINIMAP_MODE_OFF) {
129+
getMap(data->pos, data->map_size, data->scan_height, data->radar);
130+
data->map_invalidated = false;
164131
}
165132
}
166-
END_DEBUG_EXCEPTION_HANDLER(errorstream)
167-
168-
return NULL;
169133
}
170134

171135
MinimapUpdateThread::~MinimapUpdateThread()
@@ -177,7 +141,7 @@ MinimapUpdateThread::~MinimapUpdateThread()
177141
}
178142
}
179143

180-
MinimapPixel *MinimapUpdateThread::getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height)
144+
MinimapPixel *MinimapUpdateThread::getMinimapPixel(v3s16 pos, s16 height, s16 &pixel_height)
181145
{
182146
pixel_height = height - MAP_BLOCKSIZE;
183147
v3s16 blockpos_max, blockpos_min, relpos;
@@ -198,7 +162,7 @@ MinimapPixel *MinimapUpdateThread::getMinimapPixel (v3s16 pos, s16 height, s16 &
198162
return NULL;
199163
}
200164

201-
s16 MinimapUpdateThread::getAirCount (v3s16 pos, s16 height)
165+
s16 MinimapUpdateThread::getAirCount(v3s16 pos, s16 height)
202166
{
203167
s16 air_count = 0;
204168
v3s16 blockpos_max, blockpos_min, relpos;
@@ -215,7 +179,7 @@ s16 MinimapUpdateThread::getAirCount (v3s16 pos, s16 height)
215179
return air_count;
216180
}
217181

218-
void MinimapUpdateThread::getMap (v3s16 pos, s16 size, s16 height, bool radar)
182+
void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height, bool radar)
219183
{
220184
v3s16 p = v3s16 (pos.X - size / 2, pos.Y, pos.Z - size / 2);
221185

@@ -327,7 +291,7 @@ void Mapper::setMinimapMode(MinimapMode mode)
327291
data->scan_height = modeDefs[(int)mode * 3 + 1];
328292
data->map_size = modeDefs[(int)mode * 3 + 2];
329293
data->mode = mode;
330-
m_minimap_update_thread->forceUpdate();
294+
m_minimap_update_thread->deferUpdate();
331295
}
332296

333297
void Mapper::setPos(v3s16 pos)
@@ -336,7 +300,7 @@ void Mapper::setPos(v3s16 pos)
336300
if (pos != data->old_pos) {
337301
data->old_pos = data->pos;
338302
data->pos = pos;
339-
m_minimap_update_thread->forceUpdate();
303+
m_minimap_update_thread->deferUpdate();
340304
}
341305
}
342306

Diff for: ‎src/minimap.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ class MinimapUpdateQueue
9696

9797
bool addBlock(v3s16 pos, MinimapMapblock *data);
9898

99-
// blocking!!
10099
QueuedMinimapUpdate *pop();
101100

102101
u32 size()
@@ -110,12 +109,16 @@ class MinimapUpdateQueue
110109
JMutex m_mutex;
111110
};
112111

113-
class MinimapUpdateThread : public JThread
112+
class MinimapUpdateThread : public UpdateThread
114113
{
115114
private:
116-
JSemaphore m_queue_sem;
117115
MinimapUpdateQueue m_queue;
118116

117+
protected:
118+
const char *getName()
119+
{ return "MinimapUpdateThread"; }
120+
virtual void doUpdate();
121+
119122
public:
120123
MinimapUpdateThread(IrrlichtDevice *device, Client *client)
121124
{
@@ -131,13 +134,10 @@ class MinimapUpdateThread : public JThread
131134
video::SColor getColorFromId(u16 id);
132135

133136
void enqueue_Block(v3s16 pos, MinimapMapblock *data);
134-
void forceUpdate();
135137
IrrlichtDevice *device;
136138
Client *client;
137139
video::IVideoDriver *driver;
138140
ITextureSource *tsrc;
139-
void Stop();
140-
void *Thread();
141141
MinimapData *data;
142142
std::map<v3s16, MinimapMapblock *> m_blocks_cache;
143143
};

Diff for: ‎src/util/thread.h

+61
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525
#include "../jthread/jmutex.h"
2626
#include "../jthread/jmutexautolock.h"
2727
#include "porting.h"
28+
#include "log.h"
2829

2930
template<typename T>
3031
class MutexedVariable
@@ -208,5 +209,65 @@ class RequestQueue
208209
MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
209210
};
210211

212+
class UpdateThread : public JThread
213+
{
214+
private:
215+
JSemaphore m_update_sem;
216+
217+
protected:
218+
virtual void doUpdate() = 0;
219+
virtual const char *getName() = 0;
220+
221+
public:
222+
UpdateThread()
223+
{
224+
}
225+
~UpdateThread()
226+
{}
227+
228+
void deferUpdate()
229+
{
230+
m_update_sem.Post();
231+
}
232+
233+
void Stop()
234+
{
235+
JThread::Stop();
236+
237+
// give us a nudge
238+
m_update_sem.Post();
239+
}
240+
241+
void *Thread()
242+
{
243+
ThreadStarted();
244+
245+
const char *thread_name = getName();
246+
247+
log_register_thread(thread_name);
248+
249+
DSTACK(__FUNCTION_NAME);
250+
251+
BEGIN_DEBUG_EXCEPTION_HANDLER
252+
253+
porting::setThreadName(thread_name);
254+
255+
while (!StopRequested()) {
256+
257+
m_update_sem.Wait();
258+
259+
// Empty the queue, just in case doUpdate() is expensive
260+
while (m_update_sem.GetValue()) m_update_sem.Wait();
261+
262+
if (StopRequested()) break;
263+
264+
doUpdate();
265+
}
266+
END_DEBUG_EXCEPTION_HANDLER(errorstream)
267+
268+
return NULL;
269+
}
270+
};
271+
211272
#endif
212273

0 commit comments

Comments
 (0)
Please sign in to comment.