/* * Copyright (C) 2015 Daniel-Constantin Mierla (asipto.com) * * This file is part of Kamailio, a free SIP server. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include "../config.h" #include "../globals.h" #include "memdbg.h" #include "shm.h" #ifdef SHM_MMAP #include #include #include /*open*/ #include #include #endif #include "memcore.h" #define _ROUND2TYPE(s, type) \ (((s)+(sizeof(type)-1))&(~(sizeof(type)-1))) #define _ROUND_LONG(s) _ROUND2TYPE(s, long) void shm_core_destroy(void); #ifndef SHM_MMAP static int _shm_core_shmid = -1; /*shared memory id*/ #endif gen_lock_t* _shm_lock=0; static void* _shm_core_pool = (void*)-1; sr_shm_api_t _shm_root = {0}; /** * */ int shm_getmem(void) { #ifdef SHM_MMAP #ifndef USE_ANON_MMAP int fd; #endif #else struct shmid_ds shm_info; #endif #ifdef SHM_MMAP if (_shm_core_pool && (_shm_core_pool!=(void*)-1)){ #else if ((_shm_core_shmid!=-1)||(_shm_core_pool!=(void*)-1)){ #endif LOG(L_CRIT, "shm already initialized\n"); return -1; } #ifdef SHM_MMAP #ifdef USE_ANON_MMAP _shm_core_pool=mmap(0, shm_mem_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1 ,0); #else fd=open("/dev/zero", O_RDWR); if (fd==-1){ LOG(L_CRIT, "could not open /dev/zero: %s\n", strerror(errno)); return -1; } _shm_core_pool=mmap(0, shm_mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd ,0); /* close /dev/zero */ close(fd); #endif /* USE_ANON_MMAP */ #else _shm_core_shmid=shmget(IPC_PRIVATE, shm_mem_size , 0700); if (_shm_core_shmid==-1){ LOG(L_CRIT, "could not allocate shared memory" " segment: %s\n", strerror(errno)); return -1; } _shm_core_pool=shmat(_shm_core_shmid, 0, 0); #endif if (_shm_core_pool==(void*)-1){ LOG(L_CRIT, "could not attach shared memory" " segment: %s\n", strerror(errno)); /* destroy segment*/ shm_core_destroy(); return -1; } return 0; } /** * */ void* shm_core_get_pool(void) { int ret; long sz; long* p; long* end; ret=shm_getmem(); if (ret<0) return NULL; if (shm_force_alloc){ sz=sysconf(_SC_PAGESIZE); DBG("%ld bytes/page\n", sz); if ((szmname; _shm_root.mem_pool = ap->mem_pool; _shm_root.mem_block = ap->mem_block; _shm_root.xmalloc = ap->xmalloc; _shm_root.xmalloc_unsafe = ap->xmalloc_unsafe; _shm_root.xfree = ap->xfree; _shm_root.xfree_unsafe = ap->xfree_unsafe; _shm_root.xrealloc = ap->xrealloc; _shm_root.xresize = ap->xresize; _shm_root.xstatus = ap->xstatus; _shm_root.xinfo = ap->xinfo; _shm_root.xavailable = ap->xavailable; _shm_root.xsums = ap->xsums; _shm_root.xdestroy = ap->xdestroy; _shm_root.xmodstats = ap->xmodstats; _shm_root.xfmodstats = ap->xfmodstats; return 0; } /** * */ int shm_init_manager(char *name) { if(strcmp(name, "fm")==0 || strcmp(name, "f_malloc")==0 || strcmp(name, "fmalloc")==0) { /*fast malloc*/ return fm_malloc_init_shm_manager(); } else if(strcmp(name, "qm")==0 || strcmp(name, "q_malloc")==0 || strcmp(name, "qmalloc")==0) { /*quick malloc*/ return qm_malloc_init_shm_manager(); } else if(strcmp(name, "tlsf")==0 || strcmp(name, "tlsf_malloc")==0) { /*tlsf malloc*/ return tlsf_malloc_init_shm_manager(); } else if(strcmp(name, "sm")==0) { /*system malloc*/ } else { /*custom malloc - module*/ } return -1; } /** * */ void shm_destroy_manager(void) { shm_core_lock_destroy(); if(_shm_root.xdestroy) { _shm_root.xdestroy(); LM_DBG("destroying memory manager: %s\n", (_shm_root.mname)?_shm_root.mname:"unknown"); } shm_core_destroy(); } /** * */ void shm_print_manager(void) { LM_DBG("shm - using memory manager: %s\n", (_pkg_root.mname)?_pkg_root.mname:"unknown"); }