@@ -438,31 +438,26 @@ int pthread_attr_destroy(pthread_attr_t *a)
438
438
439
439
#endif
440
440
441
-
442
- void
443
- _Py_InitializeRecursionLimits (PyThreadState * tstate )
441
+ static void
442
+ hardware_stack_limits (uintptr_t * top , uintptr_t * base )
444
443
{
445
- _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
446
444
#ifdef WIN32
447
445
ULONG_PTR low , high ;
448
446
GetCurrentThreadStackLimits (& low , & high );
449
- _tstate -> c_stack_top = (uintptr_t )high ;
447
+ * top = (uintptr_t )high ;
450
448
ULONG guarantee = 0 ;
451
449
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 ;
454
451
#elif defined(__APPLE__ )
455
452
pthread_t this_thread = pthread_self ();
456
453
void * stack_addr = pthread_get_stackaddr_np (this_thread ); // top of the stack
457
454
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 ;
461
457
#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.)
466
461
# if defined(HAVE_PTHREAD_GETATTR_NP ) && !defined(_AIX ) && \
467
462
!defined(__NetBSD__ ) && (defined(__GLIBC__ ) || !defined(__linux__ ))
468
463
size_t stack_size , guard_size ;
@@ -475,26 +470,35 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
475
470
err |= pthread_attr_destroy (& attr );
476
471
}
477
472
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 ;
489
475
return ;
490
476
}
491
477
# 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 ;
495
482
#endif
496
483
}
497
484
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
+
498
502
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
499
503
if the recursion_depth reaches recursion_limit. */
500
504
int
0 commit comments