shm_mem.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "precompile.h"
  2. #include "q_malloc.h"
  3. #include "shm_mem.h"
  4. #include "shm.h"
  5. #include "strutil.h"
  6. #include "modCheck.h"
  7. # define MY_MALLOC qm_malloc
  8. # define MY_FREE qm_free
  9. # define shm_malloc_init qm_malloc_init
  10. //ʵÌå¼ä¹²Ïí
  11. TOOLKIT_API struct qm_block* shm_block = NULL;
  12. static int shm_shmid=-1; /*shared memory id*/
  13. static void* shm_mempool=(void*)-1;
  14. TOOLKIT_API void shm_lock()
  15. {
  16. qm_lock(shm_block);
  17. }
  18. TOOLKIT_API void shm_unlock()
  19. {
  20. qm_unlock(shm_block);
  21. }
  22. /* look at a buffer if there is perhaps enough space for the new size
  23. (It is beneficial to do so because vq_malloc is pretty stateful
  24. and if we ask for a new buffer size, we can still make it happy
  25. with current buffer); if so, we return current buffer again;
  26. otherwise, we free it, allocate a new one and return it; no
  27. guarantee for buffer content; if allocation fails, we return
  28. NULL
  29. */
  30. TOOLKIT_API int shm_getmem(int key, void **hint)
  31. {
  32. //struct shmid_ds shm_info;
  33. if ((shm_shmid!=-1)||(shm_mempool!=(void*)-1)){
  34. return 0; //Òѳõʼ»¯
  35. }
  36. shm_shmid=shmget(key, SHM_MEM_SIZE*1024*1024, IPC_CREAT);
  37. if (shm_shmid==-1){
  38. return -1;
  39. }
  40. shm_mempool=shmat(shm_shmid, hint ? *hint : NULL, 0);
  41. if (shm_mempool==(void*)-1){
  42. /* destroy segment*/
  43. shm_mem_destroy();
  44. return -1;
  45. }
  46. if (hint)
  47. *hint = shm_mempool;
  48. return 0;
  49. }
  50. static int shm_mem_init_mallocs(void* mempool, unsigned long pool_size, int newcreate)
  51. {
  52. if (newcreate) {
  53. /* init it for malloc*/
  54. shm_block=shm_malloc_init((char*)mempool, pool_size);
  55. if (shm_block==0){
  56. shm_mem_destroy();
  57. return -1;
  58. }
  59. } else {
  60. shm_block = (struct qm_block*)mempool;
  61. }
  62. return 0;
  63. }
  64. TOOLKIT_API int shm_mem_init2(int key, void *hint, int newcreate)
  65. {
  66. int ret;
  67. ret=shm_getmem(key, &hint);
  68. if (ret<0) return ret;
  69. return shm_mem_init_mallocs(shm_mempool, SHM_MEM_SIZE*1024*1024, newcreate);
  70. }
  71. TOOLKIT_API void shm_mem_destroy(void)
  72. {
  73. struct shmid_ds shm_info;
  74. if (shm_mempool && (shm_mempool!=(void*)-1)) {
  75. shmdt(shm_mempool);
  76. shm_mempool=(void*)-1;
  77. }
  78. if (shm_shmid!=-1) {
  79. shmctl(shm_shmid, IPC_RMID, &shm_info);
  80. shm_shmid=-1;
  81. }
  82. }
  83. TOOLKIT_API char *shm_strdup(const char *str)
  84. {
  85. int n;
  86. char *ret;
  87. if (!str)
  88. return NULL;
  89. n = strlen(str);
  90. ret = shm_malloc(n + 1);
  91. if (ret) {
  92. memcpy(ret, str, n+1);
  93. }
  94. return ret;
  95. }
  96. TOOLKIT_API char *shm_strdup_printf(const char *format, ...)
  97. {
  98. va_list arg;
  99. char *ret;
  100. va_start(arg, format);
  101. ret = shm_strdup_vprintf(format, arg);
  102. va_end(arg);
  103. return ret;
  104. }
  105. TOOLKIT_API char *shm_strdup_vprintf(const char *format, va_list args)
  106. {
  107. char *t = strdup_vprintf(format, args);
  108. char *r = shm_strdup(t);
  109. free(t);
  110. return r;
  111. }
  112. TOOLKIT_API void shm_set_user_data(int idx, void *user_data)
  113. {
  114. qm_set_user_data(shm_block, idx, user_data);
  115. }
  116. TOOLKIT_API void *shm_get_user_data(int idx)
  117. {
  118. if (shm_block == NULL)
  119. return NULL;
  120. return qm_get_user_data(shm_block, idx);
  121. }
  122. TOOLKIT_API void* shm_malloc(unsigned int size)
  123. {
  124. void *p;
  125. shm_lock();
  126. p=shm_malloc_unsafe(size);
  127. shm_unlock();
  128. return p;
  129. }
  130. TOOLKIT_API void *shm_malloc_unsafe(unsigned int _size)
  131. {
  132. return MY_MALLOC(shm_block, (_size));
  133. }
  134. TOOLKIT_API void shm_free_unsafe(void * _p )
  135. {
  136. MY_FREE(shm_block, (_p));
  137. }