// Called from the __bionic_clone assembler to call the thread function then exit.
__attribute__((no_sanitize("hwaddress"))) extern"C" __LIBC_HIDDEN__ void __start_thread(int (*fn)(void*), void* arg) {
BIONIC_STOP_UNWIND;
staticinline clone_id_info clone_prologue(int flags) { // Remember the parent pid and invalidate the cached value while we clone.
pthread_internal_t* self = __get_thread();
pid_t parent_pid = self->invalidate_cached_pid();
// Remmber the caller's tid so that it can be restored in the parent after clone.
pid_t caller_tid = self->tid; // Invalidate the tid before the syscall. The value is lazily cached in gettid(), // and it will be updated by fork() and pthread_create(). We don't do this if // we are sharing address space with the child. if (!(flags & (CLONE_VM | CLONE_VFORK))) {
self->tid = -1;
}
#ifdefined(__aarch64__) // AAPCS64 defines SME ZA interface as private for clone(), which means that ZA state on entry // can be "dormant" or "off", while on return it can be unchanged or "off". // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#za-interfaces // Handling the dormant state would make the code unnecessary complex, so for simplicity turn // ZA state off on entry which ensures that the state on return will be "off" as well.
__arm_za_disable(); #endif
return {self, parent_pid, caller_tid};
}
staticinlineint clone_epilogue(clone_id_info& ciinfo, int clone_result) { if (clone_result != 0) { // We're the parent, so put our known pid and tid back in place. // We leave the child without a cached pid and tid, but: // 1. pthread_create gives its children their own pthread_internal_t with the correct pid and // tid. // 2. fork uses CLONE_CHILD_SETTID to get the new pid/tid. // 3. The tid is lazily fetched in gettid(). // If any other cases become important, we could use a double trampoline like __pthread_start.
ciinfo.self->tid = ciinfo.caller_tid;
ciinfo.self->set_cached_pid(ciinfo.parent_pid);
} elseif (ciinfo.self->tid == -1) {
ciinfo.self->tid = syscall(__NR_gettid);
ciinfo.self->set_cached_pid(ciinfo.self->tid);
}
int clone_result; if (fn != nullptr) { // This call does not return in the child process.
clone_result = __bionic_clone3(cl_args, size, fn, arg);
} else {
clone_result = syscall(SYS_clone3, cl_args, size);
}
return clone_epilogue(ciinfo, clone_result);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 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.