Browse Source

Merge pull request #98385 from RandomShaper/thread_yield

Rationalize busy waits
Rémi Verschelde 7 months ago
parent
commit
8a743f23e6

+ 20 - 13
editor/editor_file_system.cpp

@@ -3027,9 +3027,9 @@ void EditorFileSystem::_refresh_filesystem() {
 }
 
 void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
-	int current_max = p_import_data->reimport_from + int(p_index);
-	p_import_data->max_index.exchange_if_greater(current_max);
-	_reimport_file(p_import_data->reimport_files[current_max].path);
+	int file_idx = p_import_data->reimport_from + int(p_index);
+	_reimport_file(p_import_data->reimport_files[file_idx].path);
+	p_import_data->imported_sem->post();
 }
 
 void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
@@ -3108,6 +3108,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 #endif
 
 	int from = 0;
+	Semaphore imported_sem;
 	for (int i = 0; i < reimport_files.size(); i++) {
 		if (groups_to_reimport.has(reimport_files[i].path)) {
 			from = i + 1;
@@ -3131,21 +3132,27 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 					importer->import_threaded_begin();
 
 					ImportThreadData tdata;
-					tdata.max_index.set(from);
 					tdata.reimport_from = from;
 					tdata.reimport_files = reimport_files.ptr();
-
-					WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &tdata, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer));
-					int current_index = from - 1;
-					do {
-						if (current_index < tdata.max_index.get()) {
-							current_index = tdata.max_index.get();
-							ep->step(reimport_files[current_index].path.get_file(), current_index, false);
+					tdata.imported_sem = &imported_sem;
+
+					int item_count = i - from + 1;
+					WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &tdata, item_count, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer));
+
+					int imported_count = 0;
+					while (true) {
+						ep->step(reimport_files[imported_count].path.get_file(), from + imported_count, false);
+						imported_sem.wait();
+						do {
+							imported_count++;
+						} while (imported_sem.try_wait());
+						if (imported_count == item_count) {
+							break;
 						}
-						OS::get_singleton()->delay_usec(1);
-					} while (!WorkerThreadPool::get_singleton()->is_group_task_completed(group_task));
+					}
 
 					WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
+					DEV_ASSERT(!imported_sem.try_wait());
 
 					importer->import_threaded_end();
 				}

+ 1 - 1
editor/editor_file_system.h

@@ -342,7 +342,7 @@ class EditorFileSystem : public Node {
 	struct ImportThreadData {
 		const ImportFile *reimport_files;
 		int reimport_from;
-		SafeNumeric<int> max_index;
+		Semaphore *imported_sem = nullptr;
 	};
 
 	void _reimport_thread(uint32_t p_index, ImportThreadData *p_import_data);

+ 1 - 3
editor/editor_log.cpp

@@ -398,9 +398,7 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
 	if (p_replace_previous) {
 		// Force sync last line update (skip if number of unprocessed log messages is too large to avoid editor lag).
 		if (log->get_pending_paragraphs() < 100) {
-			while (!log->is_finished()) {
-				::OS::get_singleton()->delay_usec(1);
-			}
+			log->wait_until_finished();
 		}
 	}
 

+ 0 - 1
editor/editor_node.cpp

@@ -5497,7 +5497,6 @@ bool EditorNode::immediate_confirmation_dialog(const String &p_text, const Strin
 	cd->popup_centered();
 
 	while (true) {
-		OS::get_singleton()->delay_usec(1);
 		DisplayServer::get_singleton()->process_events();
 		Main::iteration();
 		if (singleton->immediate_dialog_confirmed || !cd->is_visible()) {

+ 0 - 1
modules/gltf/editor/editor_scene_importer_blend.cpp

@@ -574,7 +574,6 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
 	confirmed = false;
 
 	while (true) {
-		OS::get_singleton()->delay_usec(1);
 		DisplayServer::get_singleton()->process_events();
 		Main::iteration();
 		if (!configure_blender_dialog->is_visible() || confirmed) {

+ 8 - 4
scene/gui/rich_text_label.cpp

@@ -2881,10 +2881,7 @@ void RichTextLabel::_thread_end() {
 void RichTextLabel::_stop_thread() {
 	if (threaded) {
 		stop_thread.store(true);
-		if (task != WorkerThreadPool::INVALID_TASK_ID) {
-			WorkerThreadPool::get_singleton()->wait_for_task_completion(task);
-			task = WorkerThreadPool::INVALID_TASK_ID;
-		}
+		wait_until_finished();
 	}
 }
 
@@ -2908,6 +2905,13 @@ bool RichTextLabel::is_updating() const {
 	return updating.load() || validating.load();
 }
 
+void RichTextLabel::wait_until_finished() {
+	if (task != WorkerThreadPool::INVALID_TASK_ID) {
+		WorkerThreadPool::get_singleton()->wait_for_task_completion(task);
+		task = WorkerThreadPool::INVALID_TASK_ID;
+	}
+}
+
 void RichTextLabel::set_threaded(bool p_threaded) {
 	if (threaded != p_threaded) {
 		_stop_thread();

+ 1 - 0
scene/gui/rich_text_label.h

@@ -809,6 +809,7 @@ public:
 	int get_pending_paragraphs() const;
 	bool is_finished() const;
 	bool is_updating() const;
+	void wait_until_finished();
 
 	void set_threaded(bool p_threaded);
 	bool is_threaded() const;