Ejemplo n.º 1
0
u32 BlockAllocator::AllocAligned(u32 &size, u32 sizeGrain, u32 grain, bool fromTop, const char *tag)
{
	// Sanity check
	if (size == 0 || size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return -1;
	}

	// It could be off step, but the grain should generally be a power of 2.
	if (grain < grain_)
		grain = grain_;
	if (sizeGrain < grain_)
		sizeGrain = grain_;

	// upalign size to grain
	size = (size + sizeGrain - 1) & ~(sizeGrain - 1);

	if (!fromTop)
	{
		//Allocate from bottom of mem
		for (Block *bp = bottom_; bp != NULL; bp = bp->next)
		{
			Block &b = *bp;
			u32 offset = b.start % grain;
			if (offset != 0)
				offset = grain - offset;
			u32 needed = offset + size;
			if (b.taken == false && b.size >= needed)
			{
				if (b.size == needed)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start + offset;
				}
				else
				{
					InsertFreeAfter(&b, b.start + needed, b.size - needed);
					b.taken = true;
					b.size = needed;
					b.SetTag(tag);
					return b.start + offset;
				}
			}
		}
	}
	else
	{
		// Allocate from top of mem.
		for (Block *bp = top_; bp != NULL; bp = bp->prev)
		{
			Block &b = *bp;
			u32 offset = (b.start + b.size - size) % grain;
			u32 needed = offset + size;
			if (b.taken == false && b.size >= needed)
			{
				if (b.size == needed)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start;
				}
				else
				{
					InsertFreeBefore(&b, b.start, b.size - needed);
					b.taken = true;
					b.start += b.size - needed;
					b.size = needed;
					b.SetTag(tag);
					return b.start;
				}
			}
		}
	}

	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i (%08x) bytes of contiguous memory", size, size);
	return -1;
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
0
u32 BlockAllocator::AllocAligned(u32 &size, u32 grain, bool fromTop, const char *tag)
{
	// Sanity check
	if (size == 0 || size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return -1;
	}

	// It could be off step, but the grain should generally be a power of 2.
	if (grain < grain_)
		grain = grain_;

	// upalign size to grain
	size = (size + grain - 1) & ~(grain - 1);

	if (!fromTop)
	{
		//Allocate from bottom of mem
		for (std::list<Block>::iterator iter = blocks.begin(); iter != blocks.end(); iter++)
		{
			BlockAllocator::Block &b = *iter;
			u32 offset = b.start % grain;
			u32 needed = offset + size;
			if (b.taken == false && b.size >= needed)
			{
				if (b.size == needed)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start + offset;
				}
				else
				{
					blocks.insert(++iter, Block(b.start + needed, b.size - needed, false));
					b.taken = true;
					b.size = needed;
					b.SetTag(tag);
					return b.start + offset;
				}
			}
		}
	}
	else
	{
		// Allocate from top of mem.
		for (std::list<Block>::reverse_iterator iter = blocks.rbegin(); iter != blocks.rend(); ++iter)
		{
			std::list<Block>::reverse_iterator hey = iter;
			BlockAllocator::Block &b = *((++hey).base()); //yes, confusing syntax. reverse_iterators are confusing
			u32 offset = b.start % grain;
			u32 needed = offset + size;
			if (b.taken == false && b.size >= needed)
			{
				if (b.size == needed)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start + offset;
				}
				else
				{
					blocks.insert(hey.base(), Block(b.start, b.size - needed, false));
					b.taken = true;
					b.start += b.size - needed;
					b.size = needed;
					b.SetTag(tag);
					return b.start + offset;
				}
			}
		}
	}

	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i (%08x) bytes of contiguous memory", size, size);
	return -1;
}
Ejemplo n.º 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);
	}

	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;
}
Ejemplo n.º 5
0
u32 BlockAllocator::Alloc(u32 &size, bool fromTop, const char *tag)
{
	// Sanity check
	if (size == 0 || size > rangeSize_) {
		ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size);
		return 0;
	}

	// upalign size to grain
	size = (size + grain_ - 1) & ~(grain_ - 1);

	if (!fromTop)
	{
		//Allocate from bottom of mem
		for (std::list<Block>::iterator iter = blocks.begin(); iter != blocks.end(); iter++)
		{
			BlockAllocator::Block &b = *iter;
			if (b.taken == false && b.size >= size)
			{
				if (b.size == size)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start;
				}
				else
				{
					blocks.insert(++iter, Block(b.start+size, b.size-size, false));
					b.taken = true;
					b.size = size;
					b.SetTag(tag);
					return b.start;
				}
				//Got one!
			}
		}
	}
	else
	{
		// Allocate from top of mem.
		for (std::list<Block>::reverse_iterator iter = blocks.rbegin(); iter != blocks.rend(); ++iter)
		{
			std::list<Block>::reverse_iterator hey = iter;
			BlockAllocator::Block &b = *((++hey).base()); //yes, confusing syntax. reverse_iterators are confusing
			if (b.taken == false && b.size >= size)
			{
				if (b.size == size)
				{
					b.taken = true;
					b.SetTag(tag);
					return b.start;
				}
				else
				{
					blocks.insert(hey.base(), Block(b.start, b.size-size, false));
					b.taken = true;
					b.start += b.size-size;
					b.size = size;
					b.SetTag(tag);
					return b.start;
				}
				//Got one!
			}
		}
	}

	//Out of memory :(
	ListBlocks();
	ERROR_LOG(HLE, "Block Allocator failed to allocate %i (%08x) bytes of contiguous memory", size, size);
	return -1;
}
Ejemplo n.º 6
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;
}