@@ -438,31 +438,26 @@ int pthread_attr_destroy(pthread_attr_t *a)
438438
439439#endif
440440
441-
442- void
443- _Py_InitializeRecursionLimits (PyThreadState * tstate )
441+ static void
442+ hardware_stack_limits (uintptr_t * top , uintptr_t * base )
444443{
445- _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
446444#ifdef WIN32
447445 ULONG_PTR low , high ;
448446 GetCurrentThreadStackLimits (& low , & high );
449- _tstate -> c_stack_top = (uintptr_t )high ;
447+ * top = (uintptr_t )high ;
450448 ULONG guarantee = 0 ;
451449 SetThreadStackGuarantee (& guarantee );
452- _tstate -> c_stack_hard_limit = ((uintptr_t )low ) + guarantee + _PyOS_STACK_MARGIN_BYTES ;
453- _tstate -> c_stack_soft_limit = _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES ;
450+ * base = (uintptr_t )low + guarantee ;
454451#elif defined(__APPLE__ )
455452 pthread_t this_thread = pthread_self ();
456453 void * stack_addr = pthread_get_stackaddr_np (this_thread ); // top of the stack
457454 size_t stack_size = pthread_get_stacksize_np (this_thread );
458- _tstate -> c_stack_top = (uintptr_t )stack_addr ;
459- _tstate -> c_stack_hard_limit = _tstate -> c_stack_top - stack_size ;
460- _tstate -> c_stack_soft_limit = _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES ;
455+ * top = (uintptr_t )stack_addr ;
456+ * base = ((uintptr_t )stack_addr ) - stack_size ;
461457#else
462- uintptr_t here_addr = _Py_get_machine_stack_pointer ();
463- /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size
464- /// (on alpine at least) is much smaller than expected and imposes undue limits
465- /// compared to the old stack size estimation. (We assume musl is not glibc.)
458+ /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size
459+ /// (on alpine at least) is much smaller than expected and imposes undue limits
460+ /// compared to the old stack size estimation. (We assume musl is not glibc.)
466461# if defined(HAVE_PTHREAD_GETATTR_NP ) && !defined(_AIX ) && \
467462 !defined(__NetBSD__ ) && (defined(__GLIBC__ ) || !defined(__linux__ ))
468463 size_t stack_size , guard_size ;
@@ -475,26 +470,35 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
475470 err |= pthread_attr_destroy (& attr );
476471 }
477472 if (err == 0 ) {
478- uintptr_t base = ((uintptr_t )stack_addr ) + guard_size ;
479- _tstate -> c_stack_top = base + stack_size ;
480- #ifdef _Py_THREAD_SANITIZER
481- // Thread sanitizer crashes if we use a bit more than half the stack.
482- _tstate -> c_stack_soft_limit = base + (stack_size / 2 );
483- #else
484- _tstate -> c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2 ;
485- #endif
486- _tstate -> c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES ;
487- assert (_tstate -> c_stack_soft_limit < here_addr );
488- assert (here_addr < _tstate -> c_stack_top );
473+ * base = ((uintptr_t )stack_addr ) + guard_size ;
474+ * top = (uintptr_t )stack_addr + stack_size ;
489475 return ;
490476 }
491477# endif
492- _tstate -> c_stack_top = _Py_SIZE_ROUND_UP (here_addr , 4096 );
493- _tstate -> c_stack_soft_limit = _tstate -> c_stack_top - Py_C_STACK_SIZE ;
494- _tstate -> c_stack_hard_limit = _tstate -> c_stack_top - (Py_C_STACK_SIZE + _PyOS_STACK_MARGIN_BYTES );
478+ uintptr_t here_addr = _Py_get_machine_stack_pointer ();
479+ uintptr_t top_addr = _Py_SIZE_ROUND_UP (here_addr , 4096 );
480+ * top = top_addr ;
481+ * base = top_addr - Py_C_STACK_SIZE ;
495482#endif
496483}
497484
485+ void
486+ _Py_InitializeRecursionLimits (PyThreadState * tstate )
487+ {
488+ uintptr_t top ;
489+ uintptr_t base ;
490+ hardware_stack_limits (& top , & base );
491+ #ifdef _Py_THREAD_SANITIZER
492+ // Thread sanitizer crashes if we use more than half the stack.
493+ uintptr_t stacksize = top - base ;
494+ base += stacksize /2 ;
495+ #endif
496+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
497+ _tstate -> c_stack_top = top ;
498+ _tstate -> c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES ;
499+ _tstate -> c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2 ;
500+ }
501+
498502/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
499503 if the recursion_depth reaches recursion_limit. */
500504int
0 commit comments