diff options
author | Maria Matejka <mq@jmq.cz> | 2021-11-23 11:13:11 +0000 |
---|---|---|
committer | Maria Matejka <mq@jmq.cz> | 2021-11-23 11:13:11 +0000 |
commit | 821344c781a99a4f559949a7497617b64c061c82 (patch) | |
tree | 878df97d83216fb9f85f25b7e1d0ffdb8198e1ea /sysdep/unix | |
parent | 4ba991f19c2f8aa893a723f29775c50e1370ed07 (diff) |
Stored pages release routine
Diffstat (limited to 'sysdep/unix')
-rw-r--r-- | sysdep/unix/alloc.c | 29 | ||||
-rw-r--r-- | sysdep/unix/io.c | 4 |
2 files changed, 33 insertions, 0 deletions
diff --git a/sysdep/unix/alloc.c b/sysdep/unix/alloc.c index 4ae1a9db..61360e73 100644 --- a/sysdep/unix/alloc.c +++ b/sysdep/unix/alloc.c @@ -135,3 +135,32 @@ free_sys_page(void *ptr) #endif free(ptr); } + +void +check_stored_pages(void) +{ +#ifdef ENOMEM + if (atomic_load_explicit(&global_page_list_not_empty, memory_order_relaxed) == 0) + return; + + for (uint limit = 0; limit < 256; limit++) + { + GLOBAL_PAGE_SPIN_LOCK; + void *ptr = HEAD(global_page_list); + if (!NODE_VALID(ptr)) + { + atomic_store_explicit(&global_page_list_not_empty, 0, memory_order_relaxed); + GLOBAL_PAGE_SPIN_UNLOCK; + return; + } + + rem_node(ptr); + if (munmap(ptr, page_size) < 0) + if (errno == ENOMEM) + add_tail(&global_page_list, ptr); + else + bug("munmap(%p) failed: %m", ptr); + GLOBAL_PAGE_SPIN_UNLOCK; + } +#endif +} diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index dd385c80..91d717d0 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -2193,6 +2193,7 @@ static int short_loops = 0; #define WORK_EVENTS_MAX 10 void pipe_drain(int fd); +void check_stored_pages(void); void io_loop(void) @@ -2215,6 +2216,9 @@ io_loop(void) timers_fire(&main_birdloop.time, 1); io_close_event(); + /* Try to release some memory if possible */ + check_stored_pages(); + // FIXME poll_tout = (events ? 0 : 3000); /* Time in milliseconds */ if (t = timers_first(&main_birdloop.time)) |