Skip to content

Commit 824287e

Browse files
committed
CommandQueueMT: Make re-entrant again + Fix multiple flushers case
1 parent 757bba1 commit 824287e

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

core/templates/command_queue_mt.h

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class CommandQueueMT {
107107

108108
static const uint32_t DEFAULT_COMMAND_MEM_SIZE_KB = 64;
109109

110-
bool unique_flusher = false;
110+
inline static thread_local bool flushing = false;
111+
111112
BinaryMutex mutex;
112113
LocalVector<uint8_t> command_mem;
113114
ConditionVariable sync_cond_var;
@@ -157,10 +158,20 @@ class CommandQueueMT {
157158
}
158159

159160
void _flush() {
161+
// Safeguard against trying to re-lock the binary mutex.
162+
if (flushing) {
163+
return;
164+
}
165+
166+
flushing = true;
167+
160168
MutexLock lock(mutex);
161169

162170
if (unlikely(flush_read_ptr)) {
163-
// Re-entrant call.
171+
// Another thread is flushing.
172+
lock.temp_unlock(); // Not really temp.
173+
sync();
174+
flushing = false;
164175
return;
165176
}
166177

@@ -177,17 +188,9 @@ class CommandQueueMT {
177188
CommandBase *cmd_local = reinterpret_cast<CommandBase *>(cmd_local_mem);
178189
memcpy(cmd_local_mem, (char *)cmd_original, size);
179190

180-
if (unique_flusher) {
181-
// A single thread will pump; the lock is only needed for the command queue itself.
182-
lock.temp_unlock();
183-
cmd_local->call();
184-
lock.temp_relock();
185-
} else {
186-
// At least we can unlock during WTP operations.
187-
uint32_t allowance_id = WorkerThreadPool::thread_enter_unlock_allowance_zone(lock);
188-
cmd_local->call();
189-
WorkerThreadPool::thread_exit_unlock_allowance_zone(allowance_id);
190-
}
191+
lock.temp_unlock();
192+
cmd_local->call();
193+
lock.temp_relock();
191194

192195
if (unlikely(cmd_local->sync)) {
193196
sync_head++;
@@ -206,6 +209,8 @@ class CommandQueueMT {
206209
flush_read_ptr = 0;
207210

208211
_prevent_sync_wraparound();
212+
213+
flushing = false;
209214
}
210215

211216
_FORCE_INLINE_ void _wait_for_sync(MutexLock<BinaryMutex> &p_lock) {
@@ -270,8 +275,7 @@ class CommandQueueMT {
270275
pump_task_id = p_task_id;
271276
}
272277

273-
CommandQueueMT(bool p_unique_flusher = false) :
274-
unique_flusher(p_unique_flusher) {
278+
CommandQueueMT() {
275279
command_mem.reserve(DEFAULT_COMMAND_MEM_SIZE_KB * 1024);
276280
}
277281
};

modules/betsy/image_compress_betsy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Error _betsy_compress_s3tc(Image *r_img, Image::UsedChannels p_channels);
103103
class BetsyCompressor : public Object {
104104
GDSOFTCLASS(BetsyCompressor, Object);
105105

106-
mutable CommandQueueMT command_queue = CommandQueueMT(true);
106+
mutable CommandQueueMT command_queue;
107107
bool exit = false;
108108
WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID;
109109

servers/rendering/rendering_server_default.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class RenderingServerDefault : public RenderingServer {
7474
uint64_t print_frame_profile_ticks_from = 0;
7575
uint32_t print_frame_profile_frame_count = 0;
7676

77-
mutable CommandQueueMT command_queue = CommandQueueMT(true);
77+
mutable CommandQueueMT command_queue;
7878

7979
Thread::ID server_thread = Thread::MAIN_ID;
8080
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;

0 commit comments

Comments
 (0)