mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 23:21:15 +00:00 
			
		
		
		
	Merge pull request #98385 from RandomShaper/thread_yield
Rationalize busy waits
This commit is contained in:
		
						commit
						8a743f23e6
					
				
					 7 changed files with 30 additions and 22 deletions
				
			
		| 
						 | 
					@ -3027,9 +3027,9 @@ void EditorFileSystem::_refresh_filesystem() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
 | 
					void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
 | 
				
			||||||
	int current_max = p_import_data->reimport_from + int(p_index);
 | 
						int file_idx = 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[file_idx].path);
 | 
				
			||||||
	_reimport_file(p_import_data->reimport_files[current_max].path);
 | 
						p_import_data->imported_sem->post();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 | 
					void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 | 
				
			||||||
| 
						 | 
					@ -3108,6 +3108,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int from = 0;
 | 
						int from = 0;
 | 
				
			||||||
 | 
						Semaphore imported_sem;
 | 
				
			||||||
	for (int i = 0; i < reimport_files.size(); i++) {
 | 
						for (int i = 0; i < reimport_files.size(); i++) {
 | 
				
			||||||
		if (groups_to_reimport.has(reimport_files[i].path)) {
 | 
							if (groups_to_reimport.has(reimport_files[i].path)) {
 | 
				
			||||||
			from = i + 1;
 | 
								from = i + 1;
 | 
				
			||||||
| 
						 | 
					@ -3131,21 +3132,27 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 | 
				
			||||||
					importer->import_threaded_begin();
 | 
										importer->import_threaded_begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					ImportThreadData tdata;
 | 
										ImportThreadData tdata;
 | 
				
			||||||
					tdata.max_index.set(from);
 | 
					 | 
				
			||||||
					tdata.reimport_from = from;
 | 
										tdata.reimport_from = from;
 | 
				
			||||||
					tdata.reimport_files = reimport_files.ptr();
 | 
										tdata.reimport_files = reimport_files.ptr();
 | 
				
			||||||
 | 
										tdata.imported_sem = &imported_sem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					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 item_count = i - from + 1;
 | 
				
			||||||
					int current_index = 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 {
 | 
											do {
 | 
				
			||||||
						if (current_index < tdata.max_index.get()) {
 | 
												imported_count++;
 | 
				
			||||||
							current_index = tdata.max_index.get();
 | 
											} while (imported_sem.try_wait());
 | 
				
			||||||
							ep->step(reimport_files[current_index].path.get_file(), current_index, false);
 | 
											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);
 | 
										WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
 | 
				
			||||||
 | 
										DEV_ASSERT(!imported_sem.try_wait());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					importer->import_threaded_end();
 | 
										importer->import_threaded_end();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -342,7 +342,7 @@ class EditorFileSystem : public Node {
 | 
				
			||||||
	struct ImportThreadData {
 | 
						struct ImportThreadData {
 | 
				
			||||||
		const ImportFile *reimport_files;
 | 
							const ImportFile *reimport_files;
 | 
				
			||||||
		int reimport_from;
 | 
							int reimport_from;
 | 
				
			||||||
		SafeNumeric<int> max_index;
 | 
							Semaphore *imported_sem = nullptr;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void _reimport_thread(uint32_t p_index, ImportThreadData *p_import_data);
 | 
						void _reimport_thread(uint32_t p_index, ImportThreadData *p_import_data);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -398,9 +398,7 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
 | 
				
			||||||
	if (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).
 | 
							// 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) {
 | 
							if (log->get_pending_paragraphs() < 100) {
 | 
				
			||||||
			while (!log->is_finished()) {
 | 
								log->wait_until_finished();
 | 
				
			||||||
				::OS::get_singleton()->delay_usec(1);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5497,7 +5497,6 @@ bool EditorNode::immediate_confirmation_dialog(const String &p_text, const Strin
 | 
				
			||||||
	cd->popup_centered();
 | 
						cd->popup_centered();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true) {
 | 
						while (true) {
 | 
				
			||||||
		OS::get_singleton()->delay_usec(1);
 | 
					 | 
				
			||||||
		DisplayServer::get_singleton()->process_events();
 | 
							DisplayServer::get_singleton()->process_events();
 | 
				
			||||||
		Main::iteration();
 | 
							Main::iteration();
 | 
				
			||||||
		if (singleton->immediate_dialog_confirmed || !cd->is_visible()) {
 | 
							if (singleton->immediate_dialog_confirmed || !cd->is_visible()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,7 +574,6 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
 | 
				
			||||||
	confirmed = false;
 | 
						confirmed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true) {
 | 
						while (true) {
 | 
				
			||||||
		OS::get_singleton()->delay_usec(1);
 | 
					 | 
				
			||||||
		DisplayServer::get_singleton()->process_events();
 | 
							DisplayServer::get_singleton()->process_events();
 | 
				
			||||||
		Main::iteration();
 | 
							Main::iteration();
 | 
				
			||||||
		if (!configure_blender_dialog->is_visible() || confirmed) {
 | 
							if (!configure_blender_dialog->is_visible() || confirmed) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2881,10 +2881,7 @@ void RichTextLabel::_thread_end() {
 | 
				
			||||||
void RichTextLabel::_stop_thread() {
 | 
					void RichTextLabel::_stop_thread() {
 | 
				
			||||||
	if (threaded) {
 | 
						if (threaded) {
 | 
				
			||||||
		stop_thread.store(true);
 | 
							stop_thread.store(true);
 | 
				
			||||||
		if (task != WorkerThreadPool::INVALID_TASK_ID) {
 | 
							wait_until_finished();
 | 
				
			||||||
			WorkerThreadPool::get_singleton()->wait_for_task_completion(task);
 | 
					 | 
				
			||||||
			task = WorkerThreadPool::INVALID_TASK_ID;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2908,6 +2905,13 @@ bool RichTextLabel::is_updating() const {
 | 
				
			||||||
	return updating.load() || validating.load();
 | 
						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) {
 | 
					void RichTextLabel::set_threaded(bool p_threaded) {
 | 
				
			||||||
	if (threaded != p_threaded) {
 | 
						if (threaded != p_threaded) {
 | 
				
			||||||
		_stop_thread();
 | 
							_stop_thread();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -809,6 +809,7 @@ public:
 | 
				
			||||||
	int get_pending_paragraphs() const;
 | 
						int get_pending_paragraphs() const;
 | 
				
			||||||
	bool is_finished() const;
 | 
						bool is_finished() const;
 | 
				
			||||||
	bool is_updating() const;
 | 
						bool is_updating() const;
 | 
				
			||||||
 | 
						void wait_until_finished();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void set_threaded(bool p_threaded);
 | 
						void set_threaded(bool p_threaded);
 | 
				
			||||||
	bool is_threaded() const;
 | 
						bool is_threaded() const;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue