[libc-commits] [libc] Reland "[libc] Implement clone(2) and use it in thread spawning" (PR #225384)

via libc-commits libc-commits at lists.llvm.org
Tue Sep 22 05:30:12 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Pavel Labath (labath)

<details>
<summary>Changes</summary>

This commit reverts 35006688eb78eb5b601e282d21701f430d737888/#<!-- -->225111, reapplying 9028ff14b18ea678683a4960306051044160bb67/#<!-- -->224257. It fixes an error in risc-v assembly (forgot to adjust for constant renaming).

The original commit message was:

This patch implements an internal clone syscall wrapper and uses it both to implement the public clone(2) entry point and to spawn new threads in libc's thread implementation.

Previously, thread creation in thread.cpp invoked the raw SYS_clone syscall directly, requiring target-specific inline assembly or register variables and subtle tricks with __builtin_frame_address to pass arguments to start_thread in the newly spawned thread.

By introducing an inline assembly clone wrapper that sets up func and arg on the child stack and jumps to the entry function upon clone returning in the child, we can simplify start_thread to a normal function taking a single void * argument and eliminate the frame pointer hacks as well as the need to compile thread.cpp with -fno-omit-frame-pointer or optimizations.

The public clone(2) entrypoint delegates to this wrapper after unpacking its varargs and validating pointers (returning EINVAL like glibc).

A particularly tricky aspect of this patch is the invalidation of the cached thread IDs. As with fork(), we do this in the parent, but we cannot do this safely for clone() in all situations. The problematic case is where the user does not set a custom TLS block (which means the child uses the parent's block), does not clone the address space (no copy-on-write), and does not suspend the parent (vfork semantics). In this case, we just give up and don't touch the thread ID. For this particular flag, most of the operations in the child are not safe, so we're assuming the user is prepared for such a restricted environment.

Support is implemented for x86_64, aarch64, and riscv. The architecture-specific assembly is split out into detail::clone_impl inside per-architecture headers.

Assisted-by: Gemini

---
Full diff: https://github.com/llvm/llvm-project/pull/225384.diff


20 Files Affected:

- (modified) libc/config/linux/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+1) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1) 
- (modified) libc/include/sched.yaml (+11) 
- (modified) libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt (+22) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/aarch64/clone.h (+60) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/clone.h (+72) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/riscv/clone.h (+68) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/x86_64/clone.h (+60) 
- (modified) libc/src/__support/threads/linux/CMakeLists.txt (+1-4) 
- (modified) libc/src/__support/threads/linux/thread.cpp (+20-91) 
- (modified) libc/src/pthread/CMakeLists.txt (-3) 
- (modified) libc/src/sched/CMakeLists.txt (+7) 
- (added) libc/src/sched/clone.h (+42) 
- (modified) libc/src/sched/linux/CMakeLists.txt (+18) 
- (added) libc/src/sched/linux/clone.cpp (+88) 
- (modified) libc/src/threads/CMakeLists.txt (-4) 
- (modified) libc/test/src/sched/CMakeLists.txt (+4) 
- (added) libc/test/src/sched/linux/CMakeLists.txt (+22) 
- (added) libc/test/src/sched/linux/clone_test.cpp (+194) 


``````````diff
The server is unavailable at this time. Please wait a few minutes before you try again.
``````````

</details>


https://github.com/llvm/llvm-project/pull/225384


More information about the libc-commits mailing list