Skip to content

Commit ebb9960

Browse files
committed
Fix get_stack_base in linux
In case of pthread_attr_getstack() returns np_stack_size = 1MB, - calculated stack_base = stack_limit + stack_size(default: 4MB) - real stack_base = stack_limit + np_stack_size(1MB) stack_base is wrong because calculated with 4MB default stack size. Due to this wrong stack_base, task_dispatcher::can_steal() can be always false. It causes abnormal long loop in task_dispatcher::receive_or_steal_task(). Correct stack_size by pthread_attr_getstacksize() in linux. Signed-off-by: Bongkyu Kim <[email protected]>
1 parent ad9e324 commit ebb9960

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

src/tbb/governor.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,22 @@ static std::uintptr_t get_stack_base(std::size_t stack_size) {
192192
#endif /* __TBB_USE_WINAPI */
193193
}
194194

195+
static std::size_t get_stack_size(arena &a) {
196+
#if __linux__ && !__bg__
197+
size_t np_stack_size = 0;
198+
pthread_attr_t np_attr_stack;
199+
if (0 == pthread_getattr_np(pthread_self(), &np_attr_stack)) {
200+
if (0 == pthread_attr_getstacksize(&np_attr_stack, &np_stack_size)) {
201+
__TBB_ASSERT( np_stack_size > 0, "stack size must be positive" );
202+
}
203+
pthread_attr_destroy(&np_attr_stack);
204+
}
205+
return np_stack_size > 0 ? np_stack_size : a.my_threading_control->worker_stack_size();
206+
#else
207+
return a.my_threading_control->worker_stack_size();
208+
#endif
209+
}
210+
195211
#if (_WIN32||_WIN64) && !__TBB_DYNAMIC_LOAD_ENABLED
196212
static void register_external_thread_destructor() {
197213
struct thread_destructor {
@@ -219,7 +235,7 @@ void governor::init_external_thread() {
219235
td.attach_arena(a, /*slot index*/ 0);
220236
__TBB_ASSERT(td.my_inbox.is_idle_state(false), nullptr);
221237

222-
stack_size = a.my_threading_control->worker_stack_size();
238+
stack_size = get_stack_size(a);
223239
std::uintptr_t stack_base = get_stack_base(stack_size);
224240
task_dispatcher& task_disp = td.my_arena_slot->default_task_dispatcher();
225241
td.enter_task_dispatcher(task_disp, calculate_stealing_threshold(stack_base, stack_size));

0 commit comments

Comments
 (0)