Make memcmp() and memchr() go fast again

Readahead within the specified size is legal, even if it overlaps a page
boundary; it's the fault of the caller if that causes a segfault.
This commit is contained in:
Justine Tunney 2023-11-29 05:17:21 -08:00
parent 70155df7a9
commit ff955aaa01
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
4 changed files with 137 additions and 49 deletions

View file

@ -16,24 +16,10 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/runtime/runtime.h"
#include "libc/runtime/sysconf.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#include "libc/testlib/testlib.h"
TEST(memchr, test) {
const char *s = "hello";
ASSERT_EQ(s + 1, memchr(s, 'e', 5));
}
TEST(memchr, pageOverlapTorture) {
long pagesz = sysconf(_SC_PAGESIZE);
char *map = mmap(0, pagesz * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
ASSERT_SYS(0, 0, mprotect(map + pagesz, pagesz, PROT_NONE));
strcpy(map + pagesz - 9, "12345678");
EXPECT_EQ(map + pagesz - 1, memchr(map + pagesz - 9, 0, 79));
EXPECT_SYS(0, 0, munmap(map, pagesz * 2));
}

View file

@ -113,21 +113,6 @@ TEST(memcmp, fuzz) {
}
}
TEST(memcmp, pageOverlapTorture) {
long pagesz = sysconf(_SC_PAGESIZE);
char *map = mmap(0, pagesz * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
char *map2 = mmap(0, pagesz * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
ASSERT_SYS(0, 0, mprotect(map + pagesz, pagesz, PROT_NONE));
ASSERT_SYS(0, 0, mprotect(map2 + pagesz, pagesz, PROT_NONE));
strcpy(map + pagesz - 9, "12345678");
strcpy(map2 + pagesz - 9, "12345679");
EXPECT_LT(memcmp(map + pagesz - 9, map2 + pagesz - 9, 79), 0);
EXPECT_SYS(0, 0, munmap(map2, pagesz * 2));
EXPECT_SYS(0, 0, munmap(map, pagesz * 2));
}
int buncmp(const void *, const void *, size_t) asm("bcmp");
int funcmp(const void *, const void *, size_t) asm("memcmp");