diff --git a/src/tbb/global_control.cpp b/src/tbb/global_control.cpp index 20ab26204d..29ef9ae043 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 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..ddea7a43d5 100644 --- a/src/tbb/governor.cpp +++ b/src/tbb/governor.cpp @@ -132,12 +132,12 @@ 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; -#else /* USE_PTHREAD */ + return reinterpret_cast(pteb->StackBase); +#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 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; }