Summary:
Currently there are several layers to handle `printf`. Since we now have
varargs and an implementation of `printf` this can be heavily
simplified.
1. The frontend renames `printf` into `omp_vprintf` and gives it an
argument buffer.
Removing 1. triggered some code in the AMDGPU backend menat for HIP /
OpenCL, so I hadded an exception to it.
2. Forward this to CUDA vprintf or ignore it.
We no longer need special handling for it since we have varargs. So now
we just forward this to CUDA vprintf if we have libc, otherwise just
leave `printf` as an external function and expect that `libc` will be
linked in.
This requires the user to set the upper bounds of the heap by defining
the symbol `__libc_heap_limit`. The heap begins at `_end` and ends
`__libc_heap_limit` bytes afterwards. This prevents a completely unused
heap from requiring any space, and it prevents the heap from being
zeroed at initialization time as part of BSS. It also allows users to
customize the available heap location without recompiling libc.
I'd think this should eventually be replaced with an implemenation based
on a morecore() library. This would allow the same implementation to use
sbrk() on POSIX, `_end` and `__libc_heap_limit` on embedded, and a
buffer in tests. It would also provide better "wilderness" behavior that
tends to decrease heap fragementation (see Wilson et al.)
See #98096
This decreases the surface area of the block implementation in
preparation for deeper changes to its implementation.
See #98096
- Remove dead member functions.
- Remove last() check from next(), as described in its comment.
- Rework object lifetimes such that only block headers are actually
considered live. This simplifies their implementation.
- The allocated storage becomes live at the outer call to malloc-family
functions via a special case in the C++ standard.
- Add asserts for flag properties required by the implementation.
- Remove static from member functions that don't invalidate the block.
Since there are two offsets from block start to usable area, this
ensures that the usable area is maximally aligned, so long as the offset
type size is no less than half the max alignment. This is true on at
least typical 32-bit and 64-bit targets.
Previously, there was a roughly 50-50 chance a given block's usable area
would be misaligned for a malloc on a 32-bit system. The half that were
misaligned would require at least one block of additional padding,
costing 12 bytes. With this change, the only cost is 0-4 bytes at the
beginning of the heap to reach an initial 8-byte alignment.
See #98096
The unused padding and alignment fields were removed. The used and last
bits were stashed into the lower two bits of the next chunk offset.
(This is a very typical trick for Knuth boundary tags.) The chunk
offsets were recast as counting bytes rather than multiples of the
alignment. To ensure that the lowest two bits are not significant, the
minimum alignment was bumped to 4. This shouldn't affect anything in
practice, since alignof(max_align_t) is overwhelmingly likely to be 8.
See #98096
Summary:
The configs all need default values which targets then override. This
one was an empty string which made the logic report an error. The only
reason it wasn't a build failure was because of a stray `:`.
We want to avoid any possibility that the compiler will insert a
prologue/epilogue violating the calling contracts for these special
functions, potentially clobbering registers that must be preserved. To
do that they should be marked naked, as is already the case on ARM.
See #87837 for further context.
This patch reverts #99781 and part of #99771 since `epoll_pwait2` is not
in fact available on all supported systems. It is my opinion that we
shouldn't provide a version of a function that doesn't perform as
expected, which is why this revert needs to happen.
The `epoll_pwait2` function can be reenabled when we have a way to check
if it is available on the target system, tracking bug for that is #80060
While looking through the list of includes for #99693 I found these
includes that also need to be cleaned up. I removed the extra includes
in expm1.cpp, but the include in thread.h needs more attention so I just
marked it with a todo.
Summary:
This file is an object library, but uses the `LIBC_COPT_PUBLIC_PACKAING`
option. This will always be undefined which leads to a type mismatch
when uses actually try to link against it. This patch simply removes
this and turns it into a header only library. This means that the
implementations of the callback lists and the mutexes need to live in
their respective files. The result is that `atexit` needs to be defined
for `at_quick_exit` to be valid.
This patch removes the recursion in fcntl introduced by PR #99675 as it is not required and may be dangerous in some cases: some toolchains define F_GETLK == F_GETLK64 causing infinite recursion.
In some systems like rv32, only fcntl64 is available and it employs a different structure for file locking and the correspoding F_GETLK64, F_SETLK64, and F_SETLKW64 commands.
So if we use fcntl64, the F_GETLK, F_SETLK, and F_SETLKW commands need to be changed to their 64 versions. This patch adds new cases to the swich(cmd) in our implementation of fcntl to do that.
The default case was moved to outside the switch, so we don't need to change anything, the F_GETLK, F_SETLK, and F_SETLKW commands will just go through the old implementation.
This patch implements pwait2 using pwait. The implementation is an
approximation of pwait2, since pwait only only supports timeouts in
milliseconds, not nanoseconds, as required by pwait2.
This patch enables most of the libc entrypoints for riscv, except for fstatvfs, statvfs, dmull and fmull which are currently failing compilation. float16 is also not added, as rv32 doesn't seem to support it yet.
This patch also fixes the call to seek, which should take an off_t, and was missed in PR #68269.
This patch fixes:
randomness.h and getauxval.cpp were passing ssize_t as size_t
kernel_statx.h was assigning an uint64_t to uintptr_t
fopencookie.cpp was trying to create a FileIOResult using ssize_t but the constructor expected a size_t
thread.h was trying to call free_stack (which takes a size_t) with an unsigned long long. free_stack does the calculations using uintptr_t, so I changed the passing values to size_t
When crosscompiling, we need to search for the linux kernel headers in the sysroot but since #97486 the linux kernel headers were always searched in /usr/include.
This patch fixes this behaviour by prepending a '=' to where we search for the kernel headers. As per the gcc/clang's documentation a '=' before the path is replaced by the sysroot.
This patch also includes a fix for rv32, that fails to compile due to a missing definition of CLOCK_REALTIME after this change.
Division-less Newton iterations algorithm for cube roots.
1. **Range reduction**
For `x = (-1)^s * 2^e * (1.m)`, we get 2 reduced arguments `x_r` and `a`
as:
```
x_r = 1.m
a = (-1)^s * 2^(e % 3) * (1.m)
```
Then `cbrt(x) = x^(1/3)` can be computed as:
```
x^(1/3) = 2^(e / 3) * a^(1/3).
```
In order to avoid division, we compute `a^(-2/3)` using Newton method
and then
multiply the results by a:
```
a^(1/3) = a * a^(-2/3).
```
2. **First approximation to a^(-2/3)**
First, we use a degree-7 minimax polynomial generated by Sollya to
approximate `x_r^(-2/3)` for `1 <= x_r < 2`.
```
p = P(x_r) ~ x_r^(-2/3),
```
with relative errors bounded by:
```
| p / x_r^(-2/3) - 1 | < 1.16 * 2^-21.
```
Then we multiply with `2^(e % 3)` from a small lookup table to get:
```
x_0 = 2^(-2*(e % 3)/3) * p
~ 2^(-2*(e % 3)/3) * x_r^(-2/3)
= a^(-2/3)
```
with relative errors:
```
| x_0 / a^(-2/3) - 1 | < 1.16 * 2^-21.
```
This step is done in double precision.
3. **First Newton iteration**
We follow the method described in:
Sibidanov, A. and Zimmermann, P., "Correctly rounded cubic root
evaluation
in double precision", https://core-math.gitlabpages.inria.fr/cbrt64.pdf
to derive multiplicative Newton iterations as below:
Let `x_n` be the nth approximation to `a^(-2/3)`. Define the n^th error
as:
```
h_n = x_n^3 * a^2 - 1
```
Then:
```
a^(-2/3) = x_n / (1 + h_n)^(1/3)
= x_n * (1 - (1/3) * h_n + (2/9) * h_n^2 - (14/81) * h_n^3 + ...)
```
using the Taylor series expansion of `(1 + h_n)^(-1/3)`.
Apply to `x_0` above:
```
h_0 = x_0^3 * a^2 - 1
= a^2 * (x_0 - a^(-2/3)) * (x_0^2 + x_0 * a^(-2/3) + a^(-4/3)),
```
it's bounded by:
```
|h_0| < 4 * 3 * 1.16 * 2^-21 * 4 < 2^-17.
```
So in the first iteration step, we use:
```
x_1 = x_0 * (1 - (1/3) * h_n + (2/9) * h_n^2 - (14/81) * h_n^3)
```
Its relative error is bounded by:
```
| x_1 / a^(-2/3) - 1 | < 35/242 * |h_0|^4 < 2^-70.
```
Then we perform Ziv's rounding test and check if the answer is exact.
This step is done in double-double precision.
4. **Second Newton iteration**
If the Ziv's rounding test from the previous step fails, we define the
error
term:
```
h_1 = x_1^3 * a^2 - 1,
```
And perform another iteration:
```
x_2 = x_1 * (1 - h_1 / 3)
```
with the relative errors exceed the precision of double-double.
We then check the Ziv's accuracy test with relative errors < 2^-102 to
compensate for rounding errors.
5. **Final iteration**
If the Ziv's accuracy test from the previous step fails, we perform
another
iteration in 128-bit precision and check for exact outputs.
This patch makes rand select different algorithms depending on the arch.
This is needed to avoid a test failure in 32-bit systems where the LSB
of rand was not uniform enough when the 64-bit constants are used in
32-bit systems.
Summary:
This patch implements `clock_gettime` using the monotonic clock. This
allows users to get time elapsed at nanosecond resolution. This is
primarily to facilitate compiling the `chrono` library from `libc++`.
For this reason we provide both `CLOCK_MONOTONIC`, which we can
implement
with the GPU's global fixed-frequency clock, and `CLOCK_REALTIME` which
we cannot. The latter is provided just to make people who use this
header happy and it will always return failure.
Summary:
The GPU ignores `errno` primarily, but targets want these functions to
be defined for certain C standard interfaces. This patch enables them
and makes the test function on non-Linux targets.