Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00038 #ifdef SHM_MEM
00039
00040 #include <stdlib.h>
00041
00042 #include "shm_mem.h"
00043 #include "../config.h"
00044 #include "../globals.h"
00045 #include "memdbg.h"
00046
00047 #ifdef SHM_MMAP
00048
00049 #include <unistd.h>
00050 #include <sys/mman.h>
00051 #include <sys/types.h>
00052 #include <sys/stat.h>
00053 #include <fcntl.h>
00054
00055 #endif
00056
00057 #define _ROUND2TYPE(s, type) \
00058 (((s)+(sizeof(type)-1))&(~(sizeof(type)-1)))
00059 #define _ROUND_LONG(s) _ROUND2TYPE(s, long)
00060
00061
00062 #ifndef SHM_MMAP
00063 static int shm_shmid=-1;
00064 #endif
00065
00066 #ifndef SHM_SAFE_MALLOC
00067 gen_lock_t* mem_lock=0;
00068 #endif
00069
00070 static void* shm_mempool=(void*)-1;
00071 #ifdef LL_MALLOC
00072 struct sfm_block* shm_block;
00073 #elif SF_MALLOC
00074 struct sfm_block* shm_block;
00075 #elif F_MALLOC
00076 struct fm_block* shm_block;
00077 #elif DL_MALLOC
00078 mspace shm_block;
00079 #else
00080 struct qm_block* shm_block;
00081 #endif
00082
00083
00084 inline static void* sh_realloc(void* p, unsigned int size)
00085 {
00086 void *r;
00087 shm_lock();
00088 shm_free_unsafe(p);
00089 r=shm_malloc_unsafe(size);
00090 shm_unlock();
00091 return r;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #ifdef DBG_QM_MALLOC
00104 void* _shm_resize( void* p, unsigned int s, const char* file, const char* func,
00105 int line)
00106 #else
00107 void* _shm_resize( void* p , unsigned int s)
00108 #endif
00109 {
00110 if (p==0) {
00111 DBG("WARNING:vqm_resize: resize(0) called\n");
00112 return shm_malloc( s );
00113 }
00114 return sh_realloc( p, s );
00115 }
00116
00117
00118
00119
00120
00121 int shm_getmem(void)
00122 {
00123
00124 #ifdef SHM_MMAP
00125 #ifndef USE_ANON_MMAP
00126 int fd;
00127 #endif
00128 #else
00129 struct shmid_ds shm_info;
00130 #endif
00131
00132 #ifdef SHM_MMAP
00133 if (shm_mempool && (shm_mempool!=(void*)-1)){
00134 #else
00135 if ((shm_shmid!=-1)||(shm_mempool!=(void*)-1)){
00136 #endif
00137 LOG(L_CRIT, "BUG: shm_mem_init: shm already initialized\n");
00138 return -1;
00139 }
00140
00141 #ifdef SHM_MMAP
00142 #ifdef USE_ANON_MMAP
00143 shm_mempool=mmap(0, shm_mem_size, PROT_READ|PROT_WRITE,
00144 MAP_ANON|MAP_SHARED, -1 ,0);
00145 #else
00146 fd=open("/dev/zero", O_RDWR);
00147 if (fd==-1){
00148 LOG(L_CRIT, "ERROR: shm_mem_init: could not open /dev/zero: %s\n",
00149 strerror(errno));
00150 return -1;
00151 }
00152 shm_mempool=mmap(0, shm_mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd ,0);
00153
00154 close(fd);
00155 #endif
00156 #else
00157
00158 shm_shmid=shmget(IPC_PRIVATE, shm_mem_size , 0700);
00159 if (shm_shmid==-1){
00160 LOG(L_CRIT, "ERROR: shm_mem_init: could not allocate shared memory"
00161 " segment: %s\n", strerror(errno));
00162 return -1;
00163 }
00164 shm_mempool=shmat(shm_shmid, 0, 0);
00165 #endif
00166 if (shm_mempool==(void*)-1){
00167 LOG(L_CRIT, "ERROR: shm_mem_init: could not attach shared memory"
00168 " segment: %s\n", strerror(errno));
00169
00170 shm_mem_destroy();
00171 return -1;
00172 }
00173 return 0;
00174 }
00175
00176
00177
00178 int shm_mem_init_mallocs(void* mempool, unsigned long pool_size)
00179 {
00180
00181 shm_block=shm_malloc_init(mempool, pool_size);
00182 if (shm_block==0){
00183 LOG(L_CRIT, "ERROR: shm_mem_init: could not initialize shared"
00184 " malloc\n");
00185 shm_mem_destroy();
00186 return -1;
00187 }
00188 #ifndef SHM_SAFE_MALLOC
00189 mem_lock=shm_malloc_unsafe(sizeof(gen_lock_t));
00190
00191 if (mem_lock==0){
00192 LOG(L_CRIT, "ERROR: shm_mem_init: could not allocate lock\n");
00193 shm_mem_destroy();
00194 return -1;
00195 }
00196 if (lock_init(mem_lock)==0){
00197 LOG(L_CRIT, "ERROR: shm_mem_init: could not initialize lock\n");
00198 shm_mem_destroy();
00199 return -1;
00200 }
00201 #endif
00202
00203 DBG("shm_mem_init: success\n");
00204
00205 return 0;
00206 }
00207
00208
00209 int shm_mem_init(int force_alloc)
00210 {
00211 int ret;
00212 long sz;
00213 long* p;
00214 long* end;
00215
00216 ret=shm_getmem();
00217 if (ret<0) return ret;
00218 if (force_alloc){
00219 sz=sysconf(_SC_PAGESIZE);
00220 DBG("shm_mem_init: %ld bytes/page\n", sz);
00221 if ((sz<sizeof(*p)) || (_ROUND_LONG(sz)!=sz)){
00222 LOG(L_WARN, "shm_mem_init: invalid page size %ld, using 4096\n",
00223 sz);
00224 sz=4096;
00225 }
00226 end=shm_mempool+shm_mem_size-sizeof(*p);
00227
00228 for(p=(long*)_ROUND_LONG((long)shm_mempool); p<=end;
00229 p=(long*)((char*)p+sz))
00230 *p=0;
00231 }
00232 return shm_mem_init_mallocs(shm_mempool, shm_mem_size);
00233 }
00234
00235
00236 void shm_mem_destroy(void)
00237 {
00238 #ifndef SHM_MMAP
00239 struct shmid_ds shm_info;
00240 #endif
00241
00242 DBG("shm_mem_destroy\n");
00243 #ifndef SHM_SAFE_MALLOC
00244 if (mem_lock){
00245 DBG("destroying the shared memory lock\n");
00246 lock_destroy(mem_lock);
00247 }
00248 #endif
00249 if (shm_block){
00250 shm_malloc_destroy(shm_block);
00251 shm_block=0;
00252 }
00253 if (shm_mempool && (shm_mempool!=(void*)-1)) {
00254 #ifdef SHM_MMAP
00255 munmap(shm_mempool, shm_mem_size );
00256 #else
00257 shmdt(shm_mempool);
00258 #endif
00259 shm_mempool=(void*)-1;
00260 }
00261 #ifndef SHM_MMAP
00262 if (shm_shmid!=-1) {
00263 shmctl(shm_shmid, IPC_RMID, &shm_info);
00264 shm_shmid=-1;
00265 }
00266 #endif
00267 }
00268
00269
00270 #endif