From 09b2b6c2558bc46378a3d5838f4dcebeb870c236 Mon Sep 17 00:00:00 2001 From: Alexei Katranov Date: Mon, 30 Aug 2021 12:53:20 +0300 Subject: [PATCH 1/3] Fix stack size calculation Signed-off-by: Alexei Katranov --- src/tbb/global_control.cpp | 9 +++++++++ src/tbb/governor.cpp | 4 ++-- src/tbb/misc.h | 8 +++----- src/tbb/scheduler_common.h | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/tbb/global_control.cpp b/src/tbb/global_control.cpp index 20ab26204d..084d79b31a 100644 --- a/src/tbb/global_control.cpp +++ b/src/tbb/global_control.cpp @@ -89,7 +89,16 @@ class alignas(max_nfs_size) allowed_parallelism_control : public control_storage class alignas(max_nfs_size) stack_size_control : public control_storage { std::size_t default_value() const override { +#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ + static auto ThreadStackSizeDefault = [] { + ULONG_PTR hi, lo; + GetCurrentThreadStackLimits(&lo, &hi); + return std::size_t(hi - lo); + }(); + return ThreadStackSizeDefault; +#else return ThreadStackSize; +#endif } void apply_active(std::size_t new_active) override { control_storage::apply_active(new_active); diff --git a/src/tbb/governor.cpp b/src/tbb/governor.cpp index 9238b839d5..bb8ab58420 100644 --- a/src/tbb/governor.cpp +++ b/src/tbb/governor.cpp @@ -132,11 +132,11 @@ void governor::one_time_init() { static std::uintptr_t get_stack_base(std::size_t stack_size) { // Stacks are growing top-down. Highest address is called "stack base", // and the lowest is "stack limit". -#if USE_WINTHREAD +#if __TBB_USE_WINAPI suppress_unused_warning(stack_size); NT_TIB* pteb = (NT_TIB*)NtCurrentTeb(); __TBB_ASSERT(&pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB"); - return pteb->StackBase; + return std::uintptr_t(pteb->StackBase); #else /* USE_PTHREAD */ // There is no portable way to get stack base address in Posix, so we use // non-portable method (on all modern Linux) or the simplified approach diff --git a/src/tbb/misc.h b/src/tbb/misc.h index 2e78eab2cb..597498df17 100644 --- a/src/tbb/misc.h +++ b/src/tbb/misc.h @@ -53,11 +53,9 @@ class task_scheduler_observer; const std::size_t MByte = 1024*1024; -#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) -// In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API -// that does not allow to specify the stack size. -// Still, the thread stack size value, either explicit or default, is used by the scheduler. -// So here we set the default value to match the platform's default of 1MB. +#if __TBB_USE_WINAPI +// The Microsoft Documentation about Thread Stack Size states that +// "The default stack reservation size used by the linker is 1 MB" const std::size_t ThreadStackSize = 1*MByte; #else const std::size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte; diff --git a/src/tbb/scheduler_common.h b/src/tbb/scheduler_common.h index 76ad1e776b..45f4c66986 100644 --- a/src/tbb/scheduler_common.h +++ b/src/tbb/scheduler_common.h @@ -488,6 +488,7 @@ class alignas (max_nfs_size) task_dispatcher { #endif inline std::uintptr_t calculate_stealing_threshold(std::uintptr_t base, std::size_t stack_size) { + __TBB_ASSERT(base > stack_size / 2, "Stack anchor calculation overflow"); return base - stack_size / 2; } From c61911f24af30337ca4b36186e200a16a16e359b Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 19 Nov 2021 13:12:40 +0300 Subject: [PATCH 2/3] Update src/tbb/governor.cpp Co-authored-by: Anton Potapov --- src/tbb/governor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tbb/governor.cpp b/src/tbb/governor.cpp index bb8ab58420..b2bf9bcdb1 100644 --- a/src/tbb/governor.cpp +++ b/src/tbb/governor.cpp @@ -136,7 +136,7 @@ static std::uintptr_t get_stack_base(std::size_t stack_size) { suppress_unused_warning(stack_size); NT_TIB* pteb = (NT_TIB*)NtCurrentTeb(); __TBB_ASSERT(&pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB"); - return std::uintptr_t(pteb->StackBase); + return reinterpret_cast(pteb->StackBase); #else /* USE_PTHREAD */ // There is no portable way to get stack base address in Posix, so we use // non-portable method (on all modern Linux) or the simplified approach From 384fc99f5c7382ddbedd2360d52e8123605d2686 Mon Sep 17 00:00:00 2001 From: Alexei Katranov Date: Fri, 19 Nov 2021 13:29:03 +0300 Subject: [PATCH 3/3] Apply review remarks Signed-off-by: Alexei Katranov --- src/tbb/global_control.cpp | 2 +- src/tbb/governor.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tbb/global_control.cpp b/src/tbb/global_control.cpp index 084d79b31a..29ef9ae043 100644 --- a/src/tbb/global_control.cpp +++ b/src/tbb/global_control.cpp @@ -93,7 +93,7 @@ class alignas(max_nfs_size) stack_size_control : public control_storage { static auto ThreadStackSizeDefault = [] { ULONG_PTR hi, lo; GetCurrentThreadStackLimits(&lo, &hi); - return std::size_t(hi - lo); + return hi - lo; }(); return ThreadStackSizeDefault; #else diff --git a/src/tbb/governor.cpp b/src/tbb/governor.cpp index b2bf9bcdb1..ddea7a43d5 100644 --- a/src/tbb/governor.cpp +++ b/src/tbb/governor.cpp @@ -137,7 +137,7 @@ static std::uintptr_t get_stack_base(std::size_t stack_size) { NT_TIB* pteb = (NT_TIB*)NtCurrentTeb(); __TBB_ASSERT(&pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB"); return reinterpret_cast(pteb->StackBase); -#else /* USE_PTHREAD */ +#else // There is no portable way to get stack base address in Posix, so we use // non-portable method (on all modern Linux) or the simplified approach // based on the common sense assumptions. The most important assumption @@ -164,7 +164,7 @@ static std::uintptr_t get_stack_base(std::size_t stack_size) { stack_base = reinterpret_cast(&anchor); } return stack_base; -#endif /* USE_PTHREAD */ +#endif /* __TBB_USE_WINAPI */ } #if (_WIN32||_WIN64) && !__TBB_DYNAMIC_LOAD_ENABLED