- updated INSTALL
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 26 Nov 2001 23:31:03 +0000 (23:31 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 26 Nov 2001 23:31:03 +0000 (23:31 +0000)
- fixed MKDEP in Makefile
- added shm_mem.{c,h} = shared memory + shared malloc (sh_malloc)

INSTALL
Makefile
config.h
main.c
mem.h
shm_mem.c [new file with mode: 0644]
shm_mem.h [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
index 7f424dc..fc709ea 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -5,6 +5,8 @@ Installation Notes
 Supported architectures: Linux, FreeBSD, Solaris, Win* (CYGWIN)
 (for other architectures the Makefile must be edited)
 
+There are various configuration options defined in the Makefile.
+
 Requirements:
 
 
@@ -22,8 +24,13 @@ Arhitecture Notes:
        (>=0.12). 
        
 
+Clean:
+make clean   (clean the modules too)
+make proper  (clean also the dependencies)
+
 Compile:
 
+make proper
 make
 (or gmake on non-Linux systems)
 make modules 
index 498d051..cc5f7cb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,14 @@ NAME=ser
 # DEBUG compiles in some extra debugging code
 # OLD_PARSER uses the old and stable parser (from ser 8.3.2)
 # DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1")
-DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK -DPKG_MALLOC #-DNO_DEBUG#-DSTATS -DNO_DEBUG 
+# SHM_MEM    compiles in shared mem. support, needed by some modules and
+#            by USE_SHM_MEM
+# PKG_MALLOC uses a faster malloc (exclusive w/ USE_SHM_MEM)
+# USE_SHM_MEM all pkg_malloc => sh_malloc (most mallocs use a common sh. mem.
+#           segment); don't define PKG_MALLOC!
+DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK  -DSHM_MEM -DUSE_SHM_MEM -DNO_DEBUG 
+#-DPKG_MALLOC
+#-DNO_DEBUG#-DSTATS -DNO_DEBUG 
 #-DNO_LOG
 
 PROFILE=  # -pg #set this if you want profiling
@@ -84,7 +91,7 @@ ifneq (,$(findstring CYGWIN, $(ARCH)))
 endif
 
 
-MKDEP=gcc -M 
+MKDEP=gcc -M $(DEFS)
 
 ALLDEP=Makefile
 
index b454130..af01236 100644 (file)
--- a/config.h
+++ b/config.h
@@ -44,5 +44,8 @@
 /*used only if PKG_MALLOC is defined*/
 #define PKG_MEM_POOL_SIZE 1024*1024
 
+/*used is SH_MEM is defined*/
+#define SHM_MEM_SIZE 1024*1024
+
 
 #endif
diff --git a/main.c b/main.c
index 9b10e56..e961d46 100644 (file)
--- a/main.c
+++ b/main.c
@@ -24,6 +24,9 @@
 #include "udp_server.h"
 #include "globals.h"
 #include "mem.h"
+#ifdef SHM_MEM
+#include "shm_mem.h"
+#endif
 
 
 #include <signal.h>
@@ -294,9 +297,16 @@ static void sig_usr(int signo)
 #ifdef PKG_MALLOC
                pkg_status();
 #endif
+#ifdef SHM_MEM
+               sh_status();
+#endif
                DPrint("INT received, program terminates\n");
                DPrint("Thank you for flying ser\n");
+               /* WARNING: very dangerous, might be unsafe*/
+#ifdef SHM_MEM
+               shm_mem_destroy();
                exit(0);
+#endif
        } else if (signo==SIGUSR1) { /* statistic */
 #ifdef STATS
                dump_all_statistic();
@@ -304,6 +314,9 @@ static void sig_usr(int signo)
 #ifdef PKG_MALLOC
                pkg_status();
 #endif
+#ifdef SHM_MEM
+               sh_status();
+#endif
        }
 }
        
@@ -319,16 +332,15 @@ int main(int argc, char** argv)
        char *options;
 
        /* added by jku: add exit handler */
