]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
keep cache of prealloced blocks.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 18 Oct 2007 22:17:02 +0000 (22:17 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 18 Oct 2007 22:17:02 +0000 (22:17 +0000)
git-svn-id: file:///svn/unbound/trunk@698 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/mesh.c
testcode/ldns-testpkts.c
testcode/unitverify.c
util/alloc.c
util/alloc.h

index d474f146b4a8a0c3c65ff16e6cb3a3ecc5449740..98d0aa7e34c1a3defa51670563ca90035b7eecec 100644 (file)
@@ -13,6 +13,9 @@
        - start of regional allocator code.
        - regional uses less memory and variables, simplified code.
        - remove of region-allocator.
+       - alloc cache keeps a cache of recently released regional blocks,
+         up to a maximum.
+       - make unit test cleanly free memory.
 
 17 October 2007: Wouter
        - fixup another cycle detect and ns-addr timeout resolution bug.
index 1ec5ca8c4f78d13e7533f0288bcb88845ecc0ae3..22f951e8857054401f73b020bf43e97410430156 100644 (file)
@@ -53,6 +53,7 @@
 #include "util/data/msgencode.h"
 #include "util/timehist.h"
 #include "util/fptr_wlist.h"
+#include "util/alloc.h"
 
 int
 mesh_state_compare(const void* ap, const void* bp)
@@ -195,7 +196,7 @@ struct mesh_state*
 mesh_state_create(struct module_env* env, struct query_info* qinfo, 
        uint16_t qflags, int prime)
 {
-       struct regional* region = regional_create();
+       struct regional* region = alloc_reg_obtain(env->alloc);
        struct mesh_state* mstate;
        int i;
        if(!region)
@@ -203,7 +204,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
        mstate = (struct mesh_state*)regional_alloc(region, 
                sizeof(struct mesh_state));
        if(!mstate) {
-               regional_destroy(region);
+               alloc_reg_release(env->alloc, region);
                return NULL;
        }
        memset(mstate, 0, sizeof(*mstate));
@@ -222,7 +223,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
        mstate->s.qinfo.qname = regional_alloc_init(region, qinfo->qname,
                qinfo->qname_len);
        if(!mstate->s.qinfo.qname) {
-               regional_destroy(region);
+               alloc_reg_release(env->alloc, region);
                return NULL;
        }
        /* remove all weird bits from qflags */
@@ -258,7 +259,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
                mstate->s.minfo[i] = NULL;
                mstate->s.ext_state[i] = module_finished;
        }
-       regional_destroy(mstate->s.region);
+       alloc_reg_release(mstate->s.env->alloc, mstate->s.region);
 }
 
 void 
index c4e6b6c06d980bbb3124ce163b765d23a1ff6257..d11929b7939a09a14e4ef556514137a1824de1ad 100644 (file)
@@ -534,6 +534,8 @@ read_datafile(const char* name)
        verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
 
        fclose(in);
+       ldns_rdf_deep_free(origin);
+       ldns_rdf_deep_free(prev_rr);
        return list;
 }
 
index 66462c774f7877e7c4be5628576894156d7c9460..353aeb444b63367fc5cdac2b60ae1011989bc77f 100644 (file)
@@ -282,6 +282,7 @@ verifytest_file(const char* fname, const char* at_date)
                verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
        }
 
+       ub_packed_rrset_parsedelete(dnskey, &alloc);
        delete_entry(list);
        regional_destroy(region);
        alloc_clear(&alloc);
index a6ac2caee298510f9d5cde3a5cdbe46ca2640595..113f6a737c4f0ca20a9e2738a6030503e72944bf 100644 (file)
 
 #include "config.h"
 #include "util/alloc.h"
+#include "util/regional.h"
 #include "util/data/packed_rrset.h"
 
+/** custom size of cached regional blocks */
+#define ALLOC_REG_SIZE 16384
 /** number of bits for ID part of uint64, rest for number of threads. */
 #define THRNUM_SHIFT   48      /* for 65k threads, 2^48 rrsets per thr. */
 
@@ -74,6 +77,21 @@ prealloc(struct alloc_cache* alloc)
        }
 }
 
+/** prealloc region blocks */
+static void
+prealloc_blocks(struct alloc_cache* alloc, size_t num)
+{
+       size_t i;
+       struct regional* r;
+       for(i=0; i<num; i++) {
+               r = regional_create_custom(ALLOC_REG_SIZE);
+               if(!r) fatal_exit("prealloc blocks: out of memory");
+               r->next = (char*)alloc->reg_list;
+               alloc->reg_list = r;
+               alloc->num_reg_blocks ++;
+       }
+}
+
 void 
 alloc_init(struct alloc_cache* alloc, struct alloc_cache* super,
        int thread_num)
