2
0
Andrei Pelinescu-Onciul 24 жил өмнө
parent
commit
6fa792822a
9 өөрчлөгдсөн 324 нэмэгдсэн , 12 устгасан
  1. 1 1
      Makefile
  2. 4 3
      data_lump.c
  3. 31 0
      mem.h
  4. 1 1
      msg_parser.c
  5. 1 0
      parse_via.c
  6. 232 0
      q_malloc.c
  7. 45 0
      q_malloc.h
  8. 7 6
      receive.c
  9. 2 1
      udp_server.c

+ 1 - 1
Makefile

@@ -28,7 +28,7 @@ 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 -DNO_DEBUG#-DSTATS -DNO_DEBUG 
+DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK #-DNO_DEBUG#-DSTATS -DNO_DEBUG 
 #-DNO_LOG
 
 PROFILE=  # -pg #set this if you want profiling

+ 4 - 3
data_lump.c

@@ -4,6 +4,7 @@
 
 #include "data_lump.h"
 #include "dprint.h"
+#include "mem.h"
 
 #include <stdlib.h>
 
@@ -200,18 +201,18 @@ void free_lump_list(struct lump* l)
 		r=crt->before;
 		while(r){
 			foo=r; r=r->before;
-			pkg_free_lump(foo);
+			free_lump(foo);
 			pkg_free(foo);
 		}
 		r=crt->after;
 		while(r){
 			foo=r; r=r->after;
-			pkg_free_lump(foo);
+			free_lump(foo);
 			pkg_free(foo);
 		}
 		
 		/*clean current elem*/
-		pkg_free_lump(crt);
+		free_lump(crt);
 		pkg_free(crt);
 	}
 }

+ 31 - 0
mem.h

@@ -0,0 +1,31 @@
+/* $Id$
+ *
+ * memory related stuff (malloc & friends)
+ * 
+ */
+
+
+#ifndef mem_h
+#define mem_h
+
+#ifdef PKG_MALLOC
+#include "q_malloc.h"
+
+extern struct qm_block* mem_block;
+
+
+#define pkg_malloc(s) qm_malloc(mem_block, s)
+#define pkg_free(p)   qm_free(mem_block, p)
+#define pkg_status()  qm_status(mem_block)
+
+#else
+#include <stdlib.h>
+
+#define pkg_malloc(s) malloc(s)
+#define pkg_free(p)  free(p)
+#define pkg_status()
+
+#endif
+
+
+#endif

+ 1 - 1
msg_parser.c

@@ -13,6 +13,7 @@
 #include "ut.h"
 #include "error.h"
 #include "dprint.h"
+#include "mem.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -928,4 +929,3 @@ void free_sip_msg(struct sip_msg* msg)
 
 
 
-}

+ 1 - 0
parse_via.c

@@ -22,6 +22,7 @@
 #include "dprint.h"
 #include "msg_parser.h"
 #include "ut.h"
+#include "mem.h"
 
 
 

+ 232 - 0
q_malloc.c

