mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	Directly mapped pages are kept for future use if temporarily not needed
This commit is contained in:
		
				
					committed by
					
						
						Maria Matejka
					
				
			
			
				
	
			
			
			
						parent
						
							9f24fef5e9
						
					
				
				
					commit
					644e9ca94e
				
			@@ -8,6 +8,8 @@
 | 
			
		||||
 | 
			
		||||
#include "nest/bird.h"
 | 
			
		||||
#include "lib/resource.h"
 | 
			
		||||
#include "lib/lists.h"
 | 
			
		||||
#include "lib/event.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -17,8 +19,17 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_MMAP
 | 
			
		||||
#define KEEP_PAGES  512
 | 
			
		||||
 | 
			
		||||
static u64 page_size = 0;
 | 
			
		||||
static _Bool use_fake = 0;
 | 
			
		||||
 | 
			
		||||
uint pages_kept = 0;
 | 
			
		||||
static list pages_list;
 | 
			
		||||
 | 
			
		||||
static void cleanup_pages(void *data);
 | 
			
		||||
static event page_cleanup_event = { .hook = cleanup_pages };
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
static const u64 page_size = 4096; /* Fake page size */
 | 
			
		||||
#endif
 | 
			
		||||
@@ -48,6 +59,15 @@ void *
 | 
			
		||||
alloc_page(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_MMAP
 | 
			
		||||
  if (pages_kept)
 | 
			
		||||
  {
 | 
			
		||||
    node *page = TAIL(pages_list);
 | 
			
		||||
    rem_node(page);
 | 
			
		||||
    pages_kept--;
 | 
			
		||||
    memset(page, 0, get_page_size());
 | 
			
		||||
    return page;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!use_fake)
 | 
			
		||||
  {
 | 
			
		||||
    void *ret = mmap(NULL, get_page_size(), PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 | 
			
		||||
@@ -71,10 +91,39 @@ free_page(void *ptr)
 | 
			
		||||
#ifdef HAVE_MMAP
 | 
			
		||||
  if (!use_fake)
 | 
			
		||||
  {
 | 
			
		||||
    if (munmap(ptr, get_page_size()) < 0)
 | 
			
		||||
      bug("munmap(%p) failed: %m", ptr);
 | 
			
		||||
    if (!pages_kept)
 | 
			
		||||
      init_list(&pages_list);
 | 
			
		||||
 | 
			
		||||
    memset(ptr, 0, sizeof(node));
 | 
			
		||||
    add_tail(&pages_list, ptr);
 | 
			
		||||
 | 
			
		||||
    if (++pages_kept > KEEP_PAGES)
 | 
			
		||||
      ev_schedule(&page_cleanup_event);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
#endif
 | 
			
		||||
    free(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_MMAP
 | 
			
		||||
static void
 | 
			
		||||
cleanup_pages(void *data UNUSED)
 | 
			
		||||
{
 | 
			
		||||
  for (uint seen = 0; (pages_kept > KEEP_PAGES) && (seen < KEEP_PAGES); seen++)
 | 
			
		||||
  {
 | 
			
		||||
    void *ptr = HEAD(pages_list);
 | 
			
		||||
    rem_node(ptr);
 | 
			
		||||
    if (munmap(ptr, get_page_size()) == 0)
 | 
			
		||||
      pages_kept--;
 | 
			
		||||
#ifdef ENOMEM
 | 
			
		||||
    else if (errno == ENOMEM)
 | 
			
		||||
      add_tail(&pages_list, ptr);
 | 
			
		||||
#endif
 | 
			
		||||
    else
 | 
			
		||||
      bug("munmap(%p) failed: %m", ptr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (pages_kept > KEEP_PAGES)
 | 
			
		||||
    ev_schedule(&page_cleanup_event);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user