You've already forked godot
							
							
				mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 11:50:27 +00:00 
			
		
		
		
	Increase stack size for all secondary threads on Apple platforms
This commit is contained in:
		@@ -364,24 +364,12 @@ WorkerThreadPool::TaskID WorkerThreadPool::_add_task(const Callable &p_callable,
 | 
			
		||||
		if (pump_task_count >= thread_count) {
 | 
			
		||||
			print_verbose(vformat("A greater number of dedicated threads were requested (%d) than threads available (%d). Please increase the number of available worker task threads. Recovering this session by spawning more worker task threads.", pump_task_count + 1, thread_count)); // +1 because we want to keep a Thread without any pump tasks free.
 | 
			
		||||
 | 
			
		||||
			Thread::Settings settings;
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
			// The default stack size for new threads on Apple platforms is 512KiB.
 | 
			
		||||
			// This is insufficient when using a library like SPIRV-Cross,
 | 
			
		||||
			// which can generate deep stacks and result in a stack overflow.
 | 
			
		||||
#ifdef DEV_ENABLED
 | 
			
		||||
			// Debug builds need an even larger stack size.
 | 
			
		||||
			settings.stack_size = 2 * 1024 * 1024; // 2 MiB
 | 
			
		||||
#else
 | 
			
		||||
			settings.stack_size = 1 * 1024 * 1024; // 1 MiB
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
			// Re-sizing implies relocation, which is not supported for this array.
 | 
			
		||||
			CRASH_COND_MSG(thread_count + 1 > (int)threads.get_capacity(), "Reserve trick for worker thread pool failed. Crashing.");
 | 
			
		||||
			threads.resize_initialized(thread_count + 1);
 | 
			
		||||
			threads[thread_count].index = thread_count;
 | 
			
		||||
			threads[thread_count].pool = this;
 | 
			
		||||
			threads[thread_count].thread.start(&WorkerThreadPool::_thread_function, &threads[thread_count], settings);
 | 
			
		||||
			threads[thread_count].thread.start(&WorkerThreadPool::_thread_function, &threads[thread_count]);
 | 
			
		||||
			thread_ids.insert(threads[thread_count].thread.get_id(), thread_count);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -838,23 +826,10 @@ void WorkerThreadPool::init(int p_thread_count, float p_low_priority_task_ratio)
 | 
			
		||||
#endif
 | 
			
		||||
	threads.resize(p_thread_count);
 | 
			
		||||
 | 
			
		||||
	Thread::Settings settings;
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
	// The default stack size for new threads on Apple platforms is 512KiB.
 | 
			
		||||
	// This is insufficient when using a library like SPIRV-Cross,
 | 
			
		||||
	// which can generate deep stacks and result in a stack overflow.
 | 
			
		||||
#ifdef DEV_ENABLED
 | 
			
		||||
	// Debug builds need an even larger stack size.
 | 
			
		||||
	settings.stack_size = 2 * 1024 * 1024; // 2 MiB
 | 
			
		||||
#else
 | 
			
		||||
	settings.stack_size = 1 * 1024 * 1024; // 1 MiB
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	for (uint32_t i = 0; i < threads.size(); i++) {
 | 
			
		||||
		threads[i].index = i;
 | 
			
		||||
		threads[i].pool = this;
 | 
			
		||||
		threads[i].thread.start(&WorkerThreadPool::_thread_function, &threads[i], settings);
 | 
			
		||||
		threads[i].thread.start(&WorkerThreadPool::_thread_function, &threads[i]);
 | 
			
		||||
		thread_ids.insert(threads[i].thread.get_id(), i);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -92,9 +92,20 @@ Thread::ID Thread::start(Thread::Callback p_callback, void *p_user, const Settin
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (p_settings.stack_size > 0) {
 | 
			
		||||
		pthread_attr_setstacksize(&attr, p_settings.stack_size);
 | 
			
		||||
	}
 | 
			
		||||
	// The default stack size for secondary threads on Apple platforms is 512KiB.
 | 
			
		||||
	// This is insufficient when using a library like SPIRV-Cross, which can generate deep stacks and result in a stack overflow.
 | 
			
		||||
	// It also creates a problematic discrepancy with other platforms, where secondary threads are often at least 1 MiB.
 | 
			
		||||
	pthread_attr_setstacksize(&attr,
 | 
			
		||||
#if __has_feature(address_sanitizer) || __has_feature(thread_sanitizer)
 | 
			
		||||
			// ASan (and to some degree TSan) needs a lot of extra stack size.
 | 
			
		||||
			4 * 1024 * 1024 // 4 MiB
 | 
			
		||||
#elif !defined(__OPTIMIZE__)
 | 
			
		||||
			// Unoptimized builds also need a larger stack size.
 | 
			
		||||
			2 * 1024 * 1024 // 2 MiB
 | 
			
		||||
#else
 | 
			
		||||
			1 * 1024 * 1024 // 1 MiB
 | 
			
		||||
#endif
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// Create the thread
 | 
			
		||||
	pthread_create(&pthread, &attr, thread_callback, thread_data);
 | 
			
		||||
 
 | 
			
		||||
@@ -57,8 +57,6 @@ public:
 | 
			
		||||
 | 
			
		||||
	struct Settings {
 | 
			
		||||
		Priority priority;
 | 
			
		||||
		/// Override the default stack size (0 means default)
 | 
			
		||||
		uint64_t stack_size = 0;
 | 
			
		||||
		Settings() { priority = PRIORITY_NORMAL; }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user