Use better memory strategy on Windows

Rather than using the the rollo global to pick addresses, we select them
randomly now using a conservative vaspace.
This commit is contained in:
Justine Tunney 2024-07-20 02:20:03 -07:00
parent 6a5d4ed65b
commit 2018cac11f
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
13 changed files with 113 additions and 124 deletions

View file

@ -82,6 +82,8 @@ TEST(madvise, subPages) {
}
TEST(madvise, madvWillNeed_unmappedRegion) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
@ -96,6 +98,8 @@ TEST(madvise, madvWillNeed_unmappedRegion) {
}
TEST(madvise, madvFree_unmappedRegion) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));

View file

@ -275,6 +275,8 @@ TEST(ksnprintf, testMisalignedPointer_wontFormat) {
}
TEST(ksnprintf, testUnterminatedOverrun_truncatesAtPageBoundary) {
if (IsWindows())
return; // needs carving
char *m;
char b[32];
int gran = getgransize();

View file

@ -41,7 +41,7 @@
void map_unmap_one_page(void) {
void *p;
if ((p = mmap(randaddr(), 1, PROT_READ | PROT_WRITE,
if ((p = mmap(__maps_randaddr(), 1, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)
__builtin_trap();
if (munmap(p, 1))
@ -61,8 +61,8 @@ int main() {
int n = 10000;
kprintf("%20s creating %d sparse maps...\n", "", n);
for (int i = 0; i < n; ++i) {
if (mmap(randaddr(), 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0) == MAP_FAILED)
if (mmap(__maps_randaddr(), 1, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
__builtin_trap();
}

View file

@ -112,20 +112,23 @@ TEST(mmap, fixedTaken) {
TEST(mmap, hint) {
char *p;
if (IsWindows())
return; // needs carving
// obtain four pages
ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), gransz * 4, PROT_READ,
ASSERT_NE(MAP_FAILED, (p = mmap(__maps_randaddr(), pagesz * 4, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
// unmap two of those pages
EXPECT_SYS(0, 0, munmap(p + gransz, gransz));
EXPECT_SYS(0, 0, munmap(p + gransz * 3, gransz));
EXPECT_SYS(0, 0, munmap(p + pagesz, pagesz));
EXPECT_SYS(0, 0, munmap(p + pagesz * 3, pagesz));
// test AVAILABLE nonfixed nonzero addr is granted
// - posix doesn't mandate this behavior (but should)
// - freebsd always chooses for you (which has no acceptable workaround)
// - netbsd manual claims it'll be like freebsd, but is actually like openbsd
if (!IsFreebsd())
ASSERT_EQ(p + gransz, mmap(p + gransz, gransz, PROT_READ,
ASSERT_EQ(p + pagesz, mmap(p + pagesz, pagesz, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
// test UNAVAILABLE nonfixed nonzero addr picks something nearby
@ -134,23 +137,26 @@ TEST(mmap, hint) {
// - freebsd goes about 16mb to the right
// - qemu-user is off the wall
/*if (!IsQemuUser()) {
q = mmap(p + gransz * 2, gransz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1,
q = mmap(p + pagesz * 2, pagesz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1,
0);
EXPECT_LE(ABS(q - (p + gransz * 2)), 128 * 1024 * 1024);
EXPECT_SYS(0, 0, munmap(q, gransz));
EXPECT_LE(ABS(q - (p + pagesz * 2)), 128 * 1024 * 1024);
EXPECT_SYS(0, 0, munmap(q, pagesz));
}*/
// clean up
EXPECT_SYS(0, 0, munmap(p, gransz * 4));
EXPECT_SYS(0, 0, munmap(p, pagesz * 4));
}
TEST(mprotect, punchHoleAndFillHole) {
char *p;
int count = __maps.count;
if (IsWindows())
return; // needs carving
// obtain memory
ASSERT_NE(MAP_FAILED,
(p = mmap(randaddr(), gransz * 3, PROT_READ | PROT_WRITE,
(p = mmap(__maps_randaddr(), gransz * 3, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
ASSERT_EQ((count += IsWindows() ? 3 : 1), __maps.count);

View file

@ -259,6 +259,8 @@ TEST(mprotect, weirdSize) {
}
TEST(mprotect, outerOverlap) {
if (IsWindows())
return; // needs carving
char *p;
int gransz = getgransize();
EXPECT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_EXEC,

View file

@ -42,8 +42,9 @@ TEST(mremap, dontMove_hasRoom_itMoves) {
return; // NetBSD requires MREMAP_MAYMOVE
char *p;
int pagesz = getpagesize();
ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
ASSERT_NE(MAP_FAILED,
(p = mmap(__maps_randaddr(), pagesz, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_TRUE(testlib_memoryexists(p));
EXPECT_FALSE(testlib_memoryexists(p + pagesz));
ASSERT_SYS(0, p, mremap(p, pagesz, pagesz * 2, 0));
@ -59,8 +60,9 @@ TEST(mremap, dontMove_noRoom_itFailsWithEnomem) {
return; // NetBSD requires MREMAP_MAYMOVE
char *p;
int pagesz = getpagesize();
ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
ASSERT_NE(MAP_FAILED,
(p = mmap(__maps_randaddr(), pagesz * 2, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0));
EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1));
EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2));
@ -77,8 +79,9 @@ TEST(mremap, dontMove_noRoom_itFailsWithEnomem) {
TEST(mremap, mayMove_noRoom_itRelocates) {
char *p, *p2;
int pagesz = getpagesize();
ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
ASSERT_NE(MAP_FAILED,
(p = mmap(__maps_randaddr(), pagesz * 2, PROT_READ | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0));
EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1));
EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2));
@ -112,7 +115,7 @@ TEST(mremap, mayMove_noRoom_itRelocates) {
TEST(mremap, bench) {
#define N 10
long size = 1024 * 1024;
char *rollo = randaddr();
char *rollo = __maps_randaddr();
char *addr[N];
// create mappings

View file

@ -54,6 +54,8 @@ TEST(munmap, test) {
}
TEST(munmap, punchHoleInMemory) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
@ -72,6 +74,8 @@ TEST(munmap, punchHoleInMemory) {
}
TEST(munmap, memoryHasHole) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
@ -86,6 +90,8 @@ TEST(munmap, memoryHasHole) {
}
TEST(munmap, blanketFree) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
@ -104,6 +110,8 @@ TEST(munmap, blanketFree) {
}
TEST(munmap, trimLeft) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
@ -118,6 +126,8 @@ TEST(munmap, trimLeft) {
}
TEST(munmap, trimRight) {
if (IsWindows())
return; // needs carving
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
@ -173,7 +183,7 @@ TEST(munmap, tinyFile_preciseUnmapSize) {
// clang-format off
TEST(munmap, tinyFile_mapThriceUnmapOnce) {
char *p = randaddr();
char *p = __maps_randaddr();
ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644));
ASSERT_SYS (0, 5, write(3, "hello", 5));
ASSERT_EQ(p+gransz*0, mmap(p+gransz*0, gransz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0));

View file

@ -21,7 +21,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/struct/sched_param.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigaltstack.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/dce.h"
#include "libc/errno.h"