-        if (signal(SIGINT, sig_usr) == SIG_ERR ) {
-               DPrint("ERROR: no SIGINT signal handler can be installed\n");
-                goto error;
-        }
-#ifdef STATS
+       if (signal(SIGINT, sig_usr) == SIG_ERR ) {
+               DPrint("ERROR: no SIGINT signal handler can be installed\n");
+               goto error;
+       }
+
        if (signal(SIGUSR1, sig_usr)  == SIG_ERR ) {
-                DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
-                goto error;
-        }
-#endif
+               DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
+               goto error;
+       }
 
        /* process command line (get port no, cfg. file path etc) */
        opterr=0;
@@ -529,7 +541,13 @@ int main(int argc, char** argv)
                goto error;
        }
 #endif
-
+       
+#ifdef SHM_MEM
+       if (shm_mem_init()==-1) {
+               LOG(L_CRIT, "could not initialize shared memory pool, exiting...\n");
+               goto error;
+       }
+#endif
        
        return main_loop();
 
diff --git a/mem.h b/mem.h
index 019aa2e..b402d15 100644 (file)
--- a/mem.h
+++ b/mem.h
@@ -19,7 +19,16 @@ extern struct qm_block* mem_block;
 #define pkg_free(p)   qm_free(mem_block, p)
 #define pkg_status()  qm_status(mem_block)
 
+#elif defined(SHM_MEM) && defined(USE_SHM_MEM)
+
+#include "shm_mem.h"
+
+#define pkg_malloc(s) sh_malloc(s)
+#define pkg_free(p)   sh_free(p)
+#define pkg_status()  sh_status()
+
 #else
+
 #include <stdlib.h>
 
 #define pkg_malloc(s) \
