Squeeze more performance out of memory manager

This commit is contained in:
Justine Tunney 2024-07-08 03:08:42 -07:00
parent 63065cdd70
commit 76cea6c687
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
4 changed files with 18 additions and 29 deletions

View file

@ -52,7 +52,6 @@ void __maps_unlock(void);
void __maps_add(struct Map *); void __maps_add(struct Map *);
void __maps_free(struct Map *); void __maps_free(struct Map *);
struct Map *__maps_alloc(void); struct Map *__maps_alloc(void);
struct Map *__maps_ceil(const char *);
struct Map *__maps_floor(const char *); struct Map *__maps_floor(const char *);
void __maps_stack(char *, int, int, size_t, int, intptr_t); void __maps_stack(char *, int, int, size_t, int, intptr_t);
int __maps_compare(const struct Tree *, const struct Tree *); int __maps_compare(const struct Tree *, const struct Tree *);

View file

@ -88,19 +88,9 @@ privileged optimizespeed struct Map *__maps_floor(const char *addr) {
return 0; return 0;
} }
struct Map *__maps_ceil(const char *addr) {
struct Tree *node;
if ((node = tree_ceil(__maps.maps, addr, __maps_search)))
return MAP_TREE_CONTAINER(node);
return 0;
}
static bool __maps_overlaps(const char *addr, size_t size, int pagesz) { static bool __maps_overlaps(const char *addr, size_t size, int pagesz) {
ASSERT(!((uintptr_t)addr & (getgransize() - 1)) && size); struct Map *map, *floor = __maps_floor(addr);
struct Map *map, *ceil, *floor; for (map = floor; map && map->addr <= addr + size; map = __maps_next(map))
floor = __maps_floor(addr);
ceil = __maps_ceil(addr + size);
for (map = floor; map && map != ceil; map = __maps_next(map))
if (MAX(addr, map->addr) < if (MAX(addr, map->addr) <
MIN(addr + PGUP(size), map->addr + PGUP(map->size))) MIN(addr + PGUP(size), map->addr + PGUP(map->size)))
return true; return true;
@ -138,11 +128,9 @@ static int __muntrack(char *addr, size_t size, int pagesz,
int rc = 0; int rc = 0;
struct Map *map; struct Map *map;
struct Map *next; struct Map *next;
struct Map *ceil;
struct Map *floor; struct Map *floor;
floor = __maps_floor(addr); floor = __maps_floor(addr);
ceil = __maps_ceil(addr + size); for (map = floor; map && map->addr <= addr + size; map = next) {
for (map = floor; map && map != ceil; map = next) {
next = __maps_next(map); next = __maps_next(map);
char *map_addr = map->addr; char *map_addr = map->addr;
size_t map_size = map->size; size_t map_size = map->size;
@ -252,10 +240,10 @@ static void __maps_insert(struct Map *map) {
int prot = map->prot & ~(MAP_FIXED | MAP_FIXED_NOREPLACE); int prot = map->prot & ~(MAP_FIXED | MAP_FIXED_NOREPLACE);
int flags = map->flags; int flags = map->flags;
bool coalesced = false; bool coalesced = false;
struct Map *floor, *ceil, *other, *last = 0; struct Map *floor, *other, *last = 0;
floor = __maps_floor(map->addr); for (other = floor = __maps_floor(map->addr);
ceil = __maps_ceil(map->addr + map->size); other && other->addr <= map->addr + map->size;
for (other = floor; other; last = other, other = __maps_next(other)) { last = other, other = __maps_next(other)) {
if (prot == other->prot && flags == other->flags) { if (prot == other->prot && flags == other->flags) {
if (!coalesced) { if (!coalesced) {
if (map->addr == other->addr + other->size) { if (map->addr == other->addr + other->size) {
@ -282,8 +270,6 @@ static void __maps_insert(struct Map *map) {
__maps_check(); __maps_check();
} }
} }
if (other == ceil)
break;
} }
if (coalesced) if (coalesced)
return; return;
@ -683,10 +669,16 @@ static void *__mremap(char *old_addr, size_t old_size, size_t new_size,
int pagesz = getpagesize(); int pagesz = getpagesize();
int gransz = getgransize(); int gransz = getgransize();
// demand kernel support // kernel support
if (!IsLinux() && !IsNetbsd()) if (!IsLinux() && !IsNetbsd())
return (void *)enosys(); return (void *)enosys();
// it is not needed
if (new_size <= old_size)
if (!(flags & MREMAP_FIXED))
if (flags & MREMAP_MAYMOVE)
flags &= ~MREMAP_MAYMOVE;
// we support these flags // we support these flags
if (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) if (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED))
return (void *)einval(); return (void *)einval();

View file

@ -74,10 +74,9 @@ int __mprotect(char *addr, size_t size, int prot) {
__maps_unlock(); __maps_unlock();
return edeadlk(); return edeadlk();
} }
struct Map *map, *ceil, *floor; struct Map *map, *floor;
floor = __maps_floor(addr); floor = __maps_floor(addr);
ceil = __maps_ceil(addr + size); for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) {
for (map = floor; map && map != ceil; map = __maps_next(map)) {
char *map_addr = map->addr; char *map_addr = map->addr;
size_t map_size = map->size; size_t map_size = map->size;
char *beg = MAX(addr, map_addr); char *beg = MAX(addr, map_addr);

View file

@ -37,10 +37,9 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) {
if (__maps_lock()) { if (__maps_lock()) {
rc = edeadlk(); rc = edeadlk();
} else { } else {
struct Map *map, *ceil, *floor; struct Map *map, *floor;
floor = __maps_floor(addr); floor = __maps_floor(addr);
ceil = __maps_ceil(addr + size); for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) {
for (map = floor; map && map != ceil; map = __maps_next(map)) {
char *beg = MAX(addr, map->addr); char *beg = MAX(addr, map->addr);
char *end = MIN(addr + size, map->addr + map->size); char *end = MIN(addr + size, map->addr + map->size);
if (beg < end) if (beg < end)