Пример #1
0
struct page *alloc_pages(struct buddy *pool, unsigned int order)
{
	struct buddy_freelist *freelist = &pool->free[order];
	struct list *head, *curr;
	struct page *page;
	unsigned int i;

	for (i = order; i < BUDDY_MAX_ORDER; i++, freelist++) {
		head = &freelist->list;
		curr = head->next;

		if (curr != head) {
			page = get_container_of(curr, struct page, link);

			list_del(curr);
			BITMAP_TOGGLE(freelist->bitmap,
					PAGE_INDEX(page->addr), i);

			/* if allocating from higher order, split in half to add
			 * one of them to current order. */
			while (i > order) {
				freelist--;
				i--;

				list_add(&page->link, &freelist->list);
				BITMAP_TOGGLE(freelist->bitmap,
						PAGE_INDEX(page->addr), i);

				page += 1 << i;
			}

			pool->nr_free -= 1 << order;

			SET_PAGE_ORDER(page, order);
			SET_PAGE_FLAG(page, PAGE_BUDDY);

			return page;
		}
	}
Пример #2
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);
}
Пример #3
0
/* Write data to specified page
 */
RV NandDevice04::WritePage(BLOCK_ID blockID,
						   PAGE_ID pageID,
						   const BYTE * buffer,
						   int offset,
						   int size)
{
	ASSERT(eraseCounter);
	ASSERT(blockID >= 0 && blockID < info.blockCount);
	ASSERT(pageID >= 0 && pageID < info.pageCountPerBlock);

	if (eraseCounter[blockID] >= info.eraseLimitation) {
		return RV_ERROR_FLASH_BLOCK_BROKEN;
	}

	// write process
	vfImage.seekg(blockID * blockSize + pageID * info.pageSize, ios::beg);
	vfImage.write((const char *)buffer, info.pageSize);
	vfImage.flush();

	writeCounter[PAGE_INDEX(blockID, pageID)] ++;
	writeLatencyTotal += info.programTime;

	return RV_OK;
}