diff --git a/shm_mem.c b/shm_mem.c
new file mode 100644 (file)
index 0000000..67abb58
--- /dev/null
+++ b/shm_mem.c
@@ -0,0 +1,114 @@
+/* $Id$
+ *
+ * Shared memory functions
+ */
+
+#ifdef SHM_MEM
+
+#include "shm_mem.h"
+#include "config.h"
+
+
+/* define semun */
+#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+       /* union semun is defined by including <sys/sem.h> */
+#else
+       /* according to X/OPEN we have to define it ourselves */
+       union semun {
+               int val;                    /* value for SETVAL */
+               struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
+               unsigned short int *array;  /* array for GETALL, SETALL */
+               struct seminfo *__buf;      /* buffer for IPC_INFO */
+       };
+#endif
+
+
+
+
+static int shm_shmid=-1; /*shared memory id*/
+int shm_semid=-1; /*semaphore id*/
+static void* shm_mempool=(void*)-1;
+struct qm_block* shm_block;
+
+
+
+/* ret -1 on erro*/
+int shm_mem_init()
+{
+
+       struct shmid_ds shm_info;
+       union semun su;
+       int ret;
+
+       if ((shm_shmid!=-1)||(shm_semid!=-1)||(shm_mempool!=(void*)-1)){
+               LOG(L_CRIT, "BUG: shm_mem_init: shm already initialized\n");
+               return -1;
+       }
+       
+       shm_shmid=shmget(IPC_PRIVATE, SHM_MEM_SIZE, 0700);
+       if (shm_shmid==-1){
+               LOG(L_CRIT, "ERROR: shm_mem_init: could not allocate shared memory"
+                               " segment: %s\n", strerror(errno));
+               return -1;
+       }
+       shm_mempool=shmat(shm_shmid, 0, 0);
+       if (shm_mempool==(void*)-1){
+               LOG(L_CRIT, "ERROR: shm_mem_init: could not attach shared memory"
+                               " segment: %s\n", strerror(errno));
+               /* destroy segment*/
+               shm_mem_destroy();
+               return -1;
+       }
+       /* alloc a semaphore (for malloc)*/
+       shm_semid=semget(IPC_PRIVATE, 1, 0700);
+       if (shm_semid==-1){
+               LOG(L_CRIT, "ERROR: shm_mem_init: could not allocate semaphore: %s\n",
+                               strerror(errno));
+               shm_mem_destroy();
+               return -1;
+       }
+       /* set its value to 1 (mutex)*/
+       su.val=1;
+       ret=semctl(shm_semid, 0, SETVAL, su);
+       if (ret==-1){
+               LOG(L_CRIT, "ERROR: shm_mem_init: could not set initial semaphore"
+                               " value: %s\n", strerror(errno));
+               shm_mem_destroy();
+               return -1;
+       }
+       /* init it for malloc*/
+       shm_block=qm_malloc_init(shm_mempool, SHM_MEM_SIZE);
+       if (shm_block==0){
+               LOG(L_CRIT, "ERROR: shm_mem_init: could not initialize shared"
+                               " malloc\n");
+               shm_mem_destroy();
+               return -1;
+       }
+       DBG("shm_mem_init: success\n");
+       
+       return 0;
+}
+
+
+
+void shm_mem_destroy()
+{
+       struct shmid_ds shm_info;
+       
+       DBG("shm_mem_destroy\n");
+       if (shm_mempool && (shm_mempool!=(void*)-1)) {
+               shmdt(shm_mempool);
+               shm_mempool=(void*)-1;
+       }
+       if (shm_shmid!=-1) {
+               shmctl(shm_shmid, IPC_RMID, &shm_info);
+               shm_shmid=-1;
+       }
+       if (shm_semid!=-1) {
+               semctl(shm_semid, 0, IPC_RMID, (union semun)0);
+               shm_semid=-1;
+       }
+}
+
+
+#endif
diff --git a/shm_mem.h b/shm_mem.h
new file mode 100644 (file)
index 0000000..7cc0e0d
--- /dev/null
+++ b/shm_mem.h
@@ -0,0 +1,122 @@
+/* $Id$*
+ *
+ * shared mem stuff
+ */
+
+#ifdef SHM_MEM
+
+#ifndef shm_mem_h
+#define shm_mem_h
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include <string.h>
+#include <errno.h>
+
+
+
+#include "q_malloc.h"
+#include "dprint.h"
+
+extern struct qm_block* shm_block;
+extern int shm_semid;
+
+int shm_mem_init();
+void shm_mem_destroy();
+
+
+
+inline static void sh_lock()
+{
+       struct sembuf sop;
+       
+       sop.sem_num=0;
+       sop.sem_op=-1; /*down*/
+       sop.sem_flg=0 /*SEM_UNDO*/;
+again:
+//     semop(shm_semid, &sop, 1);
+#if 0
+       switch(ret){
+               case 0: /*ok*/
+                       break;
+               case EINTR: /*interrupted by signal, try again*/
+                       DBG("sh_lock: interrupted by signal, trying again...\n");
+                       goto again;
+               default:
+                       LOG(L_ERR, "ERROR: sh_lock: error waiting on semaphore: %s\n",
+                                       strerror(errno));
+       }
+#endif
+}
+
+
+
+inline static void sh_unlock()
+{
+       struct sembuf sop;
+       
+       sop.sem_num=0;
+       sop.sem_op=1; /*up*/
+       sop.sem_flg=0 /*SEM_UNDO*/;
+again:
+//     semop(shm_semid, &sop, 1);
+#if 0
+       /*should ret immediately*/
+       switch(ret){
+               case 0: /*ok*/
+                       break;
+               case EINTR: /*interrupted by signal, try again*/
+                       DBG("sh_lock: interrupted by signal, trying again...\n");
+                       goto again;
+               default:
+                       LOG(L_ERR, "ERROR: sh_lock: error waiting on semaphore: %s\n",
+                                       strerror(errno));
+       }
+#endif
+}
+
+
+inline static void* sh_malloc(unsigned int size)
+{
+       void *p;
+       
+       /*if (sh_lock()==0){*/
+               sh_lock();
+               p=qm_malloc(shm_block, size);
+               sh_unlock();
+       /*
+       }else{
+               p=0;
+       }*/
+       return p;
+}
+
+
+
+#define sh_free(p) \
+do { \
+               sh_lock(); \
+               qm_free(shm_block, p); \
+               sh_unlock(); \
+}while(0)
+
+
+
+#define sh_status() \
+do { \
+               sh_lock(); \
+               qm_status(shm_block); \
+               sh_unlock(); \
+}while(0)
+
+
+       
+
+#endif
+
+#endif
+