aboutsummaryrefslogtreecommitdiffstats
path: root/libsimple.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsimple.c')
-rw-r--r--libsimple.c352
1 files changed, 309 insertions, 43 deletions
diff --git a/libsimple.c b/libsimple.c
index 4ef6ec2..5232833 100644
--- a/libsimple.c
+++ b/libsimple.c
@@ -6,27 +6,6 @@
#else
#include "test.h"
-static size_t
-gcd(size_t u, size_t v)
-{
- size_t t;
- int shift = 0;
- /* Not needed because u>0, v>0: if (!(u | v)) return u + v; */
- while (!((u | v) & 1)) u >>= 1, v >>= 1, shift++;
- while (!(u & 1)) u >>= 1;
- do {
- while (!(v & 1)) v >>= 1;
- if (u > v) t = u, u = v, v = t;
- } while (v -= u);
- return u << shift;
-}
-
-static size_t
-lcm(size_t u, size_t v)
-{
- return u / gcd(u, v) * v;
-}
-
static int
test_timespec(double d, time_t sec, long int nsec, double rd, const char *s, const char *ss)
{
@@ -109,22 +88,17 @@ int
main(void)
{
struct allocinfo *volatile info;
- void *ptr;
+ void *ptr, *old;
struct timespec ts, ts1, ts2;
struct timeval tv1, tv2;
const char *cs;
+ const wchar_t *cws;
char buf[1024], *s;
+ wchar_t *ws;
int intarray[10];
size_t i, j, n;
- size_t pagesize, cacheline;
-
- pagesize = (size_t)sysconf(_SC_PAGESIZE);
-
-#ifdef _SC_LEVEL1_DCACHE_LINESIZE
- cacheline = (size_t)sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
-#else
- cacheline = 64;
-#endif
+ DEFINE_PAGESIZE;
+ DEFINE_CACHELINE;
assert(libsimple_default_failure_exit == 1);
@@ -734,6 +708,7 @@ main(void)
s = libsimple_memdupa(cs, n);
assert(s);
assert(s != cs);
+ assert(!((uintptr_t)s % _Alignof(max_align_t)));
assert(!memcmp(s, cs, n));
}
#else
@@ -743,14 +718,253 @@ main(void)
#ifdef libsimple_aligned_memdupa
cs = "xyz";
for (n = 1; n < 4; n++) {
- s = libsimple_aligned_memdupa(cs, 4 + i, n);
+ for (i = 1; i < 5; i++) {
+ s = libsimple_aligned_memdupa(cs, i, n);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!memcmp(s, cs, n));
+ }
+ }
+#else
+ fprintf(stderr, "warning: libsimple_aligned_memdupa missing\n");
+#endif
+
+#ifdef libsimple_aligned_strdupa
+ for (i = 1; i < 5; i++) {
+ cs = "";
+ s = libsimple_aligned_strdupa(cs, i);
assert(s);
assert(s != cs);
- assert(!((uintptr_t)s % (4 + i)));
- assert(!memcmp(s, cs, n));
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, cs));
+
+ cs = "xyz";
+ s = libsimple_aligned_strdupa(cs, i);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, cs));
}
#else
- fprintf(stderr, "warning: libsimple_aligned_memdupa missing\n");
+ fprintf(stderr, "warning: libsimple_aligned_strdupa missing\n");
+#endif
+
+#ifdef libsimple_aligned_strndupa
+ for (i = 1; i < 5; i++) {
+ cs = "";
+ s = libsimple_aligned_strndupa(cs, i, 5);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, ""));
+
+ cs = "xyz";
+
+ s = libsimple_aligned_strndupa(cs, i, 5);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, "xyz"));
+
+ s = libsimple_aligned_strndupa(cs, i, 4);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, "xyz"));
+
+ s = libsimple_aligned_strndupa(cs, i, 3);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, "xyz"));
+
+ s = libsimple_aligned_strndupa(cs, i, 2);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, "xy"));
+
+ s = libsimple_aligned_strndupa(cs, i, 1);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, "x"));
+
+ s = libsimple_aligned_strndupa(cs, i, 0);
+ assert(s);
+ assert(s != cs);
+ assert(!((uintptr_t)s % i));
+ assert(!strcmp(s, ""));
+ }
+#else
+ fprintf(stderr, "warning: libsimple_aligned_strndupa missing\n");
+#endif
+
+#ifdef libsimple_wcsdupa
+ cws = L"";
+ ws = libsimple_wcsdupa(cws);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, cws));
+
+ cws = L"xyz";
+ ws = libsimple_wcsdupa(cws);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, cws));
+#else
+ fprintf(stderr, "warning: libsimple_wcsdupa missing\n");
+#endif
+
+#ifdef libsimple_wcsndupa
+ cws = L"";
+ ws = libsimple_wcsndupa(cws, 5);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L""));
+
+ cws = L"xyz";
+
+ ws = libsimple_wcsndupa(cws, 5);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_wcsndupa(cws, 4);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_wcsndupa(cws, 3);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_wcsndupa(cws, 2);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L"xy"));
+
+ ws = libsimple_wcsndupa(cws, 1);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L"x"));
+
+ ws = libsimple_wcsndupa(cws, 0);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wcscmp(ws, L""));
+#else
+ fprintf(stderr, "warning: libsimple_wcsndupa missing\n");
+#endif
+
+#ifdef libsimple_wmemdupa
+ cws = L"xyz";
+ for (n = 1; n < 4; n++) {
+ ws = libsimple_wmemdupa(cws, n);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % _Alignof(wchar_t)));
+ assert(!wmemcmp(ws, cws, n));
+ }
+#else
+ fprintf(stderr, "warning: libsimple_wmemdupa missing\n");
+#endif
+
+#ifdef libsimple_aligned_wmemdupa
+ cws = L"xyz";
+ for (n = 1; n < 4; n++) {
+ for (i = 1; i < 5; i++) {
+ ws = libsimple_aligned_wmemdupa(cws, i, n);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wmemcmp(ws, cws, n));
+ }
+ }
+#else
+ fprintf(stderr, "warning: libsimple_aligned_wmemdupa missing\n");
+#endif
+
+#ifdef libsimple_aligned_wcsdupa
+ for (i = 1; i < 5; i++) {
+ cws = L"";
+ ws = libsimple_aligned_wcsdupa(cws, i);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, cws));
+
+ cws = L"xyz";
+ ws = libsimple_aligned_wcsdupa(cws, i);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, cws));
+ }
+#else
+ fprintf(stderr, "warning: libsimple_aligned_wcsdupa missing\n");
+#endif
+
+#ifdef libsimple_aligned_wcsndupa
+ for (i = 1; i < 5; i++) {
+ cws = L"";
+ ws = libsimple_aligned_wcsndupa(cws, i, 5);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L""));
+
+ cws = L"xyz";
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 5);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 4);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 3);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L"xyz"));
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 2);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L"xy"));
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 1);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L"x"));
+
+ ws = libsimple_aligned_wcsndupa(cws, i, 0);
+ assert(ws);
+ assert(ws != cws);
+ assert(!((uintptr_t)ws % i));
+ assert(!wcscmp(ws, L""));
+ }
+#else
+ fprintf(stderr, "warning: libsimple_aligned_wcsndupa missing\n");
#endif
unsetenv("X");
@@ -1049,14 +1263,6 @@ main(void)
tv2.tv_sec = 1, tv2.tv_usec = 0L;
assert(libsimple_cmptimeval(&tv1, &tv2) == -1);
-#define ASSERT_ALIGNMENT(INFO, ALIGN)\
- do {\
- assert((INFO)->alignment <= lcm(cacheline, ALIGN));\
- assert(!((INFO)->alignment % (ALIGN)));\
- if ((cacheline - (ALIGN) % cacheline) % cacheline + (INFO)->size % (ALIGN) > cacheline)\
- assert(!((INFO)->alignment % cacheline));\
- } while (0)
-
assert((ptr = libsimple_mallocz(0, 11)));
if (have_custom_malloc()) {
assert((info = get_allocinfo(ptr)));
@@ -2042,6 +2248,66 @@ main(void)
assert_stderr("%s: libsimple_vmemalignz: %s\n", argv0, strerror(EINVAL));
libsimple_default_failure_exit = 1;
+#ifdef LIBSIMPLE_HAVE_ALIGNED_REALLOC
+ assert((ptr = libsimple_aligned_realloc(NULL, 16, 5)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 5 || info->size == info->alignment);
+ assert(!info->zeroed);
+ ASSERT_ALIGNMENT(info, 16);
+ info->refcount += 1;
+ }
+ stpcpy(ptr, "test");
+ assert((ptr = libsimple_aligned_realloc(old = ptr, 32, 10)));
+ assert(!strcmp(ptr, "test"));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 10 || info->size == info->alignment);
+ assert(!info->zeroed);
+ ASSERT_ALIGNMENT(info, 32);
+ assert(ptr != old);
+ free(old);
+ }
+ free(ptr);
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert(!libsimple_aligned_realloc(NULL, 8, 1) && errno == ENOMEM);
+ assert(!alloc_fail_in);
+ }
+#else
+ assert(libsimple_aligned_realloc(NULL, 8, 1) && errno == ENOSYS);
+#endif
+
+#ifdef LIBSIMPLE_HAVE_ALIGNED_REALLOC
+ assert((ptr = libsimple_aligned_reallocarray(NULL, 16, 5, 3)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 15 || info->size == info->alignment);
+ assert(!info->zeroed);
+ ASSERT_ALIGNMENT(info, 16);
+ info->refcount += 1;
+ }
+ stpcpy(ptr, "test");
+ assert((ptr = libsimple_aligned_reallocarray(old = ptr, 32, 10, 2)));
+ assert(!strcmp(ptr, "test"));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 20 || info->size == info->alignment);
+ assert(!info->zeroed);
+ ASSERT_ALIGNMENT(info, 32);
+ assert(ptr != old);
+ free(old);
+ }
+ free(ptr);
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert(!libsimple_aligned_reallocarray(NULL, 8, 1, 1) && errno == ENOMEM);
+ assert(!alloc_fail_in);
+ }
+#else
+ assert(libsimple_aligned_reallocarray(NULL, 8, 1, 1) && errno == ENOSYS);
+#endif
+
assert(libsimple_memeq("abcxyz", "abc123", 3));
assert(!libsimple_memeq("abcxyz", "abc123", 4));
assert(libsimple_memeq("abcxyz", "abcx23", 4));