@@ -0,0 +1,232 @@
+/* $Id$
+ *
+ */
+
+#define q_malloc
+#ifdef q_malloc
+
+#include "q_malloc.h"
+#include "dprint.h"
+
+
+/*usefull macros*/
+#define FRAG_END(f)  \
+			((struct qm_frag_end*)((char*)f+sizeof(struct qm_frag)+f->size))
+
+#define FRAG_NEXT(f) \
+			((struct qm_frag*)((char*)f+sizeof(struct qm_frag)+f->size+ \
+							   sizeof(struct qm_frag_end)))
+			
+#define FRAG_PREV(f) \
+		( (struct qm_frag*) ( ((char*)f-sizeof(struct qm_frag_end))- \
+		((struct qm_frag_end*)((char*)f-sizeof(struct qm_frag_end)))->size- \
+			sizeof(struct qm_frag) ) )
+
+
+
+
+
+/* init malloc and return a qm_block*/
+struct qm_block* qm_malloc_init(char* address, unsigned int size)
+{
+	char* start;
+	char* end;
+	struct qm_block* qm;
+	unsigned int init_overhead;
+	unsigned int init_size;
+	
+	init_size=size;
+	/* make address and size multiple of 8*/
+	start=(char*)( ((unsigned int)address%8)?((unsigned int)address+8)/8*8:
+			(unsigned int)address);
+	if (size<start-address) return 0;
+	size-=(start-address);
+	if (size <8) return 0;
+	size=(size%8)?(size-8)/8*8:size;
+	
+	init_overhead=sizeof(struct qm_block)+sizeof(struct qm_frag)+
+		sizeof(struct qm_frag_end);
+	if (size < init_overhead)
+	{
+		/* not enough mem to create our control structures !!!*/
+		return 0;
+	}
+	end=start+size;
+	qm=(struct qm_block*)start;
+	memset(qm, 0, sizeof(struct qm_block));
+	qm->init_size=init_size;
+	qm->size=size-init_overhead;
+	qm->real_used=init_overhead;
+	
+	qm->first_frag=(struct qm_frag*)(start+sizeof(struct qm_block));
+	qm->last_frag_end=(struct qm_frag_end*)(end-sizeof(struct qm_frag_end));
+	/* init initial fragment*/
+	qm->first_frag->size=size;
+	qm->first_frag->u.nxt_free=&(qm->free_lst);
+	qm->last_frag_end->size=size;
+	qm->last_frag_end->prev_free=&(qm->free_lst);
+	/* init free_lst* */
+	qm->free_lst.u.nxt_free=qm->first_frag;
+	qm->free_lst_end.prev_free=qm->first_frag;
+	qm->free_lst.size=0;
+	qm->free_lst_end.size=0;
+	
+	
+	return qm;
+}
+
+
+static inline void qm_insert_free(struct qm_block* qm, struct qm_frag* frag)
+{
+	struct qm_frag* f;
+	struct qm_frag* prev;
+
+	for(f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free){
+		if (frag->size < f->size) break;
+	}
+	/*insert it here*/
+	prev=FRAG_END(f)->prev_free;
+	prev->u.nxt_free=frag;
+	FRAG_END(frag)->prev_free=prev;
+	frag->u.nxt_free=f;
+	FRAG_END(f)->prev_free=frag;
+}
+
+
+
+static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag)
+{
+	struct qm_frag *prev;
+	struct qm_frag *next;
+	
+	struct qm_frag_end *end;
+
+	prev=FRAG_END(frag)->prev_free;
+	next=frag->u.nxt_free;
+	prev->u.nxt_free=next;
+	FRAG_END(next)->prev_free=prev;
+	
+}
+
+
+
+void* qm_malloc(struct qm_block* qm, unsigned int size)
+{
+	struct qm_frag* f;
+	struct qm_frag_end* end;
+	struct qm_frag* n;
+	unsigned int rest;
+	unsigned int overhead;
+	
+	/*size must be a multiple of 8*/
+	size=(size%8)?(size+8)/8*8:size;
+	if (size>(qm->size-qm->real_used)) return 0;
+	if (qm->free_lst.u.nxt_free==&(qm->free_lst)) return 0;
+	/*search for a suitable free frag*/
+	for (f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free){
+		if (f->size>=size){
+			/* we found it!*/
+			/*detach it from the free list*/
+			qm_detach_free(qm, f);
+			/*mark it as "busy"*/
+			f->u.is_free=0;
+			
+			/*see if we'll use full frag, or we'll split it in 2*/
+			rest=f->size-size;
+			overhead=sizeof(struct qm_frag)+sizeof(struct qm_frag_end);
+			if (rest>overhead){
+				f->size=size;
+				/*split the fragment*/
+				end=FRAG_END(f);
+				end->size=size;
+				n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end));
+				n->size=rest-overhead;
+				FRAG_END(n)->size=n->size;
+				qm->real_used+=overhead;
+				/* reinsert n in free list*/
+				qm_insert_free(qm, n);
+			}else{
+				/* we cannot split this fragment any more => alloc all of it*/
+			}
+			qm->real_used+=f->size;
+			qm->used+=f->size;
+			return (char*)f+sizeof(struct qm_frag);
+		}
+	}
+	return 0;
+}
+
+
+
+void qm_free(struct qm_block* qm, void* p)
+{
+	struct qm_frag* f;
+	struct qm_frag* prev;
+	struct qm_frag* next;
+	struct qm_frag_end *end;
+	unsigned int overhead;
+	unsigned int size;
+
+	if (p==0) {
+		DBG("WARNING:qm_free: free(0) called\n");
+		return;
+	}
+	prev=next=0;
+	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
+	overhead=sizeof(struct qm_frag)+sizeof(struct qm_frag_end);
+	next=FRAG_NEXT(f);
+	size=f->size;
+	qm->used-=size;
+	qm->real_used-=size;
+	if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){
+		/* join */
+		qm_detach_free(qm, next);
+		size+=next->size+overhead;
+		qm->real_used-=overhead;
+	}
+	
+	if (f > qm->first_frag){
+		prev=FRAG_PREV(f);
+		/*	(struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f-
+								sizeof(struct qm_frag_end))->size);*/
+		if (prev->u.is_free){
+			/*join*/
+			qm_detach_free(qm, prev);
+			size+=prev->size+overhead;
+			qm->real_used-=overhead;
+			f=prev;
+		}
+	}
+	FRAG_END(f)->size=f->size;
+	qm_insert_free(qm, f);
+}
+
+
+
+void qm_status(struct qm_block* qm)
+{
+	struct qm_frag* f;
+	int i;
+
+	DBG("qm_status (%x):\n", qm);
+	DBG(" init_size= %d", qm->init_size);
+	DBG(" heap size= %d", qm->size);
+	DBG(" used= %d, used+overhead=%d, free=%d\n",
+			qm->used, qm->real_used, qm->size-qm->real_used);
+	
+	DBG("dumping all fragments:\n");
+	for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;f=FRAG_NEXT(f)
+			,i++)
+		DBG("    %3d. %c  address=%x  size=%d\n", i, (f->u.is_free)?'a':'N',
+				(char*)f+sizeof(struct qm_frag), f->size);
+	DBG("dumping free list:\n");
+	for (f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free)
+		DBG("    %3d. %c  address=%x  size=%d\n", i, (f->u.is_free)?'a':'N',
+				(char*)f+sizeof(struct qm_frag), f->size);
+	DBG("-----------------------------\n");
+}
+
+
+
+
+#endif

