#include "precompile.h" #include "sp_shm.h" #include "sp_def.h" #include "toolkit.h" #include "shm_mem.h" #include #include #define TAG SPBASE_TAG("shm") #define MEM_KEY 95555 #define MEM_SIZE (SHM_MEM_SIZE * 1024 * 1024) #if defined(_MSC_VER) //0x10000000, 0x20000000, ..., 0x80000000 #define GET_ADDRESS(x) ((void*)((1+(x)) << 28)) #else //#define GET_ADDRESS(x) ((void*)((1+(x)) << 28)) #define GET_ADDRESS(x) ((void*)(((long)((1+(x))) << 40))) #endif //_MSC_VER static int g_newcreator = -1; int sp_shm_get_range(int mask) { int i; int range = 0; /*if start to refactor, you can think about : * https://forums.pcsx2.net/Thread-blog-VirtualAlloc-on-Linux * VirtualAlloc has been implement at WinPR */ for (i = 0; i < 7; ++i) { void *address = GET_ADDRESS(i); #if defined(_MSC_VER) void* ret_address = VirtualAlloc(address, MEM_SIZE, MEM_RESERVE, PAGE_NOACCESS); #else void* ret_address = VirtualAlloc(address, MEM_SIZE, MEM_RESERVE, 0); #endif //_MSC_VER if (address == ret_address) { range |= 1 << (i + 1); } else { WLog_WARN(TAG, "%s::address[%d]: %p vs %p", __FUNCTION__, i, address, ret_address); } if (ret_address) #if _WIN32 VirtualFree(ret_address, 0, MEM_RELEASE); #else VirtualFree(ret_address, MEM_SIZE, MEM_RELEASE); #endif } WLog_WARN(TAG, "%s::range: %d 0x%x", __FUNCTION__, range, range); return range & mask; } void *sp_shm_init(int range, int newcreator) { int i, res; void *address; #if !defined(NO_FIXED_ADDR) if (newcreator || (res = shm_getmem_addr(&address) == TOOLKIT_ESRCH)) { for (i = 0; i < 7; ++i) { if (range & (1 << (i + 1))) { address = GET_ADDRESS(i); WLog_DBG(TAG, "the address[%d] %p mem...", i, address); if (shm_mem_init2(MEM_KEY, address, newcreator) == 0) { if (address != NULL) { g_newcreator = newcreator; } else { WLog_WARN(TAG, "the address[%d] is null, but back succ.", i); } return address; } else { WLog_DBG(TAG, "the address[%d] %p mem init failed.", i, address); } } } } else if(res == 0) { WLog_DBG(TAG, "specified address %p mem...", address); address = shm_mem_init(address, newcreator); if (address != 0) { g_newcreator = newcreator; return address; } else { WLog_DBG(TAG, "the address %p mem init failed.", address); } } #else address = 0x10000000000; //NULL; 0x1000000000000; //0x10000000000 ; address = shm_mem_init(address, newcreator); if (address != 0) { g_newcreator = newcreator; return address; } else { WLog_DBG(TAG, "the address[%d] %p mem init failed.", i, address); } #endif return NULL; } void sp_shm_term() { /*we don't know why, this has been annotated at windows platform*/ shm_mem_destroy2(sp_shm_is_newalloc()); //if(sp_shm_is_newalloc()) // shm_mem_destroy(); } int sp_shm_is_newalloc() { if (g_newcreator == -1) return 0; return g_newcreator; }