mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-08 04:08:32 +00:00
Make numerous improvements
- Python static hello world now 1.8mb - Python static fully loaded now 10mb - Python HTTPS client now uses MbedTLS - Python REPL now completes import stmts - Increase stack size for Python for now - Begin synthesizing posixpath and ntpath - Restore Python \N{UNICODE NAME} support - Restore Python NFKD symbol normalization - Add optimized code path for Intel SHA-NI - Get more Python unit tests passing faster - Get Python help() pagination working on NT - Python hashlib now supports MbedTLS PBKDF2 - Make memcpy/memmove/memcmp/bcmp/etc. faster - Add Mersenne Twister and Vigna to LIBC_RAND - Provide privileged __printf() for error code - Fix zipos opendir() so that it reports ENOTDIR - Add basic chmod() implementation for Windows NT - Add Cosmo's best functions to Python cosmo module - Pin function trace indent depth to that of caller - Show memory diagram on invalid access in MODE=dbg - Differentiate stack overflow on crash in MODE=dbg - Add stb_truetype and tools for analyzing font files - Upgrade to UNICODE 13 and reduce its binary footprint - COMPILE.COM now logs resource usage of build commands - Start implementing basic poll() support on bare metal - Set getauxval(AT_EXECFN) to GetModuleFileName() on NT - Add descriptions to strerror() in non-TINY build modes - Add COUNTBRANCH() macro to help with micro-optimizations - Make error / backtrace / asan / memory code more unbreakable - Add fast perfect C implementation of μ-Law and a-Law audio codecs - Make strtol() functions consistent with other libc implementations - Improve Linenoise implementation (see also github.com/jart/bestline) - COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
parent
fa7b4f5bd1
commit
39bf41f4eb
806 changed files with 77494 additions and 63859 deletions
|
@ -17,8 +17,14 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(asan, test) {
|
||||
|
@ -40,3 +46,45 @@ TEST(asan, test) {
|
|||
EXPECT_TRUE(__asan_is_valid(p + 1, 64 + 2));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 1, 64 + 3));
|
||||
}
|
||||
|
||||
TEST(asan, testEmptySize_isAlwaysValid) {
|
||||
if (!IsAsan()) return;
|
||||
EXPECT_TRUE(__asan_is_valid(0, 0));
|
||||
EXPECT_TRUE(__asan_is_valid((void *)(intptr_t)-2, 0));
|
||||
EXPECT_TRUE(__asan_is_valid((void *)(intptr_t)9999, 0));
|
||||
}
|
||||
|
||||
TEST(asan, testBigSize_worksFine) {
|
||||
char *p;
|
||||
if (!IsAsan()) return;
|
||||
p = malloc(64 * 1024);
|
||||
EXPECT_TRUE(__asan_is_valid(p, 64 * 1024));
|
||||
EXPECT_FALSE(__asan_is_valid(p - 1, 64 * 1024));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 1, 64 * 1024));
|
||||
EXPECT_TRUE(__asan_is_valid(p + 1, 64 * 1024 - 1));
|
||||
free(p);
|
||||
}
|
||||
|
||||
TEST(asan, testUnmappedShadowMemory_doesntSegfault) {
|
||||
if (!IsAsan()) return;
|
||||
EXPECT_FALSE(__asan_is_valid(0, 1));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)-1, 1));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)-2, 1));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)9999, 1));
|
||||
EXPECT_FALSE(__asan_is_valid(0, 7));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)-1, 7));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)-2, 7));
|
||||
EXPECT_FALSE(__asan_is_valid((void *)(intptr_t)9999, 7));
|
||||
}
|
||||
|
||||
BENCH(asan, bench) {
|
||||
char *p;
|
||||
size_t n, m;
|
||||
if (!IsAsan()) return;
|
||||
m = 4 * 1024 * 1024;
|
||||
p = gc(malloc(m));
|
||||
EZBENCH_N("__asan_check", 0, __asan_check(p, 0));
|
||||
for (n = 2; n <= m; n *= 2) {
|
||||
EZBENCH_N("__asan_check", n, __asan_check(p, n));
|
||||
}
|
||||
}
|
||||
|
|
341
test/libc/intrin/memcmp_test.c
Normal file
341
test/libc/intrin/memcmp_test.c
Normal file
|
@ -0,0 +1,341 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/fastrandomstring.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
int golden(const void *p, const void *q, size_t n) {
|
||||
int c;
|
||||
size_t i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
if ((c = ((const unsigned char *)p)[i] - ((const unsigned char *)q)[i])) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST(memcmp, test) {
|
||||
EXPECT_EQ(0, memcmp("hi", "hi", 2));
|
||||
EXPECT_NE(0, memcmp("hi", "HI", 2));
|
||||
EXPECT_EQ(-1, memcmp("a", "b", 1));
|
||||
EXPECT_EQ(+1, memcmp("b", "a", 1));
|
||||
}
|
||||
|
||||
TEST(memcmp, hug) {
|
||||
int i, j, g;
|
||||
char a[128] = {0};
|
||||
char b[128] = {0};
|
||||
for (j = 0; j < 128; ++j) {
|
||||
for (i = 0; i < j; ++i) {
|
||||
a[i] = 1;
|
||||
g = golden(a, b, j);
|
||||
ASSERT_EQ(g, memcmp(a, b, j), "i=%d j=%d", i, j);
|
||||
ASSERT_EQ(!!g, !!bcmp(a, b, j), "i=%d j=%d", i, j);
|
||||
ASSERT_EQ(!!g, !!timingsafe_bcmp(a, b, j), "i=%d", i);
|
||||
ASSERT_EQ(MAX(-1, MIN(1, g)), timingsafe_memcmp(a, b, j), "i=%d", i);
|
||||
a[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(memcmp, fuzz) {
|
||||
int i, o, n, g;
|
||||
char a[256], b[256];
|
||||
for (i = 0; i < 100000; ++i) {
|
||||
rngset(a, sizeof(a), rand64, -1);
|
||||
memcpy(b, a, sizeof(a));
|
||||
if (rand() & 1) {
|
||||
a[rand() % sizeof(a)] += rand();
|
||||
} else {
|
||||
b[rand() % sizeof(a)] += rand();
|
||||
}
|
||||
if (rand() & 1) {
|
||||
a[rand() % sizeof(a)] += rand();
|
||||
} else {
|
||||
b[rand() % sizeof(a)] += rand();
|
||||
}
|
||||
o = rand() & 31;
|
||||
n = rand() % (sizeof(a) - o);
|
||||
g = golden(a + o, b + o, n);
|
||||
ASSERT_EQ(g, memcmp(a + o, b + o, n), "n=%d o=%d", n, o);
|
||||
ASSERT_EQ(!!g, !!bcmp(a + o, b + o, n), "n=%d o=%d", n, o);
|
||||
ASSERT_EQ(!!g, !!timingsafe_bcmp(a + o, b + o, n), "n=%d o=%d", n, o);
|
||||
ASSERT_EQ(MAX(-1, MIN(1, g)), timingsafe_memcmp(a + o, b + o, n),
|
||||
"n=%d o=%d", n, o);
|
||||
}
|
||||
}
|
||||
|
||||
int buncmp(const void *, const void *, size_t) asm("bcmp");
|
||||
int funcmp(const void *, const void *, size_t) asm("memcmp");
|
||||
|
||||
BENCH(bcmp, bench) {
|
||||
volatile int v;
|
||||
const char *volatile a;
|
||||
const char *volatile b;
|
||||
b = a = "123456789123456789123456789123456789123456789123456789";
|
||||
b = gc(strdup(b));
|
||||
EZBENCH_N("bcmp", 0, v = buncmp(a, b, 0));
|
||||
EZBENCH_N("bcmp", 1, v = buncmp(a, b, 1));
|
||||
EZBENCH_N("bcmp", 2, v = buncmp(a, b, 2));
|
||||
EZBENCH_N("bcmp", 3, v = buncmp(a, b, 3));
|
||||
EZBENCH_N("𝗯𝗰𝗺𝗽", 4, v = buncmp(a, b, 4));
|
||||
EZBENCH_N("bcmp", 5, v = buncmp(a, b, 5));
|
||||
EZBENCH_N("bcmp", 6, v = buncmp(a, b, 6));
|
||||
EZBENCH_N("bcmp", 7, v = buncmp(a, b, 7));
|
||||
EZBENCH_N("𝗯𝗰𝗺𝗽", 8, v = buncmp(a, b, 8));
|
||||
EZBENCH_N("bcmp", 9, v = buncmp(a, b, 9));
|
||||
EZBENCH_N("bcmp", 15, v = buncmp(a, b, 15));
|
||||
EZBENCH_N("𝗯𝗰𝗺𝗽", 16, v = buncmp(a, b, 16));
|
||||
EZBENCH_N("bcmp", 17, v = buncmp(a, b, 17));
|
||||
EZBENCH_N("bcmp", 31, v = buncmp(a, b, 31));
|
||||
EZBENCH_N("bcmp", 32, v = buncmp(a, b, 32));
|
||||
a = kHyperion;
|
||||
b = gc(strdup(kHyperion));
|
||||
EZBENCH_N("bcmp", 33, v = buncmp(a, b, 33));
|
||||
EZBENCH_N("bcmp", 79, v = buncmp(a, b, 79));
|
||||
EZBENCH_N("𝗯𝗰𝗺𝗽", 80, v = buncmp(a, b, 80));
|
||||
EZBENCH_N("bcmp", 128, v = buncmp(a, b, 128));
|
||||
EZBENCH_N("bcmp", 256, v = buncmp(a, b, 256));
|
||||
a = gc(malloc(16 * 1024));
|
||||
b = gc(malloc(16 * 1024));
|
||||
rngset(a, 16 * 1024, vigna, -1);
|
||||
memcpy(b, a, 16 * 1024);
|
||||
EZBENCH_N("bcmp", 16384, v = buncmp(a, b, 16384));
|
||||
a = gc(malloc(32 * 1024));
|
||||
b = gc(malloc(32 * 1024));
|
||||
rngset(a, 32 * 1024, vigna, -1);
|
||||
memcpy(b, a, 32 * 1024);
|
||||
EZBENCH_N("bcmp", 32768, v = buncmp(a, b, 32768));
|
||||
a = gc(malloc(128 * 1024));
|
||||
b = gc(malloc(128 * 1024));
|
||||
rngset(a, 128 * 1024, vigna, -1);
|
||||
memcpy(b, a, 128 * 1024);
|
||||
EZBENCH_N("bcmp", 131072, v = buncmp(a, b, 131072));
|
||||
}
|
||||
|
||||
BENCH(memcmp, bench) {
|
||||
volatile int v;
|
||||
const char *volatile a;
|
||||
const char *volatile b;
|
||||
b = a = "123456789123456789123456789123456789123456789123456789";
|
||||
b = gc(strdup(b));
|
||||
EZBENCH_N("memcmp", 0, v = funcmp(a, b, 0));
|
||||
EZBENCH_N("memcmp", 1, v = funcmp(a, b, 1));
|
||||
EZBENCH_N("memcmp", 2, v = funcmp(a, b, 2));
|
||||
EZBENCH_N("memcmp", 3, v = funcmp(a, b, 3));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗺𝗽", 4, v = funcmp(a, b, 4));
|
||||
EZBENCH_N("memcmp", 5, v = funcmp(a, b, 5));
|
||||
EZBENCH_N("memcmp", 6, v = funcmp(a, b, 6));
|
||||
EZBENCH_N("memcmp", 7, v = funcmp(a, b, 7));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗺𝗽", 8, v = funcmp(a, b, 8));
|
||||
EZBENCH_N("memcmp", 9, v = funcmp(a, b, 9));
|
||||
EZBENCH_N("memcmp", 15, v = funcmp(a, b, 15));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗺𝗽", 16, v = funcmp(a, b, 16));
|
||||
EZBENCH_N("memcmp", 17, v = funcmp(a, b, 17));
|
||||
EZBENCH_N("memcmp", 31, v = funcmp(a, b, 31));
|
||||
EZBENCH_N("memcmp", 32, v = funcmp(a, b, 32));
|
||||
a = kHyperion;
|
||||
b = gc(strdup(kHyperion));
|
||||
EZBENCH_N("memcmp", 33, v = funcmp(a, b, 33));
|
||||
EZBENCH_N("memcmp", 79, v = funcmp(a, b, 79));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗺𝗽", 80, v = funcmp(a, b, 80));
|
||||
EZBENCH_N("memcmp", 128, v = funcmp(a, b, 128));
|
||||
EZBENCH_N("memcmp", 256, v = funcmp(a, b, 256));
|
||||
a = gc(malloc(16 * 1024));
|
||||
b = gc(malloc(16 * 1024));
|
||||
rngset(a, 16 * 1024, vigna, -1);
|
||||
memcpy(b, a, 16 * 1024);
|
||||
EZBENCH_N("memcmp", 16384, v = funcmp(a, b, 16384));
|
||||
a = gc(malloc(32 * 1024));
|
||||
b = gc(malloc(32 * 1024));
|
||||
rngset(a, 32 * 1024, vigna, -1);
|
||||
memcpy(b, a, 32 * 1024);
|
||||
EZBENCH_N("memcmp", 32768, v = funcmp(a, b, 32768));
|
||||
a = gc(malloc(128 * 1024));
|
||||
b = gc(malloc(128 * 1024));
|
||||
rngset(a, 128 * 1024, vigna, -1);
|
||||
memcpy(b, a, 128 * 1024);
|
||||
EZBENCH_N("memcmp", 131072, v = funcmp(a, b, 131072));
|
||||
}
|
||||
|
||||
BENCH(timingsafe_memcmp, bench) {
|
||||
volatile int v;
|
||||
const char *volatile a;
|
||||
const char *volatile b;
|
||||
b = a = "123456789123456789123456789123456789123456789123456789";
|
||||
b = gc(strdup(b));
|
||||
EZBENCH_N("timingsafe_memcmp", 0, v = timingsafe_memcmp(a, b, 0));
|
||||
EZBENCH_N("timingsafe_memcmp", 1, v = timingsafe_memcmp(a, b, 1));
|
||||
EZBENCH_N("timingsafe_memcmp", 2, v = timingsafe_memcmp(a, b, 2));
|
||||
EZBENCH_N("timingsafe_memcmp", 3, v = timingsafe_memcmp(a, b, 3));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗺𝗲𝗺𝗰𝗺𝗽", 4, v = timingsafe_memcmp(a, b, 4));
|
||||
EZBENCH_N("timingsafe_memcmp", 5, v = timingsafe_memcmp(a, b, 5));
|
||||
EZBENCH_N("timingsafe_memcmp", 6, v = timingsafe_memcmp(a, b, 6));
|
||||
EZBENCH_N("timingsafe_memcmp", 7, v = timingsafe_memcmp(a, b, 7));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗺𝗲𝗺𝗰𝗺𝗽", 8, v = timingsafe_memcmp(a, b, 8));
|
||||
EZBENCH_N("timingsafe_memcmp", 9, v = timingsafe_memcmp(a, b, 9));
|
||||
EZBENCH_N("timingsafe_memcmp", 15, v = timingsafe_memcmp(a, b, 15));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗺𝗲𝗺𝗰𝗺𝗽", 16, v = timingsafe_memcmp(a, b, 16));
|
||||
EZBENCH_N("timingsafe_memcmp", 17, v = timingsafe_memcmp(a, b, 17));
|
||||
EZBENCH_N("timingsafe_memcmp", 31, v = timingsafe_memcmp(a, b, 31));
|
||||
EZBENCH_N("timingsafe_memcmp", 32, v = timingsafe_memcmp(a, b, 32));
|
||||
a = kHyperion;
|
||||
b = gc(strdup(kHyperion));
|
||||
EZBENCH_N("timingsafe_memcmp", 33, v = timingsafe_memcmp(a, b, 33));
|
||||
EZBENCH_N("timingsafe_memcmp", 79, v = timingsafe_memcmp(a, b, 79));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗺𝗲𝗺𝗰𝗺𝗽", 80, v = timingsafe_memcmp(a, b, 80));
|
||||
EZBENCH_N("timingsafe_memcmp", 128, v = timingsafe_memcmp(a, b, 128));
|
||||
EZBENCH_N("timingsafe_memcmp", 256, v = timingsafe_memcmp(a, b, 256));
|
||||
a = gc(malloc(16 * 1024));
|
||||
b = gc(malloc(16 * 1024));
|
||||
rngset(a, 16 * 1024, vigna, -1);
|
||||
memcpy(b, a, 16 * 1024);
|
||||
EZBENCH_N("timingsafe_memcmp", 16384, v = timingsafe_memcmp(a, b, 16384));
|
||||
a = gc(malloc(32 * 1024));
|
||||
b = gc(malloc(32 * 1024));
|
||||
rngset(a, 32 * 1024, vigna, -1);
|
||||
memcpy(b, a, 32 * 1024);
|
||||
EZBENCH_N("timingsafe_memcmp", 32768, v = timingsafe_memcmp(a, b, 32768));
|
||||
a = gc(malloc(128 * 1024));
|
||||
b = gc(malloc(128 * 1024));
|
||||
rngset(a, 128 * 1024, vigna, -1);
|
||||
memcpy(b, a, 128 * 1024);
|
||||
EZBENCH_N("timingsafe_memcmp", 131072, v = timingsafe_memcmp(a, b, 131072));
|
||||
}
|
||||
|
||||
BENCH(timingsafe_bcmp, bench) {
|
||||
volatile int v;
|
||||
const char *volatile a;
|
||||
const char *volatile b;
|
||||
b = a = "123456789123456789123456789123456789123456789123456789";
|
||||
b = gc(strdup(b));
|
||||
EZBENCH_N("timingsafe_bcmp", 0, v = timingsafe_bcmp(a, b, 0));
|
||||
EZBENCH_N("timingsafe_bcmp", 1, v = timingsafe_bcmp(a, b, 1));
|
||||
EZBENCH_N("timingsafe_bcmp", 2, v = timingsafe_bcmp(a, b, 2));
|
||||
EZBENCH_N("timingsafe_bcmp", 3, v = timingsafe_bcmp(a, b, 3));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗯𝗰𝗺𝗽", 4, v = timingsafe_bcmp(a, b, 4));
|
||||
EZBENCH_N("timingsafe_bcmp", 5, v = timingsafe_bcmp(a, b, 5));
|
||||
EZBENCH_N("timingsafe_bcmp", 6, v = timingsafe_bcmp(a, b, 6));
|
||||
EZBENCH_N("timingsafe_bcmp", 7, v = timingsafe_bcmp(a, b, 7));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗯𝗰𝗺𝗽", 8, v = timingsafe_bcmp(a, b, 8));
|
||||
EZBENCH_N("timingsafe_bcmp", 9, v = timingsafe_bcmp(a, b, 9));
|
||||
EZBENCH_N("timingsafe_bcmp", 15, v = timingsafe_bcmp(a, b, 15));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗯𝗰𝗺𝗽", 16, v = timingsafe_bcmp(a, b, 16));
|
||||
EZBENCH_N("timingsafe_bcmp", 17, v = timingsafe_bcmp(a, b, 17));
|
||||
EZBENCH_N("timingsafe_bcmp", 31, v = timingsafe_bcmp(a, b, 31));
|
||||
EZBENCH_N("timingsafe_bcmp", 32, v = timingsafe_bcmp(a, b, 32));
|
||||
a = kHyperion;
|
||||
b = gc(strdup(kHyperion));
|
||||
EZBENCH_N("timingsafe_bcmp", 33, v = timingsafe_bcmp(a, b, 33));
|
||||
EZBENCH_N("timingsafe_bcmp", 79, v = timingsafe_bcmp(a, b, 79));
|
||||
EZBENCH_N("𝘁𝗶𝗺𝗶𝗻𝗴𝘀𝗮𝗳𝗲_𝗯𝗰𝗺𝗽", 80, v = timingsafe_bcmp(a, b, 80));
|
||||
EZBENCH_N("timingsafe_bcmp", 128, v = timingsafe_bcmp(a, b, 128));
|
||||
EZBENCH_N("timingsafe_bcmp", 256, v = timingsafe_bcmp(a, b, 256));
|
||||
a = gc(malloc(16 * 1024));
|
||||
b = gc(malloc(16 * 1024));
|
||||
rngset(a, 16 * 1024, vigna, -1);
|
||||
memcpy(b, a, 16 * 1024);
|
||||
EZBENCH_N("timingsafe_bcmp", 16384, v = timingsafe_bcmp(a, b, 16384));
|
||||
a = gc(malloc(32 * 1024));
|
||||
b = gc(malloc(32 * 1024));
|
||||
rngset(a, 32 * 1024, vigna, -1);
|
||||
memcpy(b, a, 32 * 1024);
|
||||
EZBENCH_N("timingsafe_bcmp", 32768, v = timingsafe_bcmp(a, b, 32768));
|
||||
a = gc(malloc(128 * 1024));
|
||||
b = gc(malloc(128 * 1024));
|
||||
rngset(a, 128 * 1024, vigna, -1);
|
||||
memcpy(b, a, 128 * 1024);
|
||||
EZBENCH_N("timingsafe_bcmp", 131072, v = timingsafe_bcmp(a, b, 131072));
|
||||
}
|
||||
|
||||
BENCH(memcasecmp, bench) {
|
||||
volatile int v;
|
||||
const char *volatile a;
|
||||
const char *volatile b;
|
||||
b = a = "123456789123456789123456789123456789123456789123456789";
|
||||
b = gc(strdup(b));
|
||||
EZBENCH_N("memcasecmp", 0, v = memcasecmp(a, b, 0));
|
||||
EZBENCH_N("memcasecmp", 1, v = memcasecmp(a, b, 1));
|
||||
EZBENCH_N("memcasecmp", 2, v = memcasecmp(a, b, 2));
|
||||
EZBENCH_N("memcasecmp", 3, v = memcasecmp(a, b, 3));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗮𝘀𝗲𝗰𝗺𝗽", 4, v = memcasecmp(a, b, 4));
|
||||
EZBENCH_N("memcasecmp", 5, v = memcasecmp(a, b, 5));
|
||||
EZBENCH_N("memcasecmp", 6, v = memcasecmp(a, b, 6));
|
||||
EZBENCH_N("memcasecmp", 7, v = memcasecmp(a, b, 7));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗮𝘀𝗲𝗰𝗺𝗽", 8, v = memcasecmp(a, b, 8));
|
||||
EZBENCH_N("memcasecmp", 9, v = memcasecmp(a, b, 9));
|
||||
EZBENCH_N("memcasecmp", 15, v = memcasecmp(a, b, 15));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗮𝘀𝗲𝗰𝗺𝗽", 16, v = memcasecmp(a, b, 16));
|
||||
EZBENCH_N("memcasecmp", 17, v = memcasecmp(a, b, 17));
|
||||
EZBENCH_N("memcasecmp", 31, v = memcasecmp(a, b, 31));
|
||||
EZBENCH_N("memcasecmp", 32, v = memcasecmp(a, b, 32));
|
||||
a = kHyperion;
|
||||
b = gc(strdup(kHyperion));
|
||||
EZBENCH_N("memcasecmp", 33, v = memcasecmp(a, b, 33));
|
||||
EZBENCH_N("memcasecmp", 79, v = memcasecmp(a, b, 79));
|
||||
EZBENCH_N("𝗺𝗲𝗺𝗰𝗮𝘀𝗲𝗰𝗺𝗽", 80, v = memcasecmp(a, b, 80));
|
||||
EZBENCH_N("memcasecmp", 128, v = memcasecmp(a, b, 128));
|
||||
EZBENCH_N("memcasecmp", 256, v = memcasecmp(a, b, 256));
|
||||
a = gc(malloc(16 * 1024));
|
||||
b = gc(malloc(16 * 1024));
|
||||
rngset(a, 16 * 1024, vigna, -1);
|
||||
memcpy(b, a, 16 * 1024);
|
||||
EZBENCH_N("memcasecmp", 16384, v = memcasecmp(a, b, 16384));
|
||||
a = gc(malloc(32 * 1024));
|
||||
b = gc(malloc(32 * 1024));
|
||||
rngset(a, 32 * 1024, vigna, -1);
|
||||
memcpy(b, a, 32 * 1024);
|
||||
EZBENCH_N("memcasecmp", 32768, v = memcasecmp(a, b, 32768));
|
||||
a = gc(malloc(128 * 1024));
|
||||
b = gc(malloc(128 * 1024));
|
||||
rngset(a, 128 * 1024, vigna, -1);
|
||||
memcpy(b, a, 128 * 1024);
|
||||
EZBENCH_N("memcasecmp", 131072, v = memcasecmp(a, b, 131072));
|
||||
}
|
||||
|
||||
BENCH(timingsafe_memcmp, demonstration) {
|
||||
int bcmp_(const void *, const void *, size_t) asm("bcmp");
|
||||
int memcmp_(const void *, const void *, size_t) asm("memcmp");
|
||||
char a[256], b[256];
|
||||
rngset(a, 256, vigna, -1);
|
||||
memcpy(b, a, 256);
|
||||
++a[0];
|
||||
EZBENCH_N("bcmp ne", 256, bcmp_(a, b, 256));
|
||||
a[0] = b[0];
|
||||
EZBENCH_N("bcmp eq", 256, bcmp_(a, b, 256));
|
||||
++a[0];
|
||||
EZBENCH_N("memcmp ne", 256, memcmp_(a, b, 256));
|
||||
a[0] = b[0];
|
||||
EZBENCH_N("memcmp eq", 256, memcmp_(a, b, 256));
|
||||
++a[0];
|
||||
EZBENCH_N("timingsafe_bcmp ne", 256, timingsafe_bcmp(a, b, 256));
|
||||
a[0] = b[0];
|
||||
EZBENCH_N("timingsafe_bcmp eq", 256, timingsafe_bcmp(a, b, 256));
|
||||
++a[0];
|
||||
EZBENCH_N("timingsafe_memcmp ne", 256, timingsafe_memcmp(a, b, 256));
|
||||
a[0] = b[0];
|
||||
EZBENCH_N("timingsafe_memcmp eq", 256, timingsafe_memcmp(a, b, 256));
|
||||
}
|
97
test/libc/intrin/memmove_test.c
Normal file
97
test/libc/intrin/memmove_test.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
static void *golden(void *a, const void *b, size_t n) {
|
||||
size_t i;
|
||||
char *d = a;
|
||||
const char *s = b;
|
||||
if (d > s) {
|
||||
for (i = n; i--;) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
TEST(memmove, hug) {
|
||||
char *a, *b, *c;
|
||||
int i, o1, o2;
|
||||
int N[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 31, 32, 33, 63, 64, 65, 80, 81, 1000, 1024, 1025};
|
||||
a = gc(malloc(1104));
|
||||
b = gc(malloc(1104));
|
||||
for (o1 = 0; o1 < 48; ++o1) {
|
||||
for (o2 = 0; o2 < 48; ++o2) {
|
||||
for (i = 0; i < ARRAYLEN(N); ++i) {
|
||||
rngset(a, 1104, 0, 0);
|
||||
memcpy(b, a, 1104);
|
||||
ASSERT_EQ(a + o2, golden(a + o2, a + o1, N[i]));
|
||||
ASSERT_EQ(b + o2, memmove(b + o2, b + o1, N[i]));
|
||||
ASSERT_EQ(0, timingsafe_bcmp(a, b, 1104), "%d %d %d", o1, o2, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(memmove, bighug) {
|
||||
char *a, *b, *c;
|
||||
int i, o1, o2;
|
||||
int N[] = {5 * 1024 * 1024};
|
||||
a = gc(malloc(6291456));
|
||||
b = gc(malloc(6291456));
|
||||
for (o1 = 0; o1 < 40; o1 += 10) {
|
||||
for (o2 = 0; o2 < 40; o2 += 10) {
|
||||
for (i = 0; i < ARRAYLEN(N); ++i) {
|
||||
rngset(a, 6291456, 0, 0);
|
||||
memcpy(b, a, 6291456);
|
||||
ASSERT_EQ(a + o2, golden(a + o2, a + o1, N[i]));
|
||||
ASSERT_EQ(b + o2, memmove(b + o2, b + o1, N[i]));
|
||||
ASSERT_EQ(0, timingsafe_bcmp(a, b, 6291456), "%d %d %d", o1, o2, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(memmove, bench) {
|
||||
volatile char *r;
|
||||
int n, max = 8 * 1024 * 1024;
|
||||
char *volatile p = gc(calloc(max, 1));
|
||||
char *volatile q = gc(calloc(max, 1));
|
||||
EZBENCH_N("memmove", 0, memmove(p, q, 0));
|
||||
for (n = 0; n < 127; ++n) {
|
||||
EZBENCH_N("memmove", n, r = memmove(p, q, n));
|
||||
}
|
||||
for (n = 128; n <= max; n *= 2) {
|
||||
EZBENCH_N("memmove", n - 1, r = memmove(p, q, n - 1));
|
||||
EZBENCH_N("memmove", n, r = memmove(p, q, n));
|
||||
}
|
||||
}
|
95
test/libc/intrin/memset_test.c
Normal file
95
test/libc/intrin/memset_test.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
static void *golden(void *p, int c, size_t n) {
|
||||
size_t i;
|
||||
for (i = 0; i < n; ++i) ((char *)p)[i] = c;
|
||||
return p;
|
||||
}
|
||||
|
||||
TEST(memset, hug) {
|
||||
char *a, *b;
|
||||
int i, j, c;
|
||||
for (i = 0; i < 1025; ++i) {
|
||||
for (j = 0; j < 1025 - i; ++j) {
|
||||
a = malloc(i + j);
|
||||
b = malloc(i + j);
|
||||
c = vigna();
|
||||
rngset(a, i + j, vigna, 0);
|
||||
memcpy(b, a, i + j);
|
||||
ASSERT_EQ(a + i, golden(a + i, c, j));
|
||||
ASSERT_EQ(b + i, memset(b + i, c, j));
|
||||
ASSERT_EQ(0, timingsafe_bcmp(a, b, i + j));
|
||||
free(b);
|
||||
free(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(bzero, hug) {
|
||||
char *a, *b;
|
||||
int i, j;
|
||||
for (i = 0; i < 1025; ++i) {
|
||||
for (j = 0; j < 1025 - i; ++j) {
|
||||
a = malloc(i + j);
|
||||
b = malloc(i + j);
|
||||
rngset(a, i + j, vigna, 0);
|
||||
memcpy(b, a, i + j);
|
||||
golden(a + i, 0, j);
|
||||
bzero(b + i, j);
|
||||
ASSERT_EQ(0, timingsafe_bcmp(a, b, i + j));
|
||||
free(b);
|
||||
free(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(memset, bench) {
|
||||
int n, max = 8 * 1024 * 1024;
|
||||
char *volatile p = gc(malloc(max));
|
||||
EZBENCH_N("memset", 0, memset(p, -1, 0));
|
||||
for (n = 2; n <= max; n *= 2) {
|
||||
EZBENCH_N("memset", n - 1, memset(p, -1, n - 1));
|
||||
EZBENCH_N("memset", n, memset(p, -1, n));
|
||||
}
|
||||
EZBENCH_N("bzero", 0, bzero(p, 0));
|
||||
for (n = 2; n <= max; n *= 2) {
|
||||
EZBENCH_N("bzero", n - 1, bzero(p, n - 1));
|
||||
EZBENCH_N("bzero", n, bzero(p, n));
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(strlen, bench) {
|
||||
volatile size_t r;
|
||||
int n, max = 8 * 1024 * 1024;
|
||||
char *volatile p = gc(calloc(max + 1, 1));
|
||||
EZBENCH_N("strlen", 0, strlen(p));
|
||||
for (n = 2; n <= max; n *= 2) {
|
||||
memset(p, -1, n - 1);
|
||||
EZBENCH_N("strlen", n - 1, r = strlen(p));
|
||||
p[n - 1] = -1;
|
||||
EZBENCH_N("strlen", n, r = strlen(p));
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ TEST_LIBC_INTRIN_CHECKS = \
|
|||
$(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_LIBC_INTRIN_DIRECTDEPS = \
|
||||
LIBC_CALLS \
|
||||
LIBC_STDIO \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_LOG \
|
||||
|
@ -53,6 +55,10 @@ o/$(MODE)/test/libc/intrin/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_INTRIN_OBJS): \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-fno-builtin
|
||||
|
||||
.PHONY: o/$(MODE)/test/libc/intrin
|
||||
o/$(MODE)/test/libc/intrin: \
|
||||
$(TEST_LIBC_INTRIN_BINS) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue