// Call the cleanup handlers. while (thread->cleanup_stack) {
__pthread_cleanup_t* c = thread->cleanup_stack;
thread->cleanup_stack = c->__cleanup_prev;
c->__cleanup_routine(c->__cleanup_arg);
}
// Call the TLS destructors. It is important to do that before removing this // thread from the global list. This will ensure that if someone else deletes // a TLS key, the corresponding value will be set to NULL in this thread's TLS // space (see pthread_key_delete).
pthread_key_clean_all();
if (thread->alternate_signal_stack != nullptr) { // Tell the kernel to stop using the alternate signal stack.
stack_t ss = {};
ss.ss_flags = SS_DISABLE;
sigaltstack(&ss, nullptr);
// Free it.
munmap(thread->alternate_signal_stack, SIGNAL_STACK_SIZE);
thread->alternate_signal_stack = nullptr;
}
// android_run_on_all_threads() needs to see signals blocked atomically with setting the // terminating flag, so take the creation lock while doing these operations.
{
ScopedReadLock locker(&g_thread_creation_lock);
atomic_store(&thread->terminating, true);
// We don't want to take a signal after unmapping the stack, the shadow call stack, or dynamic // TLS memory.
sigset64_t set;
sigfillset64(&set);
__rt_sigprocmask(SIG_BLOCK, &set, nullptr, sizeof(sigset64_t));
}
#ifdefined(__aarch64__) || defined(__riscv) // Free the shadow call stack and guard pages.
munmap(thread->shadow_call_stack_guard_region, SCS_GUARD_REGION_SIZE); #endif
__free_dynamic_tls(__get_bionic_tcb());
if (old_state == THREAD_DETACHED) { // The thread is detached, no one will use pthread_internal_t after pthread_exit. // So we can free mapped space, which includes pthread_internal_t and thread stack. // First make sure that the kernel does not try to clear the tid field // because we'll have freed the memory before the thread actually exits.
__set_tid_address(nullptr);
// pthread_internal_t is freed below with stack, not here.
__pthread_internal_remove(thread);
}
#ifdefined(__aarch64__) if (void* stack_mte_tls = thread->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE)) {
stack_mte_free_ringbuffer(reinterpret_cast<uintptr_t>(stack_mte_tls));
} #endif // Everything below this line needs to be no_sanitize("memtag").
if (old_state == THREAD_DETACHED && thread->mmap_size != 0) { // We need to free mapped space for detached threads when they exit. // That's not something we can do in C.
_exit_with_stack_teardown(thread->mmap_base, thread->mmap_size);
} // No need to free mapped space. Either there was no space mapped, // or it is left for the pthread_join caller to clean up.
__exit(0);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.