Add EXPECT_STREQ and ASSERT_STREQ macros to IntegrationTest/test.h using
cpp::string_view. Note that, unlike the unit test macro (but like
googletest), this version treats NULL as distinct from "". The
inconsistency is unfortunate, but I think it's important as the code is
used for testing functions like getenv(), where "" and NULL have very
different meanings.
We should probably follow this up with a change to make the unit test
macro behave the same way.
Update integration tests to use the new macros instead of handrolled
string equality functions (my_streq), strcmp, inline_strcmp, or
string_view wrappers.
Added the POSIX putenv() function and its internal support.
Implemented EnvironmentManager::put() to insert caller-provided
"name=value" strings directly into the environment array, managing
ownership correctly (caller retains ownership).
Registered for x86_64, aarch64, and riscv. Integration tests cover basic
operations, ownership semantics, validation, and edge cases.
Assisted-by: Automated tooling, human reviewed.
Resolved compiler warnings in several libc unit and integration tests:
- Fixed -Wmissing-designated-field-initializers in localtime_r_test.cpp
by using zero-initialisation instead of partial designated initialisers.
- Fixed -Wimplicit-int-conversion in sigaltstack_test.cpp by explicitly
casting the loop index to uint8_t.
- Fixed -Wunused-parameter in pthread_barrier_test.cpp by omitting
unused parameter names in function definitions.
Assisted-by: Automated tooling, human reviewed.
Synchronised child thread execution in pthread_setschedparam_test using
a mutex lock. This prevents race conditions where the child thread
exited before scheduling parameter assertions ran on multi-core
platforms such as aarch64.
Added missing pthread target dependencies to CMakeLists.txt.
Assisted-by: Automated tooling, human reviewed.
Implemented the pthread_setschedparam and pthread_getschedparam
functions.
Added Linux syscall wrappers:
* sched_setscheduler
* sched_getscheduler
* sched_getparam
Updated the Thread class to support getting and setting scheduling
parameters.
Added integration tests to verify the implementation.
Assisted-by: Automated tooling, human reviewed.
and replace with granular includes of type/macro proxy headers -- where
those headers exist. I'm leaving the creation of new proxy headers for
another patch.
Assisted by Gemini.
Added the POSIX unsetenv() function and its internal support.
Implemented EnvironmentManager::unset() to remove a variable by name,
free the string if allocated, and compact the array.
Updated EnvironmentManager to synchronize the public global environ
pointer when transitioning to managed storage.
Registered for x86_64, aarch64, and riscv. Integration tests cover basic
operations and edge cases.
Assisted-by: Automated tooling, human reviewed.
fix#203411.
This PR addresses the problem that `EAGAIN` may be treated as timeout in
mutex and rwlock. Two changes are applied:
1. timeout sites always explicitly check for timeout now to make the
logic more robust;
2. the futex wait now discards the error of `EAGAIN/EWOULDBLOCK` and
returns 0;
We don't distinguish waking up from signal and waking up from mismatch
for the following 3 reasons:
- We have userspace guard to avoid futex syscall if we already know
value would match, it seems awkward to make that check returns error, as
we may wake up and loop back to the check, where signal is consumed but
we still return error....;
- futex syscall can spuriously wake up anyway, there is no way to tell
whether the signal is "indeed" consumed;
- other platforms like darwin does not distinguish these states either.
Assisted-by: Gemini powered automation tools (human-in-the-loop).
Some of these requests are architecture specific, and linux/ptrace.h is
pretty clean, so I'm including it for all the constants definitions
(this matches bionic, but not musl or glibc).
There's one unfortunate rename that we need to fix up (kernel uses
PTRACE_PEEKUSR, without the *E*), and (matching all libc
implementations) I also add the BSD-compatibility names for the basic
requests (although the usefulness if this is questionable as nearly
everything about ptrace is OS-specific).
Some of the options structs also have a different name in the kernel
headers (ptrace_peeksiginfo_args) and glibc (__ptrace_peeksiginfo_args),
but:
- these are very scarcely used, and
- the manpage actually documents the kernel names
which is why I'm hoping we can get away with this.
The ptrace entry point implements the standard PTRACE_PEEK translation
from by-ptr arguments to return values.
---------
Co-authored-by: Jeff Bailey <jbailey@raspberryginger.com>
This function is more complicated than your average syscall wrapper,
which is why this PR is mainly about setting up the infrastructure. I've
made this an experimental entry point, as the only request it handles is
PTRACE_TRACEME.
I also added a test to verify the PTRACE_TRACEME behavior. It's an
integration test as anything ptrace-y requires two processes.
Assisted by Gemini.
Move the `fixedbuffer` GPU test to an integration test.
libc tests are intended to be GTest style tests written with the normal
`TEST(Suite, Test)` GTest macros. Example
[here](https://github.com/llvm/llvm-project/blob/main/libc/test/include/SignbitTest.h#L32).
This test has its own `main` which ends up causing a `main multiple
definitions` linker error when compiling for SPIR-V (work in progress).
I'm not sure why this error doesn't occur for AMDGPU, probably the fact
we have to compile with a ton less compile/linker flags for SPIR-V and
one of them hides the issue.
Specifically the fix is that we don't link against
`libc/test/UnitTest/CMakeFiles/LibcTest.hermetic.dir/LibcTestMain.cpp.o`
which has its own main which conflicts with the one defined in the test.
All other tests in this directory are integration tests too.
A quick check of other uses of the `TEST_MAIN` macro also showed them
using `add_integration_test` and not `add_libc_test`.
Signed-off-by: Nick Sarnie <nick.sarnie@intel.com>
Reverts the experimental gating of sysconf introduced in 1d93fc4f74
and restores it to the Scudo integration test entrypoints (undoing
8257855f77).
sysconf works correctly for the constants it handles. Moving it behind
the experimental flag broke the Scudo build since Scudo calls
sysconf(_SC_PAGESIZE).
Changes:
* libc/config/linux/{x86_64,aarch64,riscv}/entrypoints.txt: moved
sysconf back into TARGET_LIBC_ENTRYPOINTS, removed the
LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS guard.
* libc/test/integration/scudo/CMakeLists.txt: restored
libc.src.unistd.sysconf to the Scudo entrypoint library.
Assisted-by: Automated tooling, human reviewed.
sysconf moved behind LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS in commit
8146920541c4. When that flag is OFF (the default), the target is not
built as an OBJECT library, so referencing it via add_entrypoint_library
causes a CMake generation error on the libc-x86_64-debian-fullbuild bot.
Scudo does not use sysconf, so this is a safe removal.
Assisted-by: Automated tooling, human reviewed.
Use recently added support for timed_wait in CndVar and try_lock in
Mutex to implement the C11 functions `cnd_timedwait` and `mtx_trylock`
(counterparts of `pthread_cond_timedwait` and `pthread_mutex_trylock`,
respectively).
Fixes a minor edge case in `ensure_monotonicity` conversion where the
converted timeout could fall before epoch - clamp it to be 0 / epoch in
that case.
Assisted by: Gemini
Add the POSIX setenv() function, with EnvironmentManager::set()
handling environment array management and ownership tracking.
Registered for x86_64, aarch64, and riscv architectures. Integration
tests cover overwrite/no-overwrite semantics, empty/invalid names,
empty values, and repeated replacement.
Assisted-by: Automated tooling, human reviewed.
---------
Co-authored-by: Michael Jones <michaelrj@google.com>
Removed the last direct <sys/mman.h> include from mmap.h, replacing it
with hdr/types/size_t.h and hdr/types/off_t.h.
Added hdr/sys_mman_macros.h to test files that relied on transitive
includes for PROT_READ, MAP_ANONYMOUS, and similar macros.
Fix#194034.
Detect the deadlock cases of mutual thread joining.
Required by
`libcxx/test/std/thread/thread.jthread/join.deadlock.pass.cpp`
Assisted-by: Codex with gpt-5.5 high fast
Fix#193892.
This is found during libc++ bringing up process. This patch:
- implement recursive mutex support for real.
- fix the issue that pthread mutex initializer and public mutex
interface misalign with internal representation. this was the root cause
that hangs the libc++ test as padding bytes effectively pollute the
futex state if default initializer was used.
- additionally, we changed the field to bitfield to allow encoding more
data. (e.g. the error checking flag that is not yet added). timed bit is
removed as we always support it anyway. PI bit is added instead.
Renamed check-libc-lit to check-libc, replacing the old CTest-driven
target. Dependencies now use -build targets (e.g.
libc-hermetic-tests-build) so that check-libc only builds test
executables and delegates execution to lit.
This PR reimplements conditional variable with two different variants:
- futex-based shared condvar with atomic counter for waiters
- queue-based private condvar
Notice that thread-local queue node cannot be reliably accessed in
shared processes, so we cannot use a unified implementation in this
case.
POSIX.1-2024 (Issue 8) added atomicity conditions to conditional
variable:
- The `pthread_cond_broadcast()` function shall, **as a single atomic
operation**, determine which threads, if any, are blocked on the
specified condition variable cond and unblock all of these threads.
- The `pthread_cond_signal()` function shall, as a **single atomic
operation**, determine which threads, if any, are blocked on the
specified condition variable cond and unblock at least one of these
threads.
This means that threads parked after a condvar signal event shall not
steal signals before it. From my read, both implementation fulfills the
requirement but glibc claims that single futex does not provide the
stronger ordering needed by its users hence switched to a rotational
queue, to fulfill the requirements mentioned in
https://sourceware.org/bugzilla/show_bug.cgi?id=13165. As in a single
futex, the lock acquisition do not happen in order and hence when a
spurious wakeup happen, later waiters may "steal" the signal. However
musl's shared implementation and bionic's whole implementation and
Rust's std condvar still stick to a signal-futex+accounting data style.
Musl's private condvar and this implementation are even stronger in the
sense that not only the queue is decided as an atomic event, the mutex
acquisition also happens in baton-passing style.
Our implementation is different from musl in the sense that we have done
some spin attempts instead of always do futex syscall to requeue threads
(with a new requeued state added). This gives a chance for the
signal/waiter to stay in fast path if the queue is really small. Based
on the microbenchmark, this implementation is generally more performant.
We also abuse the `RawMutex`'s LOCKED state as "waiting for its turn".
One caveat we can see from the benchmark
(https://github.com/SchrodingerZhu/condvar-benchmark) is that strict
FIFO condvar is not that good if users are maintain the order on
themselves as in `turn_ring`, because many threads may just wake up
first only see it is not its turn while blocking the real thread in
turn. However, a semaphore or other synchronization primitives would be
more suitable in those cases. Even though in benchmark like
`turn_ring/broadcast_stress` made this code perform badly (but still
similar to musl anyway), they are not really the correct usage. In other
cases, we are always close to the fastest while providing a stronger
FIFO semantic.
TODO in future commit:
- support pthread cancellation. Ideally we should block cancellation
when signal is consumed and add cancellation callback for checking
illegibility.
- think about stronger ordering semantic in shared case (?)
Now that check-libc-lit has been validated alongside check-libc, make
lit the default test runner by renaming check-libc-lit to check-libc.
Remove the old CMake-driven check-libc custom target.
Make futex a common abstraction layer across platforms.
(linux/wasm/macOS/windows/fuchsia all have the support, which we can
align their support later on).
This patch also expose a requeue API that returns ENOSYS on unsupported
platforms. The requeue operation will be needed to reimplement a strict
FIFO style condvar similar to musl.
Additional cleanup is done to change raw syscall return value to
`ErrorOr<int>`.
Assisted-by: Codex with gpt-5.4 medium fast
Implemented getcontext and setcontext for x86_64 architecture in LLVM
libc. These functions use inline assembly with naked attributes to
capture and restore the exact register state.
Added:
* src/ucontext/getcontext.h and setcontext.h
* src/ucontext/x86_64/getcontext.cpp and setcontext.cpp
* Hermetic integration test for register preservation.
* Unit tests for basic functionality and signal mask preservation.
Updated entrypoints for x86_64 Linux.
The test compared getcwd() with getenv("PWD"), which is not reliable
under symlinked paths: PWD may preserve the logical path while getcwd()
returns the physical path.
Use stat(2) to verify directory identity instead.
Co-authored-by: Zile Xiong <xiongzile99@gmail.com>
Expose existing trylock internal operation to posix interface.
POSIX.1-2024 only specifies the `EBUSY` error case.
Assisted-by: Codex with gpt-5.4 default fast
This PR moves abort implementation to a header library so that internal
dependency no longer relies on the entrypoint object.
Additionally, it clean up prior dependency to the entrypoint object and
update staled tests.
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary:
It was very convenient to have the RPC server use the internal libc
printing utilities, but it caused a lot of problems. The LLVM libc
internals were never meant to be included arbitrarily and we completely
bypassed this restriction. Furthermore it prevented us from installing
and using these libraries in other contexts. There was a whole host of
hacks around this, leading to endless PPC problems, compiler errors,
etc.
This PR re-uses the old minified format parser I used to use for the GPU
case. We simply parse the formats to get the size, then copy the
strings. The actual printing instead is done by locking the output file
and repeatedly building up the string using the host's `printf`. Slight
test modifications because we no longer can depend on the specific user
printf specification, it may not handle null or binary values for
example.
Updated check-libc-lit to depend only on build-only targets. Added
libc-integration-tests-build to track integration test executables and
updated LLVMLibCTestRules.cmake to populate it.
Removed incorrect dependencies on execution suites in include and
integration tests that were introduced in #184366.
Summary:
This builds off the pattern to add support for more of the standard
operations. The reductions could concievably use the AMDGPU builtins
later once we can enable DPP or other optimizations.
Summary:
This was previously a Trieber stack, which is a perfectly fine generic
and lock-free data structure. However, this used some expensive CAS
operations and had issues with ABA. Because the only user of this was
the slab cache mechanism, we can pretty safely specialize it. Instead,
we simply search a fixed size buffer for some sentinal values and CAS
into it.
For allocations that only ever hit the cache, this improves performance
from ~9000 cycles to ~6000 cycles and similar improvements for workloads
that feel the pain of small thread counts hitting the cache.
The lit-based test runner introduced in c776a52f only discovered
libc.test.src tests with a strict __unit__.__build__ or
__hermetic__.__build__ suffix. This missed four categories of tests:
1. libc.test.include.* tests (e.g. isnan_test, signbit_test)
2. libc.test.integration.* tests (e.g. pthread, unistd, startup)
3. libc.test.src.* tests that have no __unit__/__hermetic__ marker (e.g.
errno_test, dirent_test, htonl)
4. libc.test.src.* tests with extra option suffixes between the type
marker and .__build__ (e.g. __unit__.__NO_FMA_OPT.__build__)
Wire up the two missing build dependencies so that check-libc-lit builds
include and integration tests before running them, and update
_isTestExecutable() to recognise all four patterns.
The pattern documentation was consolidated into the _isTestExecutable()
docstring, where it is next to the code it describes, to avoid the two
diverging in future.
Tested:
Compared the test count from a full `ninja check-libc` run (2765 tests)
against `llvm-lit --show-tests libc/test` after this change and
confirmed the counts match exactly.
Resolves ifunc targets before `main()` runs in static libc
This enables static binaries to use ifunc-based dispatch during early
process startup, so optimized implementations can be selected based on
CPU features. Without this relocation step in startup, those targets are
not ready when program code begins executing.
This change:
- adds IRELATIVE relocation handling for x86_64, AArch64, ARMv7 and RISC-V,
- reads `AT_HWCAP` / `AT_HWCAP2` from auxv and passes them to resolvers
where required (notably AArch64),
- runs IRELATIVE processing after base-address discovery and before TLS
setup,
- adds integration tests for both the ifunc path and the no-ifunc path,
- Changed the load bias type for ptrdiff_t to intptr_t to align with
IRELATIVE handling, which uses intptr_t for load bias calculations.
Summary:
The NVIDIA ITS protocol allows lanes to diverge inside of a warp. We
previously had contingencies around this, but there were cases where
issues would still show up under highly stressed usage.
The rules state that as long as the PC is the same, threads can
reconverge. This means that we can see a 'convergent' warp even when
they took completely divergent paths to get there. This resulted in the
'index' value in the RPC port lookup loop thinking we were in a
convergent group while all the indices were different. Fix this with a
broadcast to force the expected behavior
Additionally, we did not force that the threads were actually done with
their 'work_fn'. If the work included something that caused divergence
the other threads could continue and toggle the mailbox, resulting in
the server seeing unfinished work. Fix this with an explicit sync and
have one thread do it.
Add a test to make sure this actually works.
Summary:
Closing ports was previously done manually, This makes the protocol more
error prone as unclosed ports will leak and eventually the locks will
run out. I believe the original fear was that the RAII portion would
negatively impact code generation but I have not noticed anything
significant.
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This moves the libc-internal AllocChecker API out of
src/__support/CPP/new.h and updates CPP/README.md to state the
intent to keep src/__support/CPP and the LIBC_NAMESPACE::cpp
namespace a "pure" subset of standard C++ API polyfills.
This patch implements the generic mutex and raw_mutex interfaces on
macOS. A new Futex class is provided that relies on os_sync_wait and
os_sync_wake to emulate futex‑like wait and wake semantics. The
OS‑specific part is moved into futex_utils, which now contains the
Darwin implementation.
[libc][stdlib] Simplify getenv_test by using inline_strcmp instead of custom helper
Replace the custom `my_streq` helper function with LLVM libc's
`inline_strcmp` utility from `src/string/memory_utils/inline_strcmp.h`.
Changes:
- Remove 18-line custom `my_streq` implementation
- Use `inline_strcmp` with a simple comparator lambda for string comparisons
- Replace `my_streq(..., nullptr)` checks with direct `== nullptr` comparisons
- Maintain identical test coverage while reducing code duplication
Benefits:
- Uses existing, well-tested LLVM libc infrastructure
- Clearer test assertions with standard comparison functions
- More concise code (reduced from ~48 to ~33 lines)
- Consistent with LLVM libc coding practices
The test continues to verify:
- Empty string handling
- Invalid name handling ('=')
- Missing environment variable queries
- Correct retrieval of existing variables (FRANCE, GERMANY, PATH)
- Partial name matching behavior (FRANC vs FRANCE, FRANCE1 vs FRANCE)