Ejemplo n.º 1
0
/**
 * Test bit in bitmap
 *
 * @v bitmap		Bitmap
 * @v bit		Bit index
 * @ret is_set		Bit is set
 */
int bitmap_test ( struct bitmap *bitmap, unsigned int bit ) {
	unsigned int index = BITMAP_INDEX ( bit );
        bitmap_block_t mask = BITMAP_MASK ( bit );

	if ( bit >= bitmap->length )
		return 0;
	return ( bitmap->blocks[index] & mask );
}
Ejemplo n.º 2
0
/*
 * Sets a given bit in the bitmap. If the bit is already set
 * it returns -1, 0 otherwise.
 */
int
bitmap_set(bitmap_t bitmap, uint32_t bit)
{
	if(bitmap_is_set(bitmap, bit))
		return -1;
	
	bitmap[bit/BITMAP_BITS_PER_ENTRY] |= 
		BITMAP_MASK(BITMAP_REMAINING_BITS(bit));
	
	return 0;
}
Ejemplo n.º 3
0
/**
 * Set bit in bitmap
 *
 * @v bitmap		Bitmap
 * @v bit		Bit index
 */
void bitmap_set ( struct bitmap *bitmap, unsigned int bit ) {
	unsigned int index = BITMAP_INDEX ( bit );
        bitmap_block_t mask = BITMAP_MASK ( bit );

	DBGC ( bitmap, "Bitmap %p setting bit %d\n", bitmap, bit );

	/* Update bitmap */
	bitmap->blocks[index] |= mask;

	/* Update first gap counter */
	while ( bitmap_test ( bitmap, bitmap->first_gap ) ) {
		bitmap->first_gap++;
	}
}
Ejemplo n.º 4
0
static inline int
bb_table_lookup(bb_table_t *table, uint addr)
{
    byte *bm = table->bm;
    PRINT(5, "lookup "PFX" in bb table "PFX"\n",
          (ptr_uint_t)addr, (ptr_uint_t)table);
    /* We see this and it seems to be erroneous data from the pdb,
     * xref drsym_enumerate_lines() from drsyms.
     */
    if (table->size <= addr)
        return BB_TABLE_ENTRY_INVALID;
    if (bm[BITMAP_INDEX(addr)] == 0xff ||
        TEST(BITMAP_MASK(BITMAP_OFFSET(addr)), bm[BITMAP_INDEX(addr)]))
        return BB_TABLE_ENTRY_SET;
    return BB_TABLE_ENTRY_CLEAR;
}
Ejemplo n.º 5
0
static inline bool
bb_table_add(bb_table_t *table, bb_entry_t *entry)
{
    byte *bm;
    uint idx, offs, addr_end, idx_end, offs_end, i;
    if (table == BB_TABLE_IGNORE)
        return false;
    if (table->size <= entry->start + entry->size) {
        WARN(3, "Wrong range "PFX"-"PFX" or table size "PFX" for table "PFX"\n",
             (ptr_uint_t)entry->start,
             (ptr_uint_t)entry->start + entry->size,
             (ptr_uint_t)table->size,
             (ptr_uint_t)table);
        return false;
    }
    bm  = table->bm;
    idx = BITMAP_INDEX(entry->start);
    /* we assume that the whole bb is seen if its start addr is seen */
    if (bm[idx] == BB_TABLE_RANGE_SET)
        return false;
    offs = BITMAP_OFFSET(entry->start);
    if (TEST(BITMAP_MASK(offs), bm[idx]))
        return false;
    /* now we add a new bb */
    PRINT(6, "Add "PFX"-"PFX" in table "PFX"\n",
          (ptr_uint_t)entry->start,
          (ptr_uint_t)entry->start + entry->size,
          (ptr_uint_t)table);
    addr_end = entry->start + entry->size - 1;
    idx_end  = BITMAP_INDEX(addr_end);
    offs_end = (idx_end > idx) ? BITS_PER_BYTE-1 : BITMAP_OFFSET(addr_end);
    /* first byte in the bitmap */
    bm[idx] |= bitmap_set[offs][offs_end];
    /* set all the middle byte */
    for (i = idx + 1; i < idx_end; i++)
        bm[i] = BB_TABLE_RANGE_SET;
    /* last byte in the bitmap */
    if (idx_end > idx) {
        offs_end = BITMAP_OFFSET(addr_end);
        bm[idx_end] |= bitmap_set[0][offs_end];
    }
    return true;
}
Ejemplo n.º 6
0
void free_pages(struct buddy *pool, struct page *page)
{
	struct page *buddy;
	struct buddy_freelist *freelist;
	unsigned int order, index;

	order    = GET_PAGE_ORDER(page);
	freelist = &pool->free[order];
	index    = PAGE_INDEX(page->addr);

	pool->nr_free += 1U << order;

	while (order < BUDDY_MAX_ORDER) {
		BITMAP_TOGGLE(freelist->bitmap, index, order);
		/* If it was 0 before toggling, it means both of buddies
		 * were allocated. So nothing can be merged to upper order
		 * as one of them is still allocated. Otherwise, both of 
		 * them are free now. Therefore merge it to upper order. */
		if (BITMAP_MASK(freelist->bitmap, index, order))
			break;

		/* find buddy and detach it from current order to merge */
		buddy = &mem_map[index ^ (1U << order)];
		list_del(&buddy->link);

		/* grab the first address of merging buddies */
		index &= ~(1U << order);

		order++;
		freelist++;
	}

	list_add(&mem_map[index].link, &freelist->list);

	RESET_PAGE_FLAG(page, PAGE_BUDDY);
}
Ejemplo n.º 7
0
/*
 * Returns if the bit is set or not
 */
int
bitmap_is_set(bitmap_t bitmap, uint32_t bit)
{
	return bitmap[bit / BITMAP_BITS_PER_ENTRY] &
		BITMAP_MASK(BITMAP_REMAINING_BITS(bit));
}