aboutsummaryrefslogtreecommitdiff
path: root/malloc/tst-memalign-2.c
diff options
context:
space:
mode:
Diffstat (limited to 'malloc/tst-memalign-2.c')
-rw-r--r--malloc/tst-memalign-2.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/malloc/tst-memalign-2.c b/malloc/tst-memalign-2.c
new file mode 100644
index 0000000..4996578
--- /dev/null
+++ b/malloc/tst-memalign-2.c
@@ -0,0 +1,155 @@
+/* Test for memalign chunk reuse.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <array_length.h>
+#include <libc-pointer-arith.h>
+#include <support/check.h>
+
+typedef struct TestCase {
+ size_t size;
+ size_t alignment;
+ void *ptr1;
+ void *ptr2;
+} TestCase;
+
+static TestCase tcache_allocs[] = {
+ { 24, 8, NULL, NULL },
+ { 24, 16, NULL, NULL },
+ { 128, 32, NULL, NULL }
+};
+#define TN array_length (tcache_allocs)
+
+static TestCase large_allocs[] = {
+ { 23450, 64, NULL, NULL },
+ { 23450, 64, NULL, NULL },
+ { 23550, 64, NULL, NULL },
+ { 23550, 64, NULL, NULL },
+ { 23650, 64, NULL, NULL },
+ { 23650, 64, NULL, NULL },
+ { 33650, 64, NULL, NULL },
+ { 33650, 64, NULL, NULL }
+};
+#define LN array_length (large_allocs)
+
+void *p;
+
+/* Sanity checks, ancillary to the actual test. */
+#define CHECK(p,a) \
+ if (p == NULL || !PTR_IS_ALIGNED (p, a)) \
+ FAIL_EXIT1 ("NULL or misaligned memory detected.\n");
+
+static int
+do_test (void)
+{
+ int i, j;
+ int count;
+ void *ptr[10];
+ void *p;
+
+ /* TCache test. */
+
+ for (i = 0; i < TN; ++ i)
+ {
+ tcache_allocs[i].ptr1 = memalign (tcache_allocs[i].alignment, tcache_allocs[i].size);
+ CHECK (tcache_allocs[i].ptr1, tcache_allocs[i].alignment);
+ free (tcache_allocs[i].ptr1);
+ /* This should return the same chunk as was just free'd. */
+ tcache_allocs[i].ptr2 = memalign (tcache_allocs[i].alignment, tcache_allocs[i].size);
+ CHECK (tcache_allocs[i].ptr2, tcache_allocs[i].alignment);
+ free (tcache_allocs[i].ptr2);
+
+ TEST_VERIFY (tcache_allocs[i].ptr1 == tcache_allocs[i].ptr2);
+ }
+
+ /* Test for non-head tcache hits. */
+ for (i = 0; i < array_length (ptr); ++ i)
+ {
+ if (i == 4)
+ {
+ ptr[i] = memalign (64, 256);
+ CHECK (ptr[i], 64);
+ }
+ else
+ {
+ ptr[i] = malloc (256);
+ CHECK (ptr[i], 4);
+ }
+ }
+ for (i = 0; i < array_length (ptr); ++ i)
+ free (ptr[i]);
+
+ p = memalign (64, 256);
+ CHECK (p, 64);
+
+ count = 0;
+ for (i = 0; i < 10; ++ i)
+ if (ptr[i] == p)
+ ++ count;
+ free (p);
+ TEST_VERIFY (count > 0);
+
+ /* Large bins test. */
+
+ for (i = 0; i < LN; ++ i)
+ {
+ large_allocs[i].ptr1 = memalign (large_allocs[i].alignment, large_allocs[i].size);
+ CHECK (large_allocs[i].ptr1, large_allocs[i].alignment);
+ /* Keep chunks from combining by fragmenting the heap. */
+ p = malloc (512);
+ CHECK (p, 4);
+ }
+
+ for (i = 0; i < LN; ++ i)
+ free (large_allocs[i].ptr1);
+
+ /* Force the unsorted bins to be scanned and moved to small/large
+ bins. */
+ p = malloc (60000);
+
+ for (i = 0; i < LN; ++ i)
+ {
+ large_allocs[i].ptr2 = memalign (large_allocs[i].alignment, large_allocs[i].size);
+ CHECK (large_allocs[i].ptr2, large_allocs[i].alignment);
+ }
+
+ count = 0;
+ for (i = 0; i < LN; ++ i)
+ {
+ int ok = 0;
+ for (j = 0; j < LN; ++ j)
+ if (large_allocs[i].ptr1 == large_allocs[j].ptr2)
+ ok = 1;
+ if (ok == 1)
+ count ++;
+ }
+
+ /* The allocation algorithm is complicated outside of the memalign
+ logic, so just make sure it's working for most of the
+ allocations. This avoids possible boundary conditions with
+ empty/full heaps. */
+ TEST_VERIFY (count > LN / 2);
+
+ return 0;
+}
+
+#include <support/test-driver.c>