+ 45 - 0
q_malloc.h

@@ -0,0 +1,45 @@
+/* $Id$
+ *
+ * simple & fast malloc library
+ */
+
+#ifndef q_malloc_h
+#define q_malloc_h
+
+
+struct qm_frag{
+	unsigned int size;
+	union{
+		struct qm_frag* nxt_free;
+		int is_free;
+	}u;
+};
+
+struct qm_frag_end{
+	unsigned int size;
+	struct qm_frag* prev_free;
+};
+
+
+struct qm_block{
+	unsigned int init_size;
+	unsigned int size; /* total size */
+	unsigned int used; /* alloc'ed size*/
+	unsigned int real_used; /* used+malloc overhead*/
+	
+	struct qm_frag* first_frag;
+	struct qm_frag_end* last_frag_end;
+	
+	struct qm_frag free_lst;
+	struct qm_frag_end free_lst_end;
+};
+
+
+
+struct qm_block* qm_malloc_init(char* address, unsigned int size);
+void* qm_malloc(struct qm_block*, unsigned int size);
+void  qm_free(struct qm_block*, void* p);
+void  qm_status(struct qm_block*);
+
+
+#endif

+ 7 - 6
receive.c

@@ -11,6 +11,7 @@
 #include "msg_parser.h"
 #include "forward.h"
 #include "action.h"
+#include "mem.h"
 
 
 #ifdef DEBUG_DMALLOC
@@ -27,7 +28,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 {
 	struct sip_msg* msg;
 
-	msg=pkt_malloc(sizeof(struct sip_msg));
+	msg=pkg_malloc(sizeof(struct sip_msg));
 	if (msg==0) goto error1;
 	msg_no++;
 #ifdef STATS
@@ -41,7 +42,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 	msg->src_ip=src_ip;
 	msg->id=msg_no;
 	/* make a copy of the message */
-	msg->orig=(char*) pkt_malloc(len+1);
+	msg->orig=(char*) pkg_malloc(len+1);
 	if (msg->orig==0){
 		LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
 		goto error1;
@@ -108,7 +109,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 skip:
 	DBG("skip:...\n");
 	free_sip_msg(msg);
-	pkt_free(msg);
+	pkg_free(msg);
 #ifdef STATS
 	if (skipped) update_received_drops;
 #endif
@@ -116,14 +117,14 @@ skip:
 error:
 	DBG("error:...\n");
 	free_sip_msg(msg);
-	pkt_free(msg);
+	pkg_free(msg);
 #ifdef STATS
 	update_received_drops;
 #endif
 	return -1;
 error1:
-	if (msg) pkt_free(msg);
-	pkt_free(buf);
+	if (msg) pkg_free(msg);
+	pkg_free(buf);
 #ifdef STATS
 	update_received_drops;
 #endif

+ 2 - 1
udp_server.c

@@ -14,6 +14,7 @@
 #include "config.h"
 #include "dprint.h"
 #include "receive.h"
+#include "mem.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -153,7 +154,7 @@ int udp_rcv_loop()
 	struct sockaddr* from;
 	int fromlen;
 
-	buf=pkt_malloc(BUF_SIZE+1);
+	buf=pkg_malloc(BUF_SIZE+1);
 	if (buf==0){
 		LOG(L_ERR, "ERROR: udp_rcv_loop: could not allocate receive"
 				 " buffer\n");