Commit bb63e99d authored by Maria Matejka's avatar Maria Matejka
Browse files

Page allocator moved from pools to IO loops.

The resource pool system is highly hierarchical and keeping spare pages
in pools leads to unnecessarily complex memory management.

Loops have a flat hiearchy, at least for now, and it is therefore much
easier to keep care of pages, especially in cases of excessive virtual memory
fragmentation.
parent 385b3ea3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ lp_alloc(linpool *m, uint size)
	    {
	      /* Need to allocate a new chunk */
	      if (m->use_pages)
		c = alloc_page(m->p);
		c = alloc_page();
	      else
		c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);

@@ -271,7 +271,7 @@ lp_free(resource *r)
    {
      c = d->next;
      if (m->use_pages)
	free_page(m->p, d);
	free_page(d);
      else
	xfree(d);
    }
+0 −67
Original line number Diff line number Diff line
@@ -30,14 +30,6 @@
 * is freed upon shutdown of the module.
 */

struct pool_pages {
  uint free;
  uint used;
  void *ptr[0];
};

#define POOL_PAGES_MAX	((page_size - sizeof(struct pool_pages)) / sizeof (void *))

static void pool_dump(resource *);
static void pool_free(resource *);
static resource *pool_lookup(resource *, unsigned long);
@@ -54,9 +46,6 @@ static struct resclass pool_class = {

pool root_pool;

void *alloc_sys_page(void);
int free_sys_page(void *);

static int indent;

/**
@@ -103,16 +92,6 @@ pool_free(resource *P)
      r = rr;
    }

  if (p->pages)
    {
      ASSERT_DIE(!p->pages->used);

      for (uint i = 0; i < p->pages->free; i++)
	free_sys_page(p->pages->ptr[i]);

      free_sys_page(p->pages);
    }

  pool_parent = parent;
}

@@ -185,9 +164,6 @@ pool_memsize_locked(pool *p)
  WALK_LIST(r, p->inside)
    sum += rmemsize(r);

  if (p->pages)
    sum += page_size * (p->pages->used + p->pages->free + 1);

  return sum;
}

@@ -551,49 +527,6 @@ mb_free(void *m)
  rfree(b);
}

void *
alloc_page(pool *p)
{
  if (!p->pages)
  {
    p->pages = alloc_sys_page();
    p->pages->free = 0;
    p->pages->used = 1;
  }
  else
    p->pages->used++;

  if (p->pages->free)
  {
    void *ptr = p->pages->ptr[--p->pages->free];
    bzero(ptr, page_size);
    return ptr;
  }
  else
    return alloc_sys_page();
}

void
free_page(pool *p, void *ptr)
{
  ASSERT_DIE(p->pages);
  p->pages->used--;

  ASSERT_DIE(p->pages->free <= POOL_PAGES_MAX);

  if (p->pages->free == POOL_PAGES_MAX)
  {
    const unsigned long keep = POOL_PAGES_MAX / 4;

    for (uint i = keep; i < p->pages->free; i++)
      free_sys_page(p->pages->ptr[i]);

    p->pages->free = keep;
  }

  p->pages->ptr[p->pages->free++] = ptr;
}


#define STEP_UP(x) ((x) + (x)/2 + 4)

+2 −2
Original line number Diff line number Diff line
@@ -108,8 +108,8 @@ void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_siz
extern long page_size;

/* Allocator of whole pages; for use in slabs and other high-level allocators. */
void *alloc_page(pool *);
void free_page(pool *, void *);
void *alloc_page(void);
void free_page(void *);
#define PAGE_HEAD(x)	((void *) (((intptr_t) (x)) & ~(page_size-1)))

#ifdef HAVE_LIBDMALLOC
+6 −7
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ no_partial:
      s->num_empty_heads--;
      goto okay;
    }
  h = alloc_page(s->p);
  h = alloc_page();
#ifdef POISON
  memset(h, 0xba, page_size);
#endif
@@ -332,7 +332,7 @@ sl_free(slab *s, void *oo)
#ifdef POISON
	memset(h, 0xde, page_size);
#endif
	free_page(s->p, h);
	free_page(h);
      }
      else
	{
@@ -349,11 +349,11 @@ slab_free(resource *r)
  struct sl_head *h, *g;

  WALK_LIST_DELSAFE(h, g, s->empty_heads)
    free_page(s->p, h);
    free_page(h);
  WALK_LIST_DELSAFE(h, g, s->partial_heads)
    free_page(s->p, h);
    free_page(h);
  WALK_LIST_DELSAFE(h, g, s->full_heads)
    free_page(s->p, h);
    free_page(h);
}

static void
@@ -386,8 +386,7 @@ slab_memsize(resource *r)
  WALK_LIST(h, s->full_heads)
    heads++;

//  return ALLOC_OVERHEAD + sizeof(struct slab) + heads * (ALLOC_OVERHEAD + page_size);
  return ALLOC_OVERHEAD + sizeof(struct slab); /* The page sizes are accounted for in the pool */
  return ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size;
}

static resource *
+2 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ t_as_path_converting(void)
#endif

void resource_sys_init(void);
void io_init(void);

int
main(int argc, char *argv[])
@@ -207,6 +208,7 @@ main(int argc, char *argv[])
  resource_init();
  the_bird_lock();
  birdloop_init();
  io_init();

  bt_test_suite(t_as_path_match, "Testing AS path matching and some a-path utilities.");
  bt_test_suite(t_path_format, "Testing formating as path into byte buffer");
Loading