sp_shm.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "precompile.h"
  2. #include "sp_shm.h"
  3. #include "sp_def.h"
  4. #include "toolkit.h"
  5. #include "shm_mem.h"
  6. #include <winpr/file.h>
  7. #include <winpr/memory.h>
  8. #define TAG SPBASE_TAG("shm")
  9. #define MEM_KEY 95555
  10. #define MEM_SIZE (SHM_MEM_SIZE * 1024 * 1024)
  11. #if defined(_MSC_VER)
  12. //0x10000000, 0x20000000, ..., 0x80000000
  13. #define GET_ADDRESS(x) ((void*)((1+(x)) << 28))
  14. #else
  15. //#define GET_ADDRESS(x) ((void*)((1+(x)) << 28))
  16. #define GET_ADDRESS(x) ((void*)(((long)((1+(x))) << 40)))
  17. #endif //_MSC_VER
  18. static int g_newcreator = -1;
  19. int sp_shm_get_range(int mask)
  20. {
  21. int i;
  22. int range = 0;
  23. /*if start to refactor, you can think about :
  24. * https://forums.pcsx2.net/Thread-blog-VirtualAlloc-on-Linux
  25. * VirtualAlloc has been implement at WinPR
  26. */
  27. for (i = 0; i < 7; ++i) {
  28. void *address = GET_ADDRESS(i);
  29. #if defined(_MSC_VER)
  30. void* ret_address = VirtualAlloc(address, MEM_SIZE, MEM_RESERVE, PAGE_NOACCESS);
  31. #else
  32. void* ret_address = VirtualAlloc(address, MEM_SIZE, MEM_RESERVE, 0);
  33. #endif //_MSC_VER
  34. if (address == ret_address) {
  35. range |= 1 << (i + 1);
  36. } else {
  37. WLog_WARN(TAG, "%s::address[%d]: %p vs %p", __FUNCTION__, i, address, ret_address);
  38. }
  39. if (ret_address)
  40. #if _WIN32
  41. VirtualFree(ret_address, 0, MEM_RELEASE);
  42. #else
  43. VirtualFree(ret_address, MEM_SIZE, MEM_RELEASE);
  44. #endif
  45. }
  46. WLog_WARN(TAG, "%s::range: %d 0x%x", __FUNCTION__, range, range);
  47. return range & mask;
  48. }
  49. void *sp_shm_init(int range, int newcreator)
  50. {
  51. int i, res;
  52. void *address;
  53. #if !defined(NO_FIXED_ADDR)
  54. if (newcreator || (res = shm_getmem_addr(&address) == TOOLKIT_ESRCH)) {
  55. for (i = 0; i < 7; ++i) {
  56. if (range & (1 << (i + 1))) {
  57. address = GET_ADDRESS(i);
  58. WLog_DBG(TAG, "the address[%d] %p mem...", i, address);
  59. if (shm_mem_init2(MEM_KEY, address, newcreator) == 0) {
  60. if (address != NULL) {
  61. g_newcreator = newcreator;
  62. } else {
  63. WLog_WARN(TAG, "the address[%d] is null, but back succ.", i);
  64. }
  65. return address;
  66. } else {
  67. WLog_DBG(TAG, "the address[%d] %p mem init failed.", i, address);
  68. }
  69. }
  70. }
  71. } else if(res == 0) {
  72. WLog_DBG(TAG, "specified address %p mem...", address);
  73. address = shm_mem_init(address, newcreator);
  74. if (address != 0) {
  75. g_newcreator = newcreator;
  76. return address;
  77. } else {
  78. WLog_DBG(TAG, "the address %p mem init failed.", address);
  79. }
  80. }
  81. #else
  82. address = 0x10000000000; //NULL; 0x1000000000000; //0x10000000000 ;
  83. address = shm_mem_init(address, newcreator);
  84. if (address != 0) {
  85. g_newcreator = newcreator;
  86. return address;
  87. } else {
  88. WLog_DBG(TAG, "the address[%d] %p mem init failed.", i, address);
  89. }
  90. #endif
  91. return NULL;
  92. }
  93. void sp_shm_term()
  94. {
  95. /*we don't know why, this has been annotated at windows platform*/
  96. shm_mem_destroy2(sp_shm_is_newalloc());
  97. //if(sp_shm_is_newalloc())
  98. // shm_mem_destroy();
  99. }
  100. int sp_shm_is_newalloc()
  101. {
  102. if (g_newcreator == -1)
  103. return 0;
  104. return g_newcreator;
  105. }