Exemple #1
0
void BlockAllocator::MergeFreeBlocks()
{
restart:
	DEBUG_LOG(HLE, "Merging Blocks");
	std::list<Block>::iterator iter1, iter2;
	iter1 = blocks.begin();
	iter2 = blocks.begin();
	iter2++;
	while (iter2 != blocks.end())
	{
		BlockAllocator::Block &b1 = *iter1;
		BlockAllocator::Block &b2 = *iter2;
			
		if (b1.taken == false && b2.taken == false)
		{
			DEBUG_LOG(HLE, "Block Alloc found adjacent free blocks - merging");
			b1.size += b2.size;
			blocks.erase(iter2);
			CheckBlocks();
			goto restart; //iterators now invalid - we have to restart our search
		}
		iter1++;
		iter2++;
	}
}
Exemple #2
0
u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag)
{
	CheckBlocks();
	if (size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return -1;
	}
	
	// Downalign the position so we're allocating full blocks.
	u32 alignedPosition = position;
	u32 alignedSize = size;
	if (position & (grain_ - 1)) {
		DEBUG_LOG(HLE, "Position %08x does not align to grain.", position);
		alignedPosition &= ~(grain_ - 1);

		// Since the position was decreased, size must increase.
		alignedSize += alignedPosition - position;
	}

	// Upalign size to grain.
	alignedSize = (alignedSize + grain_ - 1) & ~(grain_ - 1);
	// Tell the caller the allocated size from their requested starting position.
	size = alignedSize - (alignedPosition - position);

	Block *bp = GetBlockFromAddress(alignedPosition);
	if (bp != NULL)
	{
		Block &b = *bp;
		if (b.taken)
		{
			ERROR_LOG(HLE, "Block allocator AllocAt failed, block taken! %08x, %i", position, size);
			return -1;
		}
		else
		{
			// Make sure the block is big enough to split.
			if (b.start + b.size < alignedPosition + alignedSize)
			{
				ERROR_LOG(HLE, "Block allocator AllocAt failed, not enough contiguous space %08x, %i", position, size);
				return -1;
			}
			//good to go
			else if (b.start == alignedPosition)
			{
				InsertFreeAfter(&b, b.start + alignedSize, b.size - alignedSize);
				b.taken = true;
				b.size = alignedSize;
				b.SetTag(tag);
				CheckBlocks();
				return position;
			}
			else
			{
				int size1 = alignedPosition - b.start;
				InsertFreeBefore(&b, b.start, size1);
				if (b.start + b.size > alignedPosition + alignedSize)
					InsertFreeAfter(&b, alignedPosition + alignedSize, b.size - (alignedSize + size1));
				b.taken = true;
				b.start = alignedPosition;
				b.size = alignedSize;
				b.SetTag(tag);

				return position;
			}
		}
	}
	else
	{
		ERROR_LOG(HLE, "Block allocator AllocAt failed :( %08x, %i", position, size);
	}

	
	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i bytes of contiguous memory", alignedSize);
	return -1;
}
Exemple #3
0
u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag)
{
	CheckBlocks();
	if (size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return -1;
	}

	// upalign size to grain
	size = (size + grain_ - 1) & ~(grain_ - 1);
	
	// check that position is aligned
	if (position & (grain_ - 1)) {
		ERROR_LOG(HLE, "Position %08x does not align to grain. Grain will be off.", position);
	}

	std::list<Block>::iterator iter = GetBlockIterFromAddress(position);
	if (iter != blocks.end())
	{
		Block &b = *iter;
		if (b.taken)
		{
			ERROR_LOG(HLE, "Block allocator AllocAt failed, block taken! %08x, %i", position, size);
			return -1;
		}
		else
		{
			//good to go
			if (b.start == position)
			{
				blocks.insert(++iter, Block(b.start + size, b.size - size, false));
				b.taken = true;
				b.size = size;
				b.SetTag(tag);
				CheckBlocks();
				return position;
			}
			else
			{
				int size1 = position - b.start;
				blocks.insert(iter, Block(b.start, size1, false));
				if (b.start + b.size > position + size)
				{
					iter++;
					blocks.insert(iter, Block(position + size, b.size - (size + size1), false));
				}
				b.taken = true;
				b.start = position;
				b.size = size;
				b.SetTag(tag);
				return position;
			}
		}
	}
	else
	{
		ERROR_LOG(HLE, "Block allocator AllocAt failed :( %08x, %i", position, size);
	}

	
	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i bytes of contiguous memory", size);
	return -1;
}
Exemple #4
0
u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag)
{
	CheckBlocks();
	if (size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return -1;
	}

	// upalign size to grain
	size = (size + grain_ - 1) & ~(grain_ - 1);
	
	// check that position is aligned
	if (position & (grain_ - 1)) {
		ERROR_LOG(HLE, "Position %08x does not align to grain. Grain will be off.", position);
	}

	Block *bp = GetBlockFromAddress(position);
	if (bp != NULL)
	{
		Block &b = *bp;
		if (b.taken)
		{
			ERROR_LOG(HLE, "Block allocator AllocAt failed, block taken! %08x, %i", position, size);
			return -1;
		}
		else
		{
			//good to go
			if (b.start == position)
			{
				InsertFreeAfter(&b, b.start + size, b.size - size);
				b.taken = true;
				b.size = size;
				b.SetTag(tag);
				CheckBlocks();
				return position;
			}
			else
			{
				int size1 = position - b.start;
				InsertFreeBefore(&b, b.start, size1);
				if (b.start + b.size > position + size)
					InsertFreeAfter(&b, position + size, b.size - (size + size1));
				b.taken = true;
				b.start = position;
				b.size = size;
				b.SetTag(tag);
				return position;
			}
		}
	}
	else
	{
		ERROR_LOG(HLE, "Block allocator AllocAt failed :( %08x, %i", position, size);
	}

	
	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i bytes of contiguous memory", size);
	return -1;
}