Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/lib/libc/stdlib t_posix_memalign: Expand test cases an...
details: https://anonhg.NetBSD.org/src/rev/280760d67bad
branches: trunk
changeset: 377259:280760d67bad
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Jul 04 15:06:36 2023 +0000
description:
t_posix_memalign: Expand test cases and properties.
- Test cartesian product of a sampling of sizes and a sampling of
alignments.
- Verify all the edge cases I could find in posix_memalign and
aligned_alloc, including failure modes.
- Test an unreasonably large (but aligned) allocation size.
- Use ATF_CHECK_* instead of ATF_REQUIRE_* so all failures will be
reported, not just the first one.
- While here, build with -fno-builtin-aligned_alloc and with
-fno-builtin-posix_memalign to make sure the compiler doesn't try
any shenanigans.
XXX pullup-10
diffstat:
tests/lib/libc/stdlib/Makefile | 5 +-
tests/lib/libc/stdlib/t_posix_memalign.c | 222 +++++++++++++++++++++++-------
2 files changed, 173 insertions(+), 54 deletions(-)
diffs (294 lines):
diff -r 782c6735dab4 -r 280760d67bad tests/lib/libc/stdlib/Makefile
--- a/tests/lib/libc/stdlib/Makefile Tue Jul 04 15:06:28 2023 +0000
+++ b/tests/lib/libc/stdlib/Makefile Tue Jul 04 15:06:36 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.33 2020/07/01 07:16:37 jruoho Exp $
+# $NetBSD: Makefile,v 1.34 2023/07/04 15:06:36 riastradh Exp $
.include <bsd.own.mk>
@@ -31,6 +31,9 @@ BINDIR= ${TESTSDIR}
PROGS+= h_atexit
PROGS+= h_getopt h_getopt_long
+CFLAGS.t_posix_memalign.c+= -fno-builtin-posix_memalign
+CFLAGS.t_posix_memalign.c+= -fno-builtin-aligned_alloc
+
CPPFLAGS.t_strtod.c+= -D__TEST_FENV
LDADD.t_strtod= -lm
DPADD.t_strtod+= ${LIBM}
diff -r 782c6735dab4 -r 280760d67bad tests/lib/libc/stdlib/t_posix_memalign.c
--- a/tests/lib/libc/stdlib/t_posix_memalign.c Tue Jul 04 15:06:28 2023 +0000
+++ b/tests/lib/libc/stdlib/t_posix_memalign.c Tue Jul 04 15:06:36 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_posix_memalign.c,v 1.5 2018/07/29 01:45:25 maya Exp $ */
+/* $NetBSD: t_posix_memalign.c,v 1.6 2023/07/04 15:06:36 riastradh Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_posix_memalign.c,v 1.5 2018/07/29 01:45:25 maya Exp $");
+__RCSID("$NetBSD: t_posix_memalign.c,v 1.6 2023/07/04 15:06:36 riastradh Exp $");
#include <atf-c.h>
@@ -43,6 +43,8 @@
#include <stdlib.h>
#include <string.h>
+#define rounddown(x, n) (((x) / (n)) * (n))
+
ATF_TC(posix_memalign_basic);
ATF_TC_HEAD(posix_memalign_basic, tc)
{
@@ -50,32 +52,77 @@ ATF_TC_HEAD(posix_memalign_basic, tc)
}
ATF_TC_BODY(posix_memalign_basic, tc)
{
- static const size_t size[] = {
- 1, 2, 3, 4, 10, 100, 16384, 32768, 65536
- };
+ enum { maxaligntest = 16384 };
static const size_t align[] = {
- 512, 1024, 16, 32, 64, 4, 2048, 16, 2
+ 0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
+ 8192, maxaligntest,
};
+ static const size_t size[] = {
+ 0, 1, 2, 3, 4, 10, 100, 10000, 16384, 32768, 65536,
+ rounddown(SIZE_MAX, maxaligntest),
+ };
+ size_t i, j;
- size_t i;
- void *p;
+ for (i = 0; i < __arraycount(align); i++) {
+ for (j = 0; j < __arraycount(size); j++) {
+ void *p = (void *)0x1;
+ const int ret = posix_memalign(&p, align[i], size[j]);
- for (i = 0; i < __arraycount(size); i++) {
- int ret;
- p = (void*)0x1;
-
- (void)printf("Checking posix_memalign(&p, %zu, %zu)...\n",
- align[i], size[i]);
- ret = posix_memalign(&p, align[i], size[i]);
+ if (align[i] == 0 ||
+ (align[i] & (align[i] - 1)) != 0 ||
+ align[i] < sizeof(void *)) {
+ ATF_CHECK_EQ_MSG(ret, EINVAL,
+ "posix_memalign(&p, %zu, %zu): %s",
+ align[i], size[j], strerror(ret));
+ continue;
+ }
+ if (size[j] == rounddown(SIZE_MAX, maxaligntest) &&
+ ret != EINVAL) {
+ /*
+ * If obscenely large alignment isn't
+ * rejected as EINVAL, we can't
+ * allocate that much memory anyway.
+ */
+ ATF_CHECK_EQ_MSG(ret, ENOMEM,
+ "posix_memalign(&p, %zu, %zu): %s",
+ align[i], size[j], strerror(ret));
+ continue;
+ }
- if ( align[i] < sizeof(void *))
- ATF_REQUIRE_EQ_MSG(ret, EINVAL,
- "posix_memalign: %s", strerror(ret));
- else {
- ATF_REQUIRE_EQ_MSG(ret, 0,
- "posix_memalign: %s", strerror(ret));
- ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0,
- "p = %p", p);
+ /*
+ * Allocation should fail only if the alignment
+ * isn't supported, in which case it will fail
+ * with EINVAL. No standard criterion for what
+ * alignments are supported, so just stop here
+ * on EINVAL.
+ */
+ if (ret == EINVAL)
+ continue;
+
+ ATF_CHECK_EQ_MSG(ret, 0,
+ "posix_memalign(&p, %zu, %zu): %s",
+ align[i], size[j], strerror(ret));
+ ATF_CHECK_EQ_MSG((intptr_t)p & (align[i] - 1), 0,
+ "posix_memalign(&p, %zu, %zu): %p",
+ align[i], size[j], p);
+
+ if (size[j] != 0) {
+ if (p == NULL) {
+ atf_tc_fail_nonfatal(
+ "%s:%d:"
+ "posix_memalign(&p, %zu, %zu):"
+ " %p",
+ __FILE__, __LINE__,
+ align[i], size[j], p);
+ }
+ } else {
+ /*
+ * No guarantees about whether
+ * zero-size allocation yields null
+ * pointer or something else.
+ */
+ }
+
free(p);
}
}
@@ -89,40 +136,108 @@ ATF_TC_HEAD(aligned_alloc_basic, tc)
}
ATF_TC_BODY(aligned_alloc_basic, tc)
{
- static const size_t size[] = {
- 1, 2, 3, 4, 10, 100, 16384, 32768, 65536, 10000, 0
- };
+ enum { maxaligntest = 16384 };
static const size_t align[] = {
- 512, 1024, 16, 32, 64, 4, 2048, 16, 2, 2048, 0
+ 0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
+ 8192, maxaligntest,
};
+ static const size_t size[] = {
+ 0, 1, 2, 3, 4, 10, 100, 10000, 16384, 32768, 65536,
+ rounddown(SIZE_MAX, maxaligntest),
+ };
+ size_t i, j;
+
+ for (i = 0; i < __arraycount(align); i++) {
+ for (j = 0; j < __arraycount(size); j++) {
+ void *const p = aligned_alloc(align[i], size[j]);
- size_t i;
- void *p;
+ /*
+ * C11, 6.2.8 Alignment of objects, paragraph
+ * 4, p. 48:
+ *
+ * Every valid alignment value shall be a
+ * nonnegative integral power of two.
+ *
+ * C11, 7.22.3.1 The aligned_alloc function,
+ * paragraph 2, p. 348:
+ *
+ * The value of alignment shall be a valid
+ * alignment supported by the
+ * implementation and the value of size
+ * shall be an integral multiple of
+ * alignment.
+ *
+ * Setting errno to EINVAL is a NetBSD
+ * extension. The last clause appears to rule
+ * out aligned_alloc(n, 0) for any n, but it's
+ * not clear.
+ */
+ if (align[i] == 0 ||
+ (align[i] & (align[i] - 1)) != 0 ||
+ (size[j] != 0 && size[j] % align[i] != 0)) {
+ if (p != NULL) {
+ ATF_CHECK_EQ_MSG(p, NULL,
+ "aligned_alloc(%zu, %zu): %p",
+ align[i], size[j], p);
+ continue;
+ }
+ ATF_CHECK_EQ_MSG(errno, EINVAL,
+ "aligned_alloc(%zu, %zu): %s",
+ align[i], size[j], strerror(errno));
+ continue;
+ }
- for (i = 0; i < __arraycount(size); i++) {
- (void)printf("Checking aligned_alloc(%zu, %zu)...\n",
- align[i], size[i]);
- p = aligned_alloc(align[i], size[i]);
- if (p == NULL) {
- if (align[i] == 0 || ((align[i] - 1) & align[i]) != 0 ||
- size[i] % align[i] != 0) {
- ATF_REQUIRE_EQ_MSG(errno, EINVAL,
- "aligned_alloc: %s", strerror(errno));
+ if (size[j] == rounddown(SIZE_MAX, maxaligntest)) {
+ ATF_CHECK_EQ_MSG(p, NULL,
+ "aligned_alloc(%zu, %zu): %p, %s",
+ align[i], size[j], p, strerror(errno));
+ switch (errno) {
+ case EINVAL:
+ case ENOMEM:
+ break;
+ default:
+ atf_tc_fail_nonfatal(
+ "%s:%d:"
+ " aligned_alloc(%zu, %zu): %s",
+ __FILE__, __LINE__,
+ align[i], size[j],
+ strerror(errno));
+ break;
+ }
+ continue;
}
- else {
- ATF_REQUIRE_EQ_MSG(errno, ENOMEM,
- "aligned_alloc: %s", strerror(errno));
+
+ /*
+ * Allocation should fail only if the alignment
+ * isn't supported, in which case it will fail
+ * with EINVAL. No standard criterion for what
+ * alignments are supported, so just stop here
+ * on EINVAL.
+ */
+ if (p == NULL && errno == EINVAL)
+ continue;
+
+ ATF_CHECK_EQ_MSG((intptr_t)p & (align[i] - 1), 0,
+ "aligned_alloc(%zu, %zu): %p",
+ align[i], size[j], p);
+ if (size[j] != 0) {
+ if (p == NULL) {
+ atf_tc_fail_nonfatal(
+ "%s:%d:"
+ " aligned_alloc(&p, %zu, %zu):"
+ " %p, %s",
+ __FILE__, __LINE__,
+ align[i], size[j], p,
+ strerror(errno));
+ }
+ } else {
+ /*
+ * No guarantees about whether
+ * zero-size allocation yields null
+ * pointer or something else.
+ */
}
- }
- else {
- ATF_REQUIRE_EQ_MSG(align[i] == 0, false,
- "aligned_alloc: success when alignment was not "
- "a power of 2");
- ATF_REQUIRE_EQ_MSG((align[i] - 1) & align[i], 0,
- "aligned_alloc: success when alignment was not "
- "a power of 2");
- ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0,
- "p = %p", p);
+
free(p);
}
}
@@ -131,8 +246,9 @@ ATF_TC_BODY(aligned_alloc_basic, tc)
ATF_TP_ADD_TCS(tp)
{
+
ATF_TP_ADD_TC(tp, posix_memalign_basic);
- ATF_TP_ADD_TC(tp, aligned_alloc_basic);
-
+ ATF_TP_ADD_TC(tp, aligned_alloc_basic);
+
return atf_no_error();
}
Home |
Main Index |
Thread Index |
Old Index