瀏覽代碼

mem: core api for shm management

Daniel-Constantin Mierla 10 年之前
父節點
當前提交
7d0a97490d
共有 2 個文件被更改,包括 358 次插入0 次删除
  1. 272 0
      mem/shm.c
  2. 86 0
      mem/shm.h

+ 272 - 0
mem/shm.c

@@ -0,0 +1,272 @@
+/*
+ * 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 <stdlib.h>
+
+#include "../config.h"
+#include "../globals.h"
+#include "memdbg.h"
+#include "shm.h"
+
+#ifdef  SHM_MMAP
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h> /*open*/
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#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 ((sz<sizeof(*p)) || (_ROUND_LONG(sz)!=sz)){
+			LOG(L_WARN, "invalid page size %ld, using 4096\n",
+					sz);
+			sz=4096; /* invalid page size, use 4096 */
+		}
+		end=_shm_core_pool+shm_mem_size-sizeof(*p);
+		/* touch one word in every page */
+		for(p=(long*)_ROUND_LONG((long)_shm_core_pool); p<=end;
+										p=(long*)((char*)p+sz))
+			*p=0; 
+	}
+	return _shm_core_pool;
+}
+
+/**
+ * init the core lock
+ */
+int shm_core_lock_init(void)
+{
+	if (_shm_lock) {
+		LM_DBG("shared memory lock initialized\n");
+		return 0;
+	}
+	_shm_lock=shm_malloc_unsafe(sizeof(gen_lock_t)); /* skip lock_alloc, 
+													   race cond*/
+	if (_shm_lock==0){
+		LOG(L_CRIT, "could not allocate lock\n");
+		shm_core_destroy();
+		return -1;
+	}
+	if (lock_init(_shm_lock)==0){
+		LOG(L_CRIT, "could not initialize lock\n");
+		shm_core_destroy();
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ *
+ */
+void shm_core_lock_destroy(void)
+{
+	if (_shm_lock){
+		DBG("destroying the shared memory lock\n");
+		lock_destroy(_shm_lock); /* we don't need to dealloc it*/
+	}
+}
+
+/**
+ *
+ */
+void shm_core_destroy(void)
+{
+#ifndef SHM_MMAP
+	struct shmid_ds shm_info;
+#endif
+	
+	if (_shm_core_pool && (_shm_core_pool!=(void*)-1)) {
+#ifdef SHM_MMAP
+		munmap(_shm_core_pool, /* SHM_MEM_SIZE */ shm_mem_size );
+#else
+		shmdt(_shm_core_pool);
+#endif
+		_shm_core_pool=(void*)-1;
+	}
+#ifndef SHM_MMAP
+	if (shm_shmid!=-1) {
+		shmctl(shm_shmid, IPC_RMID, &shm_info);
+		shm_shmid=-1;
+	}
+#endif
+}
+
+/**
+ *
+ */
+int shm_init_api(sr_shm_api_t *ap)
+{
+	memset(&_shm_root, 0, sizeof(sr_shm_api_t));
+	_shm_root.mname          = ap->mname;
+	_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;
+	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, "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");
+}

+ 86 - 0
mem/shm.h

@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _sr_shm_h_
+#define _sr_shm_h_
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+
+#ifndef SHM_MMAP
+
+#include <sys/shm.h>
+
+#endif
+
+#include <sys/sem.h>
+
+#include "memapi.h"
+
+#include "../dprint.h"
+#include "../lock_ops.h" /* we don't include locking.h on purpose */
+
+extern gen_lock_t* _shm_lock;
+#define shm_lock()    lock_get(_shm_lock)
+#define shm_unlock()  lock_release(_shm_lock)
+int shm_core_lock_init(void);
+void shm_core_lock_destroy(void);
+
+extern sr_shm_api_t _shm_root;
+
+#ifdef DBG_SR_MEMORY
+
+#	define shm_malloc(s)         _shm_root.xmalloc(_shm_root.mem_block, (s), _SRC_LOC_, \
+									_SRC_FUNCTION_, _SRC_LINE_)
+#	define shm_malloc_unsafe(s)  _shm_root.xmalloc_unsafe(_shm_root.mem_block, (s), _SRC_LOC_, \
+									_SRC_FUNCTION_, _SRC_LINE_)
+#	define shm_realloc(p, s)     _shm_root.xrealloc(_shm_root.mem_block, (p), (s), \
+									_SRC_LOC_, _SRC_FUNCTION_, _SRC_LINE_)
+#	define shm_resize(p, s)      _shm_root.xresize(_shm_root.mem_block, (p), (s), \
+									_SRC_LOC_, _SRC_FUNCTION_, _SRC_LINE_)
+#	define shm_free(p)           _shm_root.xfree(_shm_root.mem_block, (p), _SRC_LOC_, \
+									_SRC_FUNCTION_, _SRC_LINE_)
+#	define shm_free_unsafe(p)    _shm_root.xfree_unsafe(_shm_root.mem_block, (p), _SRC_LOC_, \
+									_SRC_FUNCTION_, _SRC_LINE_)
+#else
+#	define shm_malloc(s)         _shm_root.xmalloc(_shm_root.mem_block, (s))
+#	define shm_malloc_unsafe(s)  _shm_root.xmalloc_safe(_shm_root.mem_block, (s))
+#	define shm_realloc(p, s)     _shm_root.xrealloc(_shm_root.mem_block, (p), (s))
+#	define shm_resize(p, s)      _shm_root.xresize(_shm_root.mem_block, (p), (s))
+#	define shm_free(p)           _shm_root.xfree(_shm_root.mem_block, (p))
+#	define shm_free_unsafe(p)    _shm_root.xfree_unsafe(_shm_root.mem_block, (p))
+#endif
+
+#	define shm_status()    _shm_root.xstatus(_shm_root.mem_block)
+#	define shm_info(mi)    _shm_root.xinfo(_shm_root.mem_block, mi)
+#	define shm_available() _shm_root.xavailable(_shm_root.mem_block)
+#	define shm_sums()      _shm_root.xsums(_shm_root.mem_block)
+
+void* shm_core_get_pool(void);
+int shm_init_api(sr_shm_api_t *ap);
+int shm_init_manager(char *name);
+void shm_destroy_manager(void);
+void shm_print_manager(void);
+
+#define shm_available_safe() shm_available()
+#define shm_malloc_on_fork() do{}while(0)
+
+#endif