Large alloc fix (#178)

* Improved malloc style tests

Added comprehensive testing of realloc, and other minor improvements
to reporting errors.

* Fix realloc resizing for large sizeclasses.

The rounding by sizeclass was incorrect for large allocation.  This fixes
that.

* Ensure alloc_size is committed

There is an awkward interaction between alloc_size and
committing only what is requested.  If the user assumes
everything up to alloc_size is available, then we need to
either store the more precise size for alloc_size to return
or commit the whole 2^n range, so that alloc_size stays simple.

This changes to just make the whole range committed.
In the future, we might want to store a more precise size, so
that the allocation can be sized more precisely.

* Reduce size of objects.
This commit is contained in:
Matthew Parkinson
2020-05-07 06:31:37 +01:00
committed by GitHub
parent 79ca9bdd9d
commit c899ee7ab2
6 changed files with 66 additions and 12 deletions

View File

@@ -18,8 +18,13 @@ void check_result(size_t size, size_t align, void* p, int err, bool null)
}
else
{
if (our_malloc_usable_size(p) < size)
auto asize = our_malloc_usable_size(p);
if (asize < size)
{
printf(
"Usable size is %zu, but required to be at least %zu.\n", asize, size);
abort();
}
if (static_cast<size_t>(reinterpret_cast<uintptr_t>(p) % align) != 0)
abort();
@@ -30,7 +35,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null)
void test_calloc(size_t nmemb, size_t size, int err, bool null)
{
fprintf(stderr, "calloc(%d, %d)\n", (int)nmemb, (int)size);
fprintf(stderr, "calloc(%zu, %zu)\n", nmemb, size);
errno = 0;
void* p = our_calloc(nmemb, size);
@@ -47,7 +52,11 @@ void test_calloc(size_t nmemb, size_t size, int err, bool null)
void test_realloc(void* p, size_t size, int err, bool null)
{
fprintf(stderr, "realloc(%p(%d), %d)\n", p, int(size), (int)size);
size_t old_size = 0;
if (p != nullptr)
old_size = our_malloc_usable_size(p);
fprintf(stderr, "realloc(%p(%zu), %zu)\n", p, old_size, size);
errno = 0;
auto new_p = our_realloc(p, size);
// Realloc failure case, deallocate original block
@@ -58,7 +67,7 @@ void test_realloc(void* p, size_t size, int err, bool null)
void test_posix_memalign(size_t size, size_t align, int err, bool null)
{
fprintf(stderr, "posix_memalign(&p, %d, %d)\n", (int)align, (int)size);
fprintf(stderr, "posix_memalign(&p, %zu, %zu)\n", align, size);
void* p = nullptr;
errno = our_posix_memalign(&p, align, size);
check_result(size, align, p, err, null);
@@ -66,7 +75,7 @@ void test_posix_memalign(size_t size, size_t align, int err, bool null)
void test_memalign(size_t size, size_t align, int err, bool null)
{
fprintf(stderr, "memalign(%d, %d)\n", (int)align, (int)size);
fprintf(stderr, "memalign(%zu, %zu)\n", align, size);
errno = 0;
void* p = our_memalign(align, size);
check_result(size, align, p, err, null);
@@ -81,6 +90,16 @@ int main(int argc, char** argv)
constexpr int SUCCESS = 0;
test_realloc(our_malloc(64), 4194304, SUCCESS, false);
for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++)
{
const size_t size = 1ULL << sc;
printf("malloc: %zu\n", size);
check_result(size, 1, our_malloc(size), SUCCESS, false);
check_result(size + 1, 1, our_malloc(size + 1), SUCCESS, false);
}
test_calloc(0, 0, SUCCESS, false);
for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++)
@@ -97,11 +116,37 @@ int main(int argc, char** argv)
test_calloc(n, 0, SUCCESS, false);
}
test_calloc(0, size, SUCCESS, false);
}
for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++)
{
const size_t size = sizeclass_to_size(sc);
test_realloc(our_malloc(size), size, SUCCESS, false);
test_realloc(our_malloc(size), 0, SUCCESS, true);
test_realloc(nullptr, size, SUCCESS, false);
test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true);
for (snmalloc::sizeclass_t sc2 = 0; sc2 < NUM_SIZECLASSES; sc2++)
{
const size_t size2 = sizeclass_to_size(sc2);
test_realloc(our_malloc(size), size2, SUCCESS, false);
test_realloc(our_malloc(size + 1), size2, SUCCESS, false);
}
}
for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++)
{
const size_t size = 1ULL << sc;
test_realloc(our_malloc(size), size, SUCCESS, false);
test_realloc(our_malloc(size), 0, SUCCESS, true);
test_realloc(nullptr, size, SUCCESS, false);
test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true);
for (snmalloc::sizeclass_t sc2 = 0; sc2 < (SUPERSLAB_BITS + 4); sc2++)
{
const size_t size2 = 1ULL << sc2;
printf("size1: %zu, size2:%zu\n", size, size2);
test_realloc(our_malloc(size), size2, SUCCESS, false);
test_realloc(our_malloc(size + 1), size2, SUCCESS, false);
}
}
test_posix_memalign(0, 0, EINVAL, true);