🧵 Summary:
you could find the full code here
Base init
struct pthread *pd;
size_t size;
size_t pagesize_m1 = __getpagesize () - 1; // 4096
size_t tls_static_size_for_stack = __nptl_tls_static_size_for_stack ();
size_t tls_static_align_m1 = GLRO (dl_tls_static_align) - 1;
assert (powerof2 (pagesize_m1 + 1));
assert (TCB_ALIGNMENT >= STACK_ALIGN);
the __getpagesize
on x86_64 just return an hard coded value of 4096
i would of thought this was base on the cpuid
the __nptl_tls_static_size_for_stack()
is set at the end of the libc in the __libc_setup_tls()
with the function init_static_tls()
this will init the tls
stack size
/* Get the stack size from the attribute if it is set. Otherwise we
use the default we determined at start time. */
if (attr->stacksize != 0)
size = attr->stacksize;
else
{
lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
size = __default_pthread_attr.internal.stacksize;
lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
}
Explanation:
This snippet retrieves the desired stack size for a new thread:
- If the caller has set a custom stack size via
pthread_attr_setstacksize
, it uses that. - Otherwise, it safely falls back to a global default.
This fallback is mostly a safeguard: the default stack size is typically set by
init_pthread_attr()
or through the defaultpthread_attr_t
object used by the main thread.
See part 2 – Thread Attribute Handling for where the default is initialized.
Get memory for the stack
In this section, I’ll only cover the standard path—the
else
branch of the allocation logic. I’m skipping theif (attr->flags & ATTR_FLAG_STACKADDR)
case for now, which handles user-provided stacks; I might revisit it later.Note: We’ll assume
TLS_TCB_AT_TP
, which is the default for modern platforms like x86_64 and AArch64. and other 64 byte system
memory plage