please lint, docs.

Fixup ignored return value.


git-svn-id: file:///svn/unbound/trunk@234 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-04-10 07:56:05 +00:00
parent 6457115869
commit 83039ba0b0
4 changed files with 112 additions and 42 deletions

View file

@ -5,6 +5,7 @@
- import of region-allocator code from nsd. - import of region-allocator code from nsd.
- set alloc special type to ub_packed_rrset_key. - set alloc special type to ub_packed_rrset_key.
Uses lruhash entry overflow chain next pointer in alloc cache. Uses lruhash entry overflow chain next pointer in alloc cache.
- doxygen documentation for region-allocator.
5 April 2007: Wouter 5 April 2007: Wouter
- discussed packed rrset with Jelte. - discussed packed rrset with Jelte.

View file

@ -48,7 +48,10 @@
#include "util/data/dname.h" #include "util/data/dname.h"
int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc, int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc,
struct query_info* qinf, struct reply_info** rep); struct query_info* qinf, struct reply_info** rep)
{
return LDNS_RCODE_SERVFAIL;
}
void void
reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc) reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc)

View file

@ -35,64 +35,91 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/**
* \file
* Region allocator. Allocates small portions of of larger chunks.
*/
#include "config.h" #include "config.h"
#include "util/log.h"
#include <assert.h> #include "util/region-allocator.h"
#include <stdlib.h>
#include <string.h>
#include "region-allocator.h"
#ifdef ALIGNMENT #ifdef ALIGNMENT
# undef ALIGNMENT # undef ALIGNMENT
#endif #endif
/** increase size until it fits alignment of s bytes */
#define ALIGN_UP(x, s) (((x) + s - 1) & (~(s - 1))) #define ALIGN_UP(x, s) (((x) + s - 1) & (~(s - 1)))
/** what size to align on */
#define ALIGNMENT (sizeof(void *)) #define ALIGNMENT (sizeof(void *))
#define CHECK_DOUBLE_FREE 0 /* set to 1 to perform expensive check for double recycle() */ /** set to 1 to perform expensive check for double recycle() */
#define CHECK_DOUBLE_FREE 0
/** typedef for cleanup structure */
typedef struct cleanup cleanup_type; typedef struct cleanup cleanup_type;
/** store chunks and user cleanup actions */
struct cleanup struct cleanup
{ {
/** action to call (such as free) */
void (*action)(void *); void (*action)(void *);
/** pointer to pass to action. */
void *data; void *data;
}; };
/** linked list of recycle elements of a certain size. */
struct recycle_elem { struct recycle_elem {
/** next in recycle list. First bytes of block is used for this ptr */
struct recycle_elem* next; struct recycle_elem* next;
}; };
/** hidden type of the region. */
struct region struct region
{ {
/** total bytes allocated */
size_t total_allocated; size_t total_allocated;
/** number of small objects allocated */
size_t small_objects; size_t small_objects;
/** number of large objects allocated */
size_t large_objects; size_t large_objects;
/** number of chunks allocated */
size_t chunk_count; size_t chunk_count;
size_t unused_space; /* Unused space due to alignment, etc. */ /** Unused space due to alignment, etc. */
size_t unused_space;
/** number of bytes allocated in the current chunk. */
size_t allocated; size_t allocated;
/** initial chunk */
char *initial_data; char *initial_data;
/** current chunk */
char *data; char *data;
/** how to allocate memory (for chunks) */
void *(*allocator)(size_t); void *(*allocator)(size_t);
/** how to deallocate memory (for chunks) */
void (*deallocator)(void *); void (*deallocator)(void *);
/** current max size of growing cleanup array */
size_t maximum_cleanup_count; size_t maximum_cleanup_count;
/** number used inside the cleanup array */
size_t cleanup_count; size_t cleanup_count;
/** cleanup array, chunks and user actions */
cleanup_type *cleanups; cleanup_type *cleanups;
/** size of chunks */
size_t chunk_size; size_t chunk_size;
/** large object size */
size_t large_object_size; size_t large_object_size;
/* if not NULL recycling is enabled. /** if not NULL recycling is enabled.
* It is an array of linked lists of parts held for recycle. * It is an array of linked lists of parts held for recycle.
* The parts are all pointers to within the allocated chunks. * The parts are all pointers to within the allocated chunks.
* Array [i] points to elements of size i. */ * Array [i] points to elements of size i. */
struct recycle_elem** recycle_bin; struct recycle_elem** recycle_bin;
/* amount of memory in recycle storage */ /** amount of memory in recycle storage */
size_t recycle_size; size_t recycle_size;
}; };
/** common code to initialize a region */
static region_type * static region_type *
alloc_region_base(void *(*allocator)(size_t size), alloc_region_base(void *(*allocator)(size_t size),
void (*deallocator)(void *), void (*deallocator)(void *),
@ -116,7 +143,7 @@ alloc_region_base(void *(*allocator)(size_t size),
result->allocator = allocator; result->allocator = allocator;
result->deallocator = deallocator; result->deallocator = deallocator;
assert(initial_cleanup_count > 0); log_assert(initial_cleanup_count > 0);
result->maximum_cleanup_count = initial_cleanup_count; result->maximum_cleanup_count = initial_cleanup_count;
result->cleanup_count = 0; result->cleanup_count = 0;
result->cleanups = (cleanup_type *) allocator( result->cleanups = (cleanup_type *) allocator(
@ -132,8 +159,7 @@ alloc_region_base(void *(*allocator)(size_t size),
} }
region_type * region_type *
region_create(void *(*allocator)(size_t size), region_create(void *(*allocator)(size_t), void (*deallocator)(void *))
void (*deallocator)(void *))
{ {
region_type* result = alloc_region_base(allocator, deallocator, region_type* result = alloc_region_base(allocator, deallocator,
DEFAULT_INITIAL_CLEANUP_SIZE); DEFAULT_INITIAL_CLEANUP_SIZE);
@ -162,7 +188,7 @@ region_type *region_create_custom(void *(*allocator)(size_t),
initial_cleanup_size); initial_cleanup_size);
if(!result) if(!result)
return NULL; return NULL;
assert(large_object_size <= chunk_size); log_assert(large_object_size <= chunk_size);
result->chunk_size = chunk_size; result->chunk_size = chunk_size;
result->large_object_size = large_object_size; result->large_object_size = large_object_size;
if(result->chunk_size > 0) { if(result->chunk_size > 0) {
@ -209,7 +235,7 @@ region_destroy(region_type *region)
size_t size_t
region_add_cleanup(region_type *region, void (*action)(void *), void *data) region_add_cleanup(region_type *region, void (*action)(void *), void *data)
{ {
assert(action); log_assert(action);
if (region->cleanup_count >= region->maximum_cleanup_count) { if (region->cleanup_count >= region->maximum_cleanup_count) {
cleanup_type *cleanups = (cleanup_type *) region->allocator( cleanup_type *cleanups = (cleanup_type *) region->allocator(
@ -281,7 +307,13 @@ region_alloc(region_type *region, size_t size)
++region->chunk_count; ++region->chunk_count;
region->unused_space += region->chunk_size - region->allocated; region->unused_space += region->chunk_size - region->allocated;
region_add_cleanup(region, region->deallocator, chunk); if(!region_add_cleanup(region, region->deallocator, chunk)) {
region->deallocator(chunk);
region->chunk_count--;
region->unused_space -=
region->chunk_size - region->allocated;
return NULL;
}
region->allocated = 0; region->allocated = 0;
region->data = (char *) chunk; region->data = (char *) chunk;
} }
@ -318,13 +350,13 @@ void
region_free_all(region_type *region) region_free_all(region_type *region)
{ {
size_t i; size_t i;
assert(region); log_assert(region);
assert(region->cleanups); log_assert(region->cleanups);
i = region->cleanup_count; i = region->cleanup_count;
while (i > 0) { while (i > 0) {
--i; --i;
assert(region->cleanups[i].action); log_assert(region->cleanups[i].action);
region->cleanups[i].action(region->cleanups[i].data); region->cleanups[i].action(region->cleanups[i].data);
} }
@ -369,13 +401,13 @@ region_recycle(region_type *region, void *block, size_t size)
if(aligned_size < region->large_object_size) { if(aligned_size < region->large_object_size) {
struct recycle_elem* elem = (struct recycle_elem*)block; struct recycle_elem* elem = (struct recycle_elem*)block;
/* we rely on the fact that ALIGNMENT is void* so the next will fit */ /* we rely on the fact that ALIGNMENT is void* so the next will fit */
assert(aligned_size >= sizeof(struct recycle_elem)); log_assert(aligned_size >= sizeof(struct recycle_elem));
if(CHECK_DOUBLE_FREE) { if(CHECK_DOUBLE_FREE) {
/* make sure the same ptr is not freed twice. */ /* make sure the same ptr is not freed twice. */
struct recycle_elem *p = region->recycle_bin[aligned_size]; struct recycle_elem *p = region->recycle_bin[aligned_size];
while(p) { while(p) {
assert(p != elem); log_assert(p != elem);
p = p->next; p = p->next;
} }
} }
@ -446,7 +478,7 @@ region_log_stats(region_type *region)
{ {
char buf[10240], *str=buf; char buf[10240], *str=buf;
int len=0; int len=0;
sprintf(str, "%lu objects (%lu small/%lu large), %lu bytes allocated (%lu wasted) in %lu chunks, %lu cleanups, %lu in recyclebin%n", snprintf(str, 10240, "%lu objects (%lu small/%lu large), %lu bytes allocated (%lu wasted) in %lu chunks, %lu cleanups, %lu in recyclebin%n",
(unsigned long) (region->small_objects + region->large_objects), (unsigned long) (region->small_objects + region->large_objects),
(unsigned long) region->small_objects, (unsigned long) region->small_objects,
(unsigned long) region->large_objects, (unsigned long) region->large_objects,
@ -468,8 +500,8 @@ region_log_stats(region_type *region)
el = el->next; el = el->next;
} }
if(i%ALIGNMENT == 0 && i!=0) { if(i%ALIGNMENT == 0 && i!=0) {
sprintf(str, " %lu%n", (unsigned long)count, snprintf(str, 10240, " %lu%n",
&len); (unsigned long)count, &len);
str+=len; str+=len;
} }
} }

View file

@ -35,32 +35,49 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/**
* \file
* Region allocator. Allocates small portions of of larger chunks.
*/
#ifndef _REGION_ALLOCATOR_H_ #ifndef _REGION_ALLOCATOR_H_
#define _REGION_ALLOCATOR_H_ #define _REGION_ALLOCATOR_H_
#include <stdio.h> #include <stdio.h>
/** The region type */
typedef struct region region_type; typedef struct region region_type;
/** Default reasonable size for chunks */
#define DEFAULT_CHUNK_SIZE 4096 #define DEFAULT_CHUNK_SIZE 4096
/** Default size for large objects - allocated outside of chunks. */
#define DEFAULT_LARGE_OBJECT_SIZE (DEFAULT_CHUNK_SIZE / 8) #define DEFAULT_LARGE_OBJECT_SIZE (DEFAULT_CHUNK_SIZE / 8)
/** Default size for cleanup array initial size. */
#define DEFAULT_INITIAL_CLEANUP_SIZE 16 #define DEFAULT_INITIAL_CLEANUP_SIZE 16
/* /**
* Create a new region. * Create a new region.
* @param allocator: 'malloc' or another memory allocator.
* @param deallocator: 'free' or another memory deallocator.
*/ */
region_type *region_create(void *(*allocator)(size_t), region_type *region_create(void *(*allocator)(size_t),
void (*deallocator)(void *)); void (*deallocator)(void *));
/* /**
* Create a new region, with chunk size and large object size. * Create a new region, with chunk size and large object size.
* @param allocator: 'malloc' or another memory allocator.
* @param deallocator: 'free' or another memory deallocator.
* @param chunk_size: size of chunks to allocate.
* @param large_object_size:
* Note that large_object_size must be <= chunk_size. * Note that large_object_size must be <= chunk_size.
* Anything larger than the large object size is individually alloced. * Anything larger than the large object size is individually alloced.
* large_object_size = chunk_size/8 is reasonable; * large_object_size = chunk_size/8 is reasonable;
* @param initial_cleanup_size:
* initial_cleanup_size is the number of prealloced ptrs for cleanups. * initial_cleanup_size is the number of prealloced ptrs for cleanups.
* The cleanups are in a growing array, and it must start larger than zero. * The cleanups are in a growing array, and it must start larger than zero.
* If recycle is true, environmentally friendly memory recycling is be enabled. * @param recycle:
* If recycle is true, environmentally friendly memory recycling is enabled.
*/ */
region_type *region_create_custom(void *(*allocator)(size_t), region_type *region_create_custom(void *(*allocator)(size_t),
void (*deallocator)(void *), void (*deallocator)(void *),
@ -70,73 +87,90 @@ region_type *region_create_custom(void *(*allocator)(size_t),
int recycle); int recycle);
/* /**
* Destroy REGION. All memory associated with REGION is freed as if * Destroy REGION. All memory associated with REGION is freed as if
* region_free_all was called. * region_free_all was called.
* @param region: to delete.
*/ */
void region_destroy(region_type *region); void region_destroy(region_type *region);
/* /**
* Add a cleanup to REGION. ACTION will be called with DATA as * Add a cleanup to REGION.
* @param region: the region.
* @param action: ACTION will be called with DATA as
* parameter when the region is freed or destroyed. * parameter when the region is freed or destroyed.
* * @param data: argument to action.
* Returns 0 on failure. * @return: 0 on failure.
*/ */
size_t region_add_cleanup(region_type *region, size_t region_add_cleanup(region_type *region,
void (*action)(void *), void (*action)(void *),
void *data); void *data);
/* /**
* Allocate SIZE bytes of memory inside REGION. The memory is * Allocate SIZE bytes of memory inside REGION. The memory is
* deallocated when region_free_all is called for this region. * deallocated when region_free_all is called for this region.
* @param region: the region.
* @param size: number of bytes.
* @return: pointer to memory allocated.
*/ */
void *region_alloc(region_type *region, size_t size); void *region_alloc(region_type *region, size_t size);
/* /**
* Allocate SIZE bytes of memory inside REGION and copy INIT into it. * Allocate SIZE bytes of memory inside REGION and copy INIT into it.
* The memory is deallocated when region_free_all is called for this * The memory is deallocated when region_free_all is called for this
* region. * region.
* @param region: the region.
* @param init: to copy.
* @param size: number of bytes.
* @return: pointer to memory allocated.
*/ */
void *region_alloc_init(region_type *region, const void *init, size_t size); void *region_alloc_init(region_type *region, const void *init, size_t size);
/* /**
* Allocate SIZE bytes of memory inside REGION that are initialized to * Allocate SIZE bytes of memory inside REGION that are initialized to
* 0. The memory is deallocated when region_free_all is called for * 0. The memory is deallocated when region_free_all is called for
* this region. * this region.
* @param region: the region.
* @param size: number of bytes.
* @return: pointer to memory allocated.
*/ */
void *region_alloc_zero(region_type *region, size_t size); void *region_alloc_zero(region_type *region, size_t size);
/* /**
* Run the cleanup actions and free all memory associated with REGION. * Run the cleanup actions and free all memory associated with REGION.
* @param region: the region.
*/ */
void region_free_all(region_type *region); void region_free_all(region_type *region);
/* /**
* Duplicate STRING and allocate the result in REGION. * Duplicate STRING and allocate the result in REGION.
*/ */
char *region_strdup(region_type *region, const char *string); char *region_strdup(region_type *region, const char *string);
/* /**
* Recycle an allocated memory block. Pass size used to alloc it. * Recycle an allocated memory block. Pass size used to alloc it.
* Does nothing if recycling is not enabled for the region. * Does nothing if recycling is not enabled for the region.
* @param region: the region.
* @param block: pointer to memory from region_alloc call.
* @param size: number of bytes, same as passed to region_alloc call.
*/ */
void region_recycle(region_type *region, void *block, size_t size); void region_recycle(region_type *region, void *block, size_t size);
/* /**
* Print some REGION statistics to OUT. * Print some REGION statistics to OUT.
*/ */
void region_dump_stats(region_type *region, FILE *out); void region_dump_stats(region_type *region, FILE *out);
/* get size of recyclebin */ /** get size of recyclebin */
size_t region_get_recycle_size(region_type* region); size_t region_get_recycle_size(region_type* region);
/* Debug print REGION statistics to LOG. */ /** Debug print REGION statistics to LOG. */
void region_log_stats(region_type *region); void region_log_stats(region_type *region);
#endif /* _REGION_ALLOCATOR_H_ */ #endif /* _REGION_ALLOCATOR_H_ */