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.
|
- start of regional allocator code.
|
||||||
- regional uses less memory and variables, simplified code.
|
- regional uses less memory and variables, simplified code.
|
||||||
- remove of region-allocator.
|
- 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
|
17 October 2007: Wouter
|
||||||
- fixup another cycle detect and ns-addr timeout resolution bug.
|
- fixup another cycle detect and ns-addr timeout resolution bug.
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#include "util/data/msgencode.h"
|
#include "util/data/msgencode.h"
|
||||||
#include "util/timehist.h"
|
#include "util/timehist.h"
|
||||||
#include "util/fptr_wlist.h"
|
#include "util/fptr_wlist.h"
|
||||||
|
#include "util/alloc.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
mesh_state_compare(const void* ap, const void* bp)
|
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,
|
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime)
|
uint16_t qflags, int prime)
|
||||||
{
|
{
|
||||||
struct regional* region = regional_create();
|
struct regional* region = alloc_reg_obtain(env->alloc);
|
||||||
struct mesh_state* mstate;
|
struct mesh_state* mstate;
|
||||||
int i;
|
int i;
|
||||||
if(!region)
|
if(!region)
|
||||||
|
|
@ -203,7 +204,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||||
mstate = (struct mesh_state*)regional_alloc(region,
|
mstate = (struct mesh_state*)regional_alloc(region,
|
||||||
sizeof(struct mesh_state));
|
sizeof(struct mesh_state));
|
||||||
if(!mstate) {
|
if(!mstate) {
|
||||||
regional_destroy(region);
|
alloc_reg_release(env->alloc, region);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(mstate, 0, sizeof(*mstate));
|
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,
|
mstate->s.qinfo.qname = regional_alloc_init(region, qinfo->qname,
|
||||||
qinfo->qname_len);
|
qinfo->qname_len);
|
||||||
if(!mstate->s.qinfo.qname) {
|
if(!mstate->s.qinfo.qname) {
|
||||||
regional_destroy(region);
|
alloc_reg_release(env->alloc, region);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* remove all weird bits from qflags */
|
/* remove all weird bits from qflags */
|
||||||
|
|
@ -258,7 +259,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||||
mstate->s.minfo[i] = NULL;
|
mstate->s.minfo[i] = NULL;
|
||||||
mstate->s.ext_state[i] = module_finished;
|
mstate->s.ext_state[i] = module_finished;
|
||||||
}
|
}
|
||||||
regional_destroy(mstate->s.region);
|
alloc_reg_release(mstate->s.env->alloc, mstate->s.region);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -534,6 +534,8 @@ read_datafile(const char* name)
|
||||||
verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
|
verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
|
||||||
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
ldns_rdf_deep_free(origin);
|
||||||
|
ldns_rdf_deep_free(prev_rr);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,7 @@ verifytest_file(const char* fname, const char* at_date)
|
||||||
verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
|
verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ub_packed_rrset_parsedelete(dnskey, &alloc);
|
||||||
delete_entry(list);
|
delete_entry(list);
|
||||||
regional_destroy(region);
|
regional_destroy(region);
|
||||||
alloc_clear(&alloc);
|
alloc_clear(&alloc);
|
||||||
|
|
|
||||||
64
util/alloc.c
64
util/alloc.c
|
|
@ -41,8 +41,11 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/alloc.h"
|
#include "util/alloc.h"
|
||||||
|
#include "util/regional.h"
|
||||||
#include "util/data/packed_rrset.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. */
|
/** 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. */
|
#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
|
void
|
||||||
alloc_init(struct alloc_cache* alloc, struct alloc_cache* super,
|
alloc_init(struct alloc_cache* alloc, struct alloc_cache* super,
|
||||||
int thread_num)
|
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 -= 1; /* for compiler portability. */
|
||||||
alloc->last_id |= alloc->next_id;
|
alloc->last_id |= alloc->next_id;
|
||||||
alloc->next_id += 1; /* because id=0 is special. */
|
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) {
|
if(!alloc->super) {
|
||||||
lock_quick_init(&alloc->lock);
|
lock_quick_init(&alloc->lock);
|
||||||
lock_protect(&alloc->lock, alloc, sizeof(*alloc));
|
lock_protect(&alloc->lock, alloc, sizeof(*alloc));
|
||||||
|
|
@ -98,6 +121,7 @@ void
|
||||||
alloc_clear(struct alloc_cache* alloc)
|
alloc_clear(struct alloc_cache* alloc)
|
||||||
{
|
{
|
||||||
alloc_special_t* p, *np;
|
alloc_special_t* p, *np;
|
||||||
|
struct regional* r, *nr;
|
||||||
if(!alloc)
|
if(!alloc)
|
||||||
return;
|
return;
|
||||||
if(!alloc->super) {
|
if(!alloc->super) {
|
||||||
|
|
@ -126,6 +150,14 @@ alloc_clear(struct alloc_cache* alloc)
|
||||||
}
|
}
|
||||||
alloc->quar = 0;
|
alloc->quar = 0;
|
||||||
alloc->num_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
|
uint64_t
|
||||||
|
|
@ -236,8 +268,8 @@ alloc_special_release(struct alloc_cache* alloc, alloc_special_t* mem)
|
||||||
void
|
void
|
||||||
alloc_stats(struct alloc_cache* alloc)
|
alloc_stats(struct alloc_cache* alloc)
|
||||||
{
|
{
|
||||||
log_info("%salloc: %d in cache.", alloc->super?"":"sup",
|
log_info("%salloc: %d in cache, %d blocks.", alloc->super?"":"sup",
|
||||||
(int)alloc->num_quar);
|
(int)alloc->num_quar, (int)alloc->num_reg_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t alloc_get_mem(struct alloc_cache* alloc)
|
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)) {
|
for(p = alloc->quar; p; p = alloc_special_next(p)) {
|
||||||
s += lock_get_mem(&p->entry.lock);
|
s += lock_get_mem(&p->entry.lock);
|
||||||
}
|
}
|
||||||
|
s += alloc->num_reg_blocks * ALLOC_REG_SIZE;
|
||||||
if(!alloc->super) {
|
if(!alloc->super) {
|
||||||
lock_quick_unlock(&alloc->lock);
|
lock_quick_unlock(&alloc->lock);
|
||||||
}
|
}
|
||||||
return s;
|
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 */
|
/** global debug value to keep track of total memory mallocs */
|
||||||
size_t unbound_mem_alloc = 0;
|
size_t unbound_mem_alloc = 0;
|
||||||
/** global debug value to keep track of total memory frees */
|
/** 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"
|
#include "util/locks.h"
|
||||||
struct ub_packed_rrset_key;
|
struct ub_packed_rrset_key;
|
||||||
|
struct regional;
|
||||||
|
|
||||||
/** The special type, packed rrset. Not allowed to be used for other memory */
|
/** The special type, packed rrset. Not allowed to be used for other memory */
|
||||||
typedef struct ub_packed_rrset_key alloc_special_t;
|
typedef struct ub_packed_rrset_key alloc_special_t;
|
||||||
|
|
@ -83,6 +84,13 @@ struct alloc_cache {
|
||||||
uint64_t next_id;
|
uint64_t next_id;
|
||||||
/** last id number possible */
|
/** last id number possible */
|
||||||
uint64_t last_id;
|
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);
|
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 */
|
#endif /* UTIL_ALLOC_H */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue