示例#1
0
文件: MemMap.cpp 项目: ANR2ME/ppsspp
static bool Memory_TryBase(u32 flags) {
	// OK, we know where to find free space. Now grab it!
	// We just mimic the popular BAT setup.

#if defined(_XBOX)
	void *ptr;
#elif !defined(__SYMBIAN32__)
	size_t position = 0;
	size_t last_position = 0;
#endif

	// Zero all the pointers to be sure.
	for (int i = 0; i < num_views; i++)
	{
		if (views[i].out_ptr_low)
			*views[i].out_ptr_low = 0;
		if (views[i].out_ptr)
			*views[i].out_ptr = 0;
	}

	int i;
	for (i = 0; i < num_views; i++)
	{
		const MemoryView &view = views[i];
		if (view.size == 0)
			continue;
		SKIP(flags, view.flags);
		
#ifdef __SYMBIAN32__
		if (!CanIgnoreView(view)) {
			memmap->Commit(view.virtual_address & MEMVIEW32_MASK, view.size);
		}
		*(view.out_ptr) = (u8*)base + (view.virtual_address & MEMVIEW32_MASK);
#elif defined(_XBOX)
		if (!CanIgnoreView(view)) {
			*(view.out_ptr_low) = (u8*)(base + view.virtual_address);
			ptr = VirtualAlloc(base + (view.virtual_address & MEMVIEW32_MASK), view.size, MEM_COMMIT, PAGE_READWRITE);
		}
		*(view.out_ptr) = (u8*)base + (view.virtual_address & MEMVIEW32_MASK);
#else
		if (view.flags & MV_MIRROR_PREVIOUS) {
			position = last_position;
		} else {
			*(view.out_ptr_low) = (u8*)g_arena.CreateView(position, view.size);
			if (!*view.out_ptr_low)
				goto bail;
		}
#ifdef _M_X64
		*view.out_ptr = (u8*)g_arena.CreateView(
			position, view.size, base + view.virtual_address);
#else
		if (CanIgnoreView(view)) {
			// No need to create multiple identical views.
			*view.out_ptr = *views[i - 1].out_ptr;
		} else {
			*view.out_ptr = (u8*)g_arena.CreateView(
				position, view.size, base + (view.virtual_address & MEMVIEW32_MASK));
			if (!*view.out_ptr)
				goto bail;
		}
#endif
		last_position = position;
		position += g_arena.roundup(view.size);
#endif
	}

	return true;

#if !defined(_XBOX) && !defined(__SYMBIAN32__)
bail:
	// Argh! ERROR! Free what we grabbed so far so we can try again.
	for (int j = 0; j <= i; j++)
	{
		if (views[i].size == 0)
			continue;
		SKIP(flags, views[i].flags);
		if (views[j].out_ptr_low && *views[j].out_ptr_low)
		{
			g_arena.ReleaseView(*views[j].out_ptr_low, views[j].size);
			*views[j].out_ptr_low = NULL;
		}
		if (*views[j].out_ptr)
		{
			if (!CanIgnoreView(views[j])) {
				g_arena.ReleaseView(*views[j].out_ptr, views[j].size);
			}
			*views[j].out_ptr = NULL;
		}
	}
	return false;
#endif
}
示例#2
0
文件: MemMap.cpp 项目: Orphis/ppsspp
static bool Memory_TryBase(u32 flags) {
	// OK, we know where to find free space. Now grab it!
	// We just mimic the popular BAT setup.

	size_t position = 0;
	size_t last_position = 0;

	// Zero all the pointers to be sure.
	for (int i = 0; i < num_views; i++) {
		if (views[i].out_ptr)
			*views[i].out_ptr = 0;
	}

	int i;
	for (i = 0; i < num_views; i++) {
		const MemoryView &view = views[i];
		if (view.size == 0)
			continue;
		SKIP(flags, view.flags);
		
		if (view.flags & MV_MIRROR_PREVIOUS) {
			position = last_position;
		}
#ifndef MASKED_PSP_MEMORY
		*view.out_ptr = (u8*)g_arena.CreateView(
			position, view.size, base + view.virtual_address);
		if (!*view.out_ptr) {
			goto bail;
			DEBUG_LOG(MEMMAP, "Failed at view %d", i);
		}
#else
		if (CanIgnoreView(view)) {
			// This is handled by address masking in 32-bit, no view needs to be created.
			*view.out_ptr = *views[i - 1].out_ptr;
		} else {
			*view.out_ptr = (u8*)g_arena.CreateView(
				position, view.size, base + (view.virtual_address & MEMVIEW32_MASK));
			if (!*view.out_ptr) {
				DEBUG_LOG(MEMMAP, "Failed at view %d", i);
				goto bail;
			}
		}
#endif
		last_position = position;
		position += g_arena.roundup(view.size);
	}

	return true;
bail:
	// Argh! ERROR! Free what we grabbed so far so we can try again.
	for (int j = 0; j <= i; j++) {
		if (views[i].size == 0)
			continue;
		SKIP(flags, views[i].flags);
		if (*views[j].out_ptr) {
			if (!CanIgnoreView(views[j])) {
				g_arena.ReleaseView(*views[j].out_ptr, views[j].size);
			}
			*views[j].out_ptr = NULL;
		}
	}
	return false;
}