mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
keep cache of prealloced blocks.
git-svn-id: file:///svn/unbound/trunk@698 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
6f49c2fe55
commit
ce11690aa1
6 changed files with 95 additions and 6 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
64
util/alloc.c
64
util/alloc.c
|
|
@ -41,8 +41,11 @@
|
|||
|
||||
#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 */
|
||||
|
|
|
|||
22
util/alloc.h
22
util/alloc.h
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue