* export netbsd's reallocarr proposal.
acts subtly differently from reallocarray, returns an error code
and first argument as receiver.
* not export by default
* ci tests
* apply suggestions
* doc addition
* Apply suggestions from code review
Co-authored-by: Matthew Parkinson <mjp41@users.noreply.github.com>
On Open Enclave having the `local_alloc` directly in thread-local
storage was causing a crash. This changes the `local_alloc` to be
indirected, and thus puts less pressure on the thread-local storage.
The test also has deals with how to allocate before a thread-local
storage has been established.
If there is only one slab remaining, then we probabalisticly allocator a
new one. If a slab is barely in use, then this could cause us to
effectively double the number of slabs in use.
This commit checks if the remaining slab has enough remaining elements
to provide randomisation.
* Add default for getting chunk allocator state
Makes the API same between the two configurations.
* Reduce address space usage for Open Enclave
* Fix OE Pal concept
* Add support for Pal not to provide time.
The lazy return of pages to the OS uses a simple time
based heuristic. This enables a PAL to not support time,
and return the memory to a central pool immediately.
* Update src/backend/backend.h
Co-authored-by: Amaury Chamayou <amaury@xargs.fr>
Co-authored-by: Amaury Chamayou <amaury@xargs.fr>
The primary aim for this refactor is to use a representation for
sizeclasses that uniformly covers both large and small. This allows
certain operations such as alloc_size and external_pointer to be
uniformly implemented.
The additional types make clear which kind of sizeclass is in use.
This also tidies up the code for sizeclass based divisible by and
modulus.
It fixes a bug in rust_realloc that didn't correctly determine a realloc
was required for large classes.
The spelling of inline assembler constraints on Morello would be
different, but Jessica Clarke points out that we should just be using
the builtin when available, so do that instead.
Co-authored-by: Jessica Clarke <jrtc27@jrtc27.com>
With the new snmalloc2 changes it seems the larger window is leading to
more fragmentation and harming performance. Reducing size still
provides good batching, improves memory overhead.
This adds a way to periodically pool the PAL to see if any timers have
expired. Timers can be used to periodically provide callbacks to the
rest of snmalloc.
Consuming available slabs in LIFO order makes predicting address reuse harder
but appears to have performance implications. Condition this on CHECK_CLIENT
and instead use FIFO order on !CHECK_CLIENT builds.
Errno is not required to be 0 on return from malloc,
so don't bother trying to make it 0. Leads to false test failures where
libc calls have not reset it after a failure.
On systems with larger than 16KiB page size, we have chunks
that divide a page. This seems a little strange, and if we
want to disable the pages backing a chunk, this is not possible.
This change ensures the chunk is always at least a single page.
The correct thing to do, of course, is to fix these upstream, but that requires
understanding exactly what's wrong, and that's harder than just not tickling the
bugs.
This adds a CHERI AAL and expands the FreeBSD PAL to cover CHERI. It updates a
comment in ds/address.h now that there is an example architecture that
differentiates uintptr_t and address_t.
This dates back to the much earlier design that required the use of an authority
map. Since the current CHERI design does not, go ahead and ask the platform
whenever underlying allocation requests are sufficiently aligned.
This preserves the chunk pointer through the use of a chunk as a slab. It does
grow the structure by one pointer, but on non-CHERI it is still padded to 64
bytes, even with CHECK_CLIENT guards in place:
0: MetaCommon chunk pointer
8: next pointer
16: builder head[0]
24: builder head[1]
32: builder tail[0]
40: builder tail[1]
48: builder length[0] (uint16_t)
50: builder length[1] (uint16_t)
52: padding (4 bytes)
56: needed (uint16_t)
58: sleeping (bool)
(Sadly, on CHERI, even without CHECK_CLIENT guards and with no padding, there
are now four pointers in the structure -- chunk, next, head, tail -- plus five
extra bytes. We will likely wish to explore encoding the head and tail offsets
relative to the chunk pointer.)
This lets us remove the "subversive amplification" in dealloc() in favor of just
preserving the chunk pointer. Speaking of, be sure to assign that in all the
right places, and ASSERT that we've got it right.
The use of void* had let an overzealous unsafe_ptr() leak a pointer with address
space control to the client (in LocalAllocator::alloc_not_small, specifically).
Correct this to call capptr_chunk_is_alloc() (to capture our intent) and
capptr_to_user_address_control() (to do the bounding) and defer the conversion
to void* until the very periphery of the allocator, using capptr_reveal()
(again, to capture intent).