Beispiel #1
0
struct page *alloc_pages(int n, struct page *next)
{
  struct page *best;
  int bestn;
  struct page *scan;

  assert(n >= K);

  scan = unused_pages;
  /* Find first fit */
  for (;;)
    {
      if (!scan)
	return alloc_new(n, next);

      if (scan->pagecount >= n) break;
      scan = scan->next;
    }

  /* Now find best fit */
  best = scan;
  bestn = scan->pagecount;
  for (;;)
    {
      scan = scan->next;
      if (!scan)
	return alloc_split(best, n, next);

      if (scan->pagecount >=n && scan->pagecount < bestn)
	{
	  best = scan;
	  bestn = scan->pagecount;
	}
    }
}
Beispiel #2
0
struct page *alloc_new(int n, struct page *next)
/* Assumes freepages_lock held */
{
  struct page *newp = region_get_mem(n << RPAGELOG);
  assert(newp);
  assert(!((long)newp & (RPAGESIZE - 1)));

  /* region_get_mem may get us more memory than we asked for */
  return alloc_split(newp, n, next);
}
Beispiel #3
0
void scavenge_single_pages(int n)
{
  /* Add n pages to the single_pages list */
  struct page *scan, *best;
  __rcintptr bestn;

  /* Take any group in unused_pages that is <= n or < K.
     Remember smallest entry > n too. This is sortof equivalent to
     a best fit where we allow partial allocations to make up a whole */
  best = NULL;
  bestn = (__rcintptr)1 << (sizeof(__rcintptr) * CHAR_BIT - 2);
  scan = unused_pages;
  while (scan)
    {
      /* The pages < K can't be used for anything but single pages so we
	 might as well grab them even if they are a little too big */
      if (scan->pagecount <= n || scan->pagecount < K)
	{
	  struct page *adding = scan;

	  scan = scan->next;
	  n -= adding->pagecount;
	  unlink_page(&unused_pages, adding);
	  add_single_pages(adding);
          assert(single_pages->pagecount > 0);
	  if (n <= 0) return;
	}
      else
	{
	  if (scan->pagecount < bestn)
	    {
	      bestn = scan->pagecount;
	      best = scan;
	    }
	  scan = scan->next;
	}
    }
  /* Still not enough. Split the best block if there is one, allocate
     new pages otherwise */
  if (!best) {
    add_single_pages(alloc_new(n, NULL));
  } else if (best->pagecount - n < K) {
    unlink_page(&unused_pages, best);
    add_single_pages(best);
    assert(single_pages->pagecount > 0);
  } else {
    add_single_pages(alloc_split(best, n, NULL));
    assert(single_pages->pagecount > 0);
  }
}
Beispiel #4
0
struct page* alloc_new(int n, struct page *next)
{
	/* Assumes freepages_lock held */
	struct page *newp = region_get_mem( (INT_PTR)n << RPAGELOG );

	if (!newp) {
		if (nomem_h)
			nomem_h();
		abort();
	}
	assert( !( (long)newp & (RPAGESIZE - 1) ) );
	/*newp->list_id = Hash(pthread_self())%MAXLISTS;*/
	newp->list_id = list_id % MAXLISTS;
	/* region_get_mem may get us more memory than we asked for */
	return alloc_split(newp, n, next);
}