Exemplo n.º 1
0
byte *block_alloc(byte type, size_t size)
{
  int s, b, found = 0, blocks = BLOCKS(size);
  byte *block_map;
  byte *space;

  if (arena_state != INITIALIZED)
    arena_init();

  if (blocks > BLOCKS_PER_SPACE)
    error("Trying to allocate too many contiguous blocks.");

  for(s=0; s<SPACES_IN_ARENA; ++s) {
    if (space_type[s] == TYPE_BLOCKS) {
      block_map = SPACE_MAP(s);
      for (b=0; b<BLOCKS_PER_SPACE; b++) {
	if (block_map[b] == TYPE_FREE) {
	  found ++;
	  if(found >= blocks) {
	    int start = b+1-found, k;

	    for(k=start; k<=b; ++k)
	      block_map[k] = type;
	    map(BLOCK_BASE(s,start), GRAINROUND(page_size, size));
	    return(BLOCK_BASE(s,start));
	  }
	}
	else
	  found = 0;
      }
      found = 0;
    }
  }

  /* None of the existing block spaces have room; let's make a new one */

  space = space_alloc(TYPE_BLOCKS,0);    /* allocate the new space */
  s = SPACE(space);
  block_map = SPACE_MAP(s) = block_maps + s*BLOCKS_PER_SPACE;
  /* This is where the map is */

  for(b=0; b< blocks; ++b)
    block_map[b] = type;
  for (b=blocks; b < BLOCKS_PER_SPACE; b++)
    block_map[b] = TYPE_FREE;		 /* ... and initialize it */

  map(space, GRAINROUND(page_size, size));
  return(space);
}
Exemplo n.º 2
0
static void
set_alloc_ptr(struct alloc_ptr *ptr, struct segment *seg)
{
	if (seg) {
		ptr->free = BLOCK_BASE(seg);
		BITPTR_INIT(ptr->freebit, BITMAP0_BASE(seg), 0);
	} else {
		ptr->free = NULL;
		ptr->freebit = dummy_bitptr;
	}
}
Exemplo n.º 3
0
static NOINLINE void *
find_bitmap(struct alloc_ptr *ptr)
{
	unsigned int i, index, *base, *limit, *p;
	struct segment *seg;
	bitptr_t b = ptr->freebit;
	void *obj;

	ASSERT(ptr->freebit.ptr != &dummy_bitmap);
	seg = ALLOC_PTR_TO_SEGMENT(ptr);

	BITPTR_NEXT(b);
	base = BITMAP0_BASE(seg);

	if (BITPTR_NEXT_FAILED(b)) {
		for (i = 1;; i++) {
			if (i >= SEG_RANK) {
				p = &BITPTR_WORD(b) + 1;
				limit = BITMAP_LIMIT(seg, SEG_RANK - 1);
				b = bitptr_linear_search(p, limit);
				if (BITPTR_NEXT_FAILED(b))
					return NULL;
				i = SEG_RANK - 1;
				break;
			}
			index = BITPTR_WORDINDEX(b, base) + 1;
			base = BITMAP_BASE(seg, i);
			BITPTR_INIT(b, base, index);
			BITPTR_NEXT(b);
			if (!BITPTR_NEXT_FAILED(b))
				break;
		}
		do {
			index = BITPTR_INDEX(b, base);
			base = BITMAP_BASE(seg, --i);
			BITPTR_INIT(b, base + index, 0);
			BITPTR_NEXT(b);
			ASSERT(!BITPTR_NEXT_FAILED(b));
		} while (i > 0);
	}

	index = BITPTR_INDEX(b, base);
	obj = BLOCK_BASE(seg) + (index << seg->blocksize_log2);
	ASSERT(OBJ_TO_SEGMENT(obj) == seg);

	GCSTAT_ALLOC_COUNT(find, seg->blocksize_log2, ptr->blocksize_bytes);
	BITPTR_INC(b);
	ptr->freebit = b;
	ptr->free = (char*)obj + ptr->blocksize_bytes;

	return obj;
}
Exemplo n.º 4
0
void test_mapping(void)
{
  int i,j;
  byte *block_map;
  for (i=0 ; i<NR_SPACES; ++i) {
    switch (space_type[i]) {
    case TYPE_RESERVED:
      /* these are reserved */
      message("space at 0x%08x reserved",SPACE_BASE(i));
      break;
    case TYPE_BLOCKS:
      /* test each block */
      block_map = SPACE_MAP(i);
      message("testing block space at 0x%08x",SPACE_BASE(i));
      for (j=0; j < BLOCKS_PER_SPACE; j++) {
	switch (block_map[j]) {
	case TYPE_FREE:
	  message("  testing block at 0x%08x",BLOCK_BASE(i,j));
	  map (BLOCK_BASE(i,j), BLOCK_SIZE);
	  unmap (BLOCK_BASE(i,j), BLOCK_SIZE);
	  break;
	default:
	  message("  block at 0x%08x has type %d",
		  BLOCK_BASE(i,j),block_map[j]);
	}
      }
      break;
    case TYPE_FREE:
      /* test the whole space */
      message("testing space at 0x%08x",SPACE_BASE(i));
      map(SPACE_BASE(i), SPACE_SIZE >> 1);
      unmap(SPACE_BASE(i), SPACE_SIZE >> 1);
      break;
    default:
      message("space at 0x%08x used with type %d",
	      SPACE_BASE(i), space_type[i]);
    }
  }
}
Exemplo n.º 5
0
/* for debug or GCSTAT */
static size_t
segment_filled(struct segment *seg, size_t filled_index, size_t *ret_bytes)
{
	unsigned int i;
	bitptr_t b;
	char *p = BLOCK_BASE(seg);
	size_t filled = 0, count = 0;
	const size_t blocksize = BLOCK_SIZE(seg);

	BITPTR_INIT(b, BITMAP0_BASE(seg), 0);
	for (i = 0; i < seg->layout->num_blocks; i++) {
		if (i < filled_index || BITPTR_TEST(b)) {
			ASSERT(OBJ_TOTAL_SIZE(p) <= blocksize);
			count++;
			filled += OBJ_TOTAL_SIZE(p);
		}
		BITPTR_INC(b);
		p += blocksize;
	}

	if (ret_bytes)
		*ret_bytes = filled;
	return count;
}