mirror of https://github.com/godotengine/godot
CommandQueueMT: Make re-entrant again + Fix multiple flushers case
This commit is contained in:
parent
757bba192e
commit
824287eefb
|
|
@ -107,7 +107,8 @@ class CommandQueueMT {
|
||||||
|
|
||||||
static const uint32_t DEFAULT_COMMAND_MEM_SIZE_KB = 64;
|
static const uint32_t DEFAULT_COMMAND_MEM_SIZE_KB = 64;
|
||||||
|
|
||||||
bool unique_flusher = false;
|
inline static thread_local bool flushing = false;
|
||||||
|
|
||||||
BinaryMutex mutex;
|
BinaryMutex mutex;
|
||||||
LocalVector<uint8_t> command_mem;
|
LocalVector<uint8_t> command_mem;
|
||||||
ConditionVariable sync_cond_var;
|
ConditionVariable sync_cond_var;
|
||||||
|
|
@ -157,10 +158,20 @@ class CommandQueueMT {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _flush() {
|
void _flush() {
|
||||||
|
// Safeguard against trying to re-lock the binary mutex.
|
||||||
|
if (flushing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flushing = true;
|
||||||
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
|
|
||||||
if (unlikely(flush_read_ptr)) {
|
if (unlikely(flush_read_ptr)) {
|
||||||
// Re-entrant call.
|
// Another thread is flushing.
|
||||||
|
lock.temp_unlock(); // Not really temp.
|
||||||
|
sync();
|
||||||
|
flushing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,17 +188,9 @@ class CommandQueueMT {
|
||||||
CommandBase *cmd_local = reinterpret_cast<CommandBase *>(cmd_local_mem);
|
CommandBase *cmd_local = reinterpret_cast<CommandBase *>(cmd_local_mem);
|
||||||
memcpy(cmd_local_mem, (char *)cmd_original, size);
|
memcpy(cmd_local_mem, (char *)cmd_original, size);
|
||||||
|
|
||||||
if (unique_flusher) {
|
lock.temp_unlock();
|
||||||
// A single thread will pump; the lock is only needed for the command queue itself.
|
cmd_local->call();
|
||||||
lock.temp_unlock();
|
lock.temp_relock();
|
||||||
cmd_local->call();
|
|
||||||
lock.temp_relock();
|
|
||||||
} else {
|
|
||||||
// At least we can unlock during WTP operations.
|
|
||||||
uint32_t allowance_id = WorkerThreadPool::thread_enter_unlock_allowance_zone(lock);
|
|
||||||
cmd_local->call();
|
|
||||||
WorkerThreadPool::thread_exit_unlock_allowance_zone(allowance_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(cmd_local->sync)) {
|
if (unlikely(cmd_local->sync)) {
|
||||||
sync_head++;
|
sync_head++;
|
||||||
|
|
@ -206,6 +209,8 @@ class CommandQueueMT {
|
||||||
flush_read_ptr = 0;
|
flush_read_ptr = 0;
|
||||||
|
|
||||||
_prevent_sync_wraparound();
|
_prevent_sync_wraparound();
|
||||||
|
|
||||||
|
flushing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void _wait_for_sync(MutexLock<BinaryMutex> &p_lock) {
|
_FORCE_INLINE_ void _wait_for_sync(MutexLock<BinaryMutex> &p_lock) {
|
||||||
|
|
@ -270,8 +275,7 @@ public:
|
||||||
pump_task_id = p_task_id;
|
pump_task_id = p_task_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandQueueMT(bool p_unique_flusher = false) :
|
CommandQueueMT() {
|
||||||
unique_flusher(p_unique_flusher) {
|
|
||||||
command_mem.reserve(DEFAULT_COMMAND_MEM_SIZE_KB * 1024);
|
command_mem.reserve(DEFAULT_COMMAND_MEM_SIZE_KB * 1024);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ Error _betsy_compress_s3tc(Image *r_img, Image::UsedChannels p_channels);
|
||||||
class BetsyCompressor : public Object {
|
class BetsyCompressor : public Object {
|
||||||
GDSOFTCLASS(BetsyCompressor, Object);
|
GDSOFTCLASS(BetsyCompressor, Object);
|
||||||
|
|
||||||
mutable CommandQueueMT command_queue = CommandQueueMT(true);
|
mutable CommandQueueMT command_queue;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID;
|
WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class RenderingServerDefault : public RenderingServer {
|
||||||
uint64_t print_frame_profile_ticks_from = 0;
|
uint64_t print_frame_profile_ticks_from = 0;
|
||||||
uint32_t print_frame_profile_frame_count = 0;
|
uint32_t print_frame_profile_frame_count = 0;
|
||||||
|
|
||||||
mutable CommandQueueMT command_queue = CommandQueueMT(true);
|
mutable CommandQueueMT command_queue;
|
||||||
|
|
||||||
Thread::ID server_thread = Thread::MAIN_ID;
|
Thread::ID server_thread = Thread::MAIN_ID;
|
||||||
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue