]> jfr.im git - irc/quakenet/newserv.git/commitdiff
nsfree is now O(1), add nsrealloc and statistics.
authorChris Porter <redacted>
Fri, 29 Feb 2008 01:15:03 +0000 (01:15 +0000)
committerChris Porter <redacted>
Fri, 29 Feb 2008 01:15:03 +0000 (01:15 +0000)
core/nsmalloc.c
core/nsmalloc.h

index d7d093e3991a5135b29e872acd7eb7f8c722494e..ea6a216e08789d4b575e9fdcb6050f8d24e2ee8c 100644 (file)
@@ -11,10 +11,16 @@ void nsfreeall(unsigned int poolid);
 
 struct nsminfo {
   struct nsminfo *next;
+  union {
+    struct nsminfo *prev;
+    unsigned long count;
+  } p;
+
+  size_t size;
   char data[];
 };
 
-struct nsminfo *pools[MAXPOOL];
+struct nsminfo pools[MAXPOOL];
 
 void *nsmalloc(unsigned int poolid, size_t size) {
   struct nsminfo *nsmp;
@@ -28,28 +34,75 @@ void *nsmalloc(unsigned int poolid, size_t size) {
   if (!nsmp)
     return NULL;
   
-  nsmp->next=pools[poolid];
-  pools[poolid]=nsmp;
-  
+  nsmp->size=size;
+  pools[poolid].size+=size;
+  pools[poolid].p.count++;
+
+  nsmp->next=pools[poolid].next;
+  nsmp->p.prev=&pools[poolid];
+  if (pools[poolid].next)
+    pools[poolid].next->p.prev=nsmp;
+  pools[poolid].next=nsmp;
+
   return (void *)nsmp->data;
 }
 
+/* we dump core on ptr == NULL */
 void nsfree(unsigned int poolid, void *ptr) {
-  struct nsminfo *nsmp, **nsmh;
+  struct nsminfo *nsmp;
   
   if (poolid >= MAXPOOL)
     return;
-    
-  for (nsmh=&(pools[poolid]);*nsmh;nsmh=&((*nsmh)->next)) {
-    if ((void *)&((*nsmh)->data) == ptr) {
-      nsmp=*nsmh;
-      *nsmh = nsmp->next;
-      free(nsmp);
-      return;
-    }
+
+  /* evil */
+  nsmp=(struct nsminfo*)ptr - 1;
+
+  /* always set as we have a sentinel */
+  nsmp->p.prev->next=nsmp->next;
+  if (nsmp->next)
+    nsmp->next->p.prev=nsmp->p.prev;
+
+  pools[poolid].size-=nsmp->size;
+  pools[poolid].p.count--;
+
+  free(nsmp);
+  return;
+}
+
+void *nsrealloc(unsigned int poolid, void *ptr, size_t size) {
+  struct nsminfo *nsmp, *nsmpn;
+
+  if (ptr == NULL)
+    return nsmalloc(poolid, size);
+
+  if (size == 0) {
+    nsfree(poolid, ptr);
+    return NULL;
   }
-  
-  Error("core",ERR_WARNING,"Attempt to free unknown pointer %p in pool %d\n",ptr,poolid);
+
+  if (poolid >= MAXPOOL)
+    return NULL;
+
+  /* evil */
+  nsmp=(struct nsminfo *)ptr - 1;
+
+  if (size == nsmp->size)
+    return (void *)nsmp->data;
+
+  nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size);
+  if (!nsmpn)
+    return NULL;
+
+  pools[poolid].size+=size-nsmpn->size;
+  nsmpn->size=size;
+
+  /* always set as we have a sentinel */
+  nsmpn->p.prev->next=nsmpn;
+
+  if (nsmpn->next)
+    nsmpn->next->p.prev=nsmpn;
+
+  return (void *)nsmpn->data;
 }
 
 void nsfreeall(unsigned int poolid) {
@@ -58,22 +111,33 @@ void nsfreeall(unsigned int poolid) {
   if (poolid >= MAXPOOL)
     return;
  
-  for (nsmp=pools[poolid];nsmp;nsmp=nnsmp) {
+  for (nsmp=pools[poolid].next;nsmp;nsmp=nnsmp) {
     nnsmp=nsmp->next;
     free(nsmp);
   }
   
-  pools[poolid]=NULL;
+  pools[poolid].next=NULL;
+  pools[poolid].size=0;
+  pools[poolid].p.count=0;
 }
 
 void nsexit() {
   unsigned int i;
   
   for (i=0;i<MAXPOOL;i++) {
-    if (pools[i]) {
-      Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d\n",i);
+    if (pools[i].next) {
+      Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d (%lub, %lu items)\n",i,pools[i].size, pools[i].p.count);
       nsfreeall(i);
     }
   }
 }
 
+int nspoolstats(unsigned int poolid, size_t *size, unsigned long *count) {
+  if (poolid >= MAXPOOL)
+    return 0;
+
+  *size = pools[poolid].size;
+  *count = pools[poolid].p.count;
+
+  return 1;
+}
index e1bcd2dcb2c5b72da914e920c32362ced5bf31f3..47d69684174d743cfc9e068e427e0a6b4e20b756 100644 (file)
@@ -6,6 +6,8 @@ void *nsmalloc(unsigned int poolid, size_t size);
 void nsfree(unsigned int poolid, void *ptr);
 void nsfreeall(unsigned int poolid);
 void nsexit(void);
+void *nsrealloc(unsigned int poolid, void *ptr, size_t size);
+int nspoolstats(unsigned int poolid, size_t *size, unsigned long *count);
 
 #define MAXPOOL                100
 
@@ -20,3 +22,4 @@ void nsexit(void);
 #define POOL_AUTHTRACKER       7
 #define POOL_PROXYSCAN         8
 #define POOL_LUA               9
+#define POOL_TROJANSCAN                10