@@ -88,6 +106,11 @@ alloc_init(struct alloc_cache* alloc, struct alloc_cache* super,
        alloc->last_id -= 1;                    /* for compiler portability. */
        alloc->last_id |= alloc->next_id;
        alloc->next_id += 1;                    /* because id=0 is special. */
+       alloc->max_reg_blocks = 100;
+       alloc->num_reg_blocks = 0;
+       alloc->reg_list = NULL;
+       if(alloc->super)
+               prealloc_blocks(alloc, alloc->max_reg_blocks);
        if(!alloc->super) {
                lock_quick_init(&alloc->lock);
                lock_protect(&alloc->lock, alloc, sizeof(*alloc));
@@ -98,6 +121,7 @@ void
 alloc_clear(struct alloc_cache* alloc)
 {
        alloc_special_t* p, *np;
+       struct regional* r, *nr;
        if(!alloc)
                return;
        if(!alloc->super) {
@@ -126,6 +150,14 @@ alloc_clear(struct alloc_cache* alloc)
        }
        alloc->quar = 0;
        alloc->num_quar = 0;
+       r = alloc->reg_list;
+       while(r) {
+               nr = (struct regional*)r->next;
+               free(r);
+               r = nr;
+       }
+       alloc->reg_list = NULL;
+       alloc->num_reg_blocks = 0;
 }
 
 uint64_t
@@ -236,8 +268,8 @@ alloc_special_release(struct alloc_cache* alloc, alloc_special_t* mem)
 void 
 alloc_stats(struct alloc_cache* alloc)
 {
-       log_info("%salloc: %d in cache.", alloc->super?"":"sup",
-               (int)alloc->num_quar);
+       log_info("%salloc: %d in cache, %d blocks.", alloc->super?"":"sup",
+               (int)alloc->num_quar, (int)alloc->num_reg_blocks);
 }
 
 size_t alloc_get_mem(struct alloc_cache* alloc)
@@ -251,12 +283,40 @@ size_t alloc_get_mem(struct alloc_cache* alloc)
        for(p = alloc->quar; p; p = alloc_special_next(p)) {
                s += lock_get_mem(&p->entry.lock);
        }
+       s += alloc->num_reg_blocks * ALLOC_REG_SIZE;
        if(!alloc->super) {
                lock_quick_unlock(&alloc->lock);
        }
        return s;
 }
 
+struct regional* 
+alloc_reg_obtain(struct alloc_cache* alloc)
+{
+       if(alloc->num_reg_blocks > 0) {
+               struct regional* r = alloc->reg_list;
+               alloc->reg_list = (struct regional*)r->next;
+               r->next = NULL;
+               alloc->num_reg_blocks--;
+               return r;
+       }
+       return regional_create_custom(ALLOC_REG_SIZE);
+}
+
+void 
+alloc_reg_release(struct alloc_cache* alloc, struct regional* r)
+{
+       if(alloc->num_reg_blocks >= alloc->max_reg_blocks) {
+               regional_destroy(r);
+               return;
+       }
+       regional_free_all(r);
+       log_assert(r->next == NULL);
+       r->next = (char*)alloc->reg_list;
+       alloc->reg_list = r;
+       alloc->num_reg_blocks++;
+}
+
 /** global debug value to keep track of total memory mallocs */
 size_t unbound_mem_alloc = 0;
 /** global debug value to keep track of total memory frees */
index 1bf8e4e8209d4de43f6676c477041331a7a22d6b..8bba43e5de2035a778c038bbd0fa831b8d88ef2b 100644 (file)
@@ -50,6 +50,7 @@
 
 #include "util/locks.h"
 struct ub_packed_rrset_key;
+struct regional;
 
 /** The special type, packed rrset. Not allowed to be used for other memory */
 typedef struct ub_packed_rrset_key alloc_special_t;
@@ -83,6 +84,13 @@ struct alloc_cache {
        uint64_t next_id;
        /** last id number possible */
        uint64_t last_id;
+
+       /** how many regional blocks to keep back max */
+       size_t max_reg_blocks;
+       /** how many regional blocks are kept now */
+       size_t num_reg_blocks;
+       /** linked list of regional blocks, using regional->next */
+       struct regional* reg_list;
 };
 
 /**
@@ -140,4 +148,18 @@ size_t alloc_get_mem(struct alloc_cache* alloc);
  */
 void alloc_stats(struct alloc_cache* alloc);
 
+/**
+ * Get a new regional for query states
+ * @param alloc: where to alloc it.
+ * @return regional for use or NULL on alloc failure.
+ */
+struct regional* alloc_reg_obtain(struct alloc_cache* alloc);
+
+/**
+ * Put regional for query states back into alloc cache.
+ * @param alloc: where to alloc it.
+ * @param r: regional to put back.
+ */
+void alloc_reg_release(struct alloc_cache* alloc, struct regional* r);
+
 #endif /* UTIL_ALLOC_H */