Example #1
0
u32 BlockAllocator::GetBlockStartFromAddress(u32 addr) 
{
	Block *b = GetBlockFromAddress(addr);
	if (b)
		return b->start;
	else
		return -1;
}
Example #2
0
u32 BlockAllocator::GetBlockSizeFromAddress(u32 addr) const
{
	const Block *b = GetBlockFromAddress(addr);
	if (b)
		return b->size;
	else
		return -1;
}
Example #3
0
bool BlockAllocator::FreeExact(u32 position)
{
	BlockAllocator::Block *b = GetBlockFromAddress(position);
	if (b && b->taken && b->start == position)
		return Free(position);
	else
	{
		ERROR_LOG(HLE, "BlockAllocator : invalid free %08x", position);
		return false;
	}
}
Example #4
0
bool BlockAllocator::FreeExact(u32 position)
{
	Block *b = GetBlockFromAddress(position);
	if (b && b->taken && b->start == position)
	{
		b->taken = false;
		MergeFreeBlocks(b);
		return true;
	}
	else
	{
		ERROR_LOG(HLE, "BlockAllocator : invalid free %08x", position);
		return false;
	}
}
Example #5
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;
}
Example #6
0
const char *BlockAllocator::GetBlockTag(u32 addr) const {
	const Block *b = GetBlockFromAddress(addr);
	return b->tag;
}
Example #7
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;
}