Beispiel #1
0
// Maps a block of memory for use as a recompiled code buffer, and ensures that the
// allocation is below a certain memory address (specified in "bounds" parameter).
// The allocated block has code execution privileges.
// Returns NULL on allocation failure.
u8* SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
{
	u8* Mem = (u8*)HostSys::Mmap( base, size );

	if( (Mem == NULL) || (bounds != 0 && (((uptr)Mem + size) > bounds)) )
	{
		if( base )
		{
			DbgCon.Warning( "First try failed allocating %s at address 0x%x", caller, base );

			// Let's try again at an OS-picked memory area, and then hope it meets needed
			// boundschecking criteria below.
			SafeSysMunmap( Mem, size );
			Mem = (u8*)HostSys::Mmap( 0, size );
		}

		if( (bounds != 0) && (((uptr)Mem + size) > bounds) )
		{
			DevCon.Warning( "Second try failed allocating %s, block ptr 0x%x does not meet required criteria.", caller, Mem );
			SafeSysMunmap( Mem, size );

			// returns NULL, caller should throw an exception.
		}
	}
	return Mem;
}
// Notes:
//  * This method should be called if the object is already in an released (unreserved) state.
//    Subsequent calls will be ignored, and the existing reserve will be returned.
//
// Parameters:
//   size - size of the reserve, in bytes. (optional)
//     If not specified (or zero), then the default size specified in the constructor for the
//     object instance is used.
//
//   upper_bounds - criteria that must be met for the allocation to be valid.
//     If the OS refuses to allocate the memory below the specified address, the
//     object will fail to initialize and an exception will be thrown.
void* VirtualMemoryReserve::Reserve( size_t size, uptr base, uptr upper_bounds )
{
	if (!pxAssertDev( m_baseptr == NULL, "(VirtualMemoryReserve) Invalid object state; object has already been reserved." ))
		return m_baseptr;

	if (!size) size = m_defsize;
	if (!size) return NULL;

	m_pages_reserved = (size + __pagesize-4) / __pagesize;
	uptr reserved_bytes = m_pages_reserved * __pagesize;

	m_baseptr = (void*)HostSys::MmapReserve(base, reserved_bytes);

	if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds)))
	{
		DevCon.Warning( L"%s: host memory @ %s -> %s is unavailable; attempting to map elsewhere...",
			m_name.c_str(), pxsPtr(base), pxsPtr(base + size) );

		SafeSysMunmap(m_baseptr, reserved_bytes);

		if (base)
		{
			// Let's try again at an OS-picked memory area, and then hope it meets needed
			// boundschecking criteria below.
			m_baseptr = HostSys::MmapReserve( 0, reserved_bytes );
		}
	}

	if ((upper_bounds != 0) && (((uptr)m_baseptr + reserved_bytes) > upper_bounds))
	{
		SafeSysMunmap(m_baseptr, reserved_bytes);
		// returns null, caller should throw an exception or handle appropriately.
	}

	if (!m_baseptr) return NULL;

	FastFormatUnicode mbkb;
	uint mbytes = reserved_bytes / _1mb;
	if (mbytes)
		mbkb.Write( "[%umb]", mbytes );
	else
		mbkb.Write( "[%ukb]", reserved_bytes / 1024 );

	DevCon.WriteLn( Color_Gray, L"%-32s @ %s -> %s %s", m_name.c_str(),
		pxsPtr(m_baseptr), pxsPtr((uptr)m_baseptr+reserved_bytes), mbkb.c_str());

	return m_baseptr;
}
Beispiel #3
0
// Free Allocated Resources
void mVUclose(microVU& mVU) {

	safe_delete  (mVU.cache_reserve);
	SafeSysMunmap(mVU.dispCache, mVUdispCacheSize);

	// Delete Programs and Block Managers
	for (u32 i = 0; i < (mVU.progSize / 2); i++) {
		if (!mVU.prog.prog[i]) continue;
		std::deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin());
		for ( ; it != mVU.prog.prog[i]->end(); ++it) {
			mVUdeleteProg(mVU, it[0]);
		}
		safe_delete(mVU.prog.prog[i]);
	}
}
void VirtualMemoryReserve::Release()
{
	SafeSysMunmap(m_baseptr, m_pages_reserved*__pagesize);
}