make download_ldns refreshes the tarball with ldns svn trunk.
- ldns-src.tar.gz is used if no ldns is found on the system, and
statically linked into unbound.
+ - start of regional allocator code.
17 October 2007: Wouter
- fixup another cycle detect and ns-addr timeout resolution bug.
util/configparser.c \
util/configparser.h \
util/configlexer.c \
- util/locks.h
+ util/locks.h \
+ ./ldns-src
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
--- /dev/null
+/*
+ * regional.c -- region based memory allocator.
+ *
+ * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Region allocator. Allocates small portions of of larger chunks.
+ */
+
+#include "config.h"
+#include "util/log.h"
+#include "util/regional.h"
+
+#ifdef ALIGNMENT
+# undef ALIGNMENT
+#endif
+/** increase size until it fits alignment of s bytes */
+#define ALIGN_UP(x, s) (((x) + s - 1) & (~(s - 1)))
+/** what size to align on; make sure a char* fits in it. */
+#define ALIGNMENT (sizeof(uint64_t))
+
+/** Default reasonable size for chunks */
+#define REGIONAL_CHUNK_SIZE 8192
+/** Default size for large objects - allocated outside of chunks. */
+#define REGIONAL_LARGE_OBJECT_SIZE 2048
+
+struct regional*
+regional_create()
+{
+ void *block = malloc(REGIONAL_CHUNK_SIZE);
+ if(!block) return NULL;
+ return regional_create_custom(block, REGIONAL_CHUNK_SIZE);
+}
+
+/** init regional struct with first block */
+static void
+regional_init(struct regional* r)
+{
+ r->next = NULL;
+ r->size = r->first_size;
+ r->allocated = ALIGN_UP(sizeof(struct regional), ALIGNMENT);
+ r->data = (char*)r;
+ r->total_large = 0;
+ r->large_list = NULL;
+}
+
+struct regional*
+regional_create_custom(void* block, size_t size)
+{
+ struct regional* r = (struct regional*)block;
+ log_assert(sizeof(struct regional) <= size);
+ r->first_size = size;
+ regional_init(r);
+ return r;
+}
+
+void
+regional_free_all(struct regional *r)
+{
+ char* p = r->next, *np;
+ while(p) {
+ np = *(char**)p;
+ free(p);
+ p = np;
+ }
+ p = r->large_list;
+ while(p) {
+ np = *(char**)p;
+ free(p);
+ p = np;
+ }
+ regional_init(r);
+}
+
+void
+regional_destroy(struct regional *r)
+{
+ regional_free_all(r);
+ free(r);
+}
+
+void *
+regional_alloc(struct regional *r, size_t size)
+{
+ size_t a = ALIGN_UP(size, ALIGNMENT);
+ void *s;
+ /* large objects */
+ if(a > REGIONAL_LARGE_OBJECT_SIZE) {
+ s = malloc(ALIGNMENT + size);
+ if(!s) return NULL;
+ r->total_large += ALIGNMENT+size;
+ *(char**)s = r->large_list;
+ r->large_list = (char*)s;
+ return s+ALIGNMENT;
+ }
+ /* create a new chunk */
+ if(r->allocated + a > r->size) {
+ s = malloc(REGIONAL_CHUNK_SIZE);
+ if(!s) return NULL;
+ *(char**)s = r->data;
+ r->data = s;
+ r->allocated = ALIGNMENT;
+ r->size = REGIONAL_CHUNK_SIZE;
+ }
+ /* put in this chunk */
+ s = r->data + r->allocated;
+ r->allocated += a;
+ return s;
+}
+
+void *
+regional_alloc_init(struct regional* r, const void *init, size_t size)
+{
+ void *s = regional_alloc(r, size);
+ if(!s)
+ return NULL;
+ memcpy(s, init, size);
+ return s;
+}
+
+void *
+regional_alloc_zero(struct regional *r, size_t size)
+{
+ void *s = regional_alloc(r, size);
+ if(!s)
+ return NULL;
+ memset(s, 0, size);
+ return s;
+}
+
+char *
+regional_strdup(struct regional *r, const char *string)
+{
+ return regional_alloc_init(r, string, strlen(string)+1);
+}
+
+/**
+ * reasonably slow, but stats and get_mem are not supposed to be fast
+ * count the number of chunks in use
+ */
+static size_t
+count_chunks(struct regional* r)
+{
+ size_t c = 1;
+ char* p = r->next;
+ while(p) {
+ c++;
+ p = *(char**)p;
+ }
+ return c;
+}
+
+/**
+ * also reasonably slow, counts the number of large objects
+ */
+static size_t
+count_large(struct regional* r)
+{
+ size_t c = 0;
+ char* p = r->large_list;
+ while(p) {
+ c++;
+ p = *(char**)p;
+ }
+ return c;
+}
+
+void
+regional_log_stats(struct regional *r)
+{
+ log_info("regional %u chunks, %u large",
+ (unsigned)count_chunks(r), (unsigned)count_large(r));
+}
+
+size_t
+regional_get_mem(struct regional* r)
+{
+ return r->first_size + (count_chunks(r)-1)*REGIONAL_CHUNK_SIZE
+ + r->total_large;
+}
--- /dev/null
+/*
+ * regional.h -- region based memory allocator.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Region allocator. Allocates small portions of of larger chunks.
+ *
+ * Different from (nsd) region-allocator.h
+ * o does not have recycle bin
+ * o does not collect stats
+ * o does not keep cleanup list
+ * o does not have function pointers to setup
+ * o allocs the regional struct inside the first block.
+ * o can take a block to create regional from.
+ */
+
+#ifndef UTIL_REGIONAL_H_
+#define UTIL_REGIONAL_H_
+
+/**
+ * the regional* is the first block*.
+ * every block has a ptr to the next in first bytes.
+ * and so does the regional struct, which is the first block.
+ */
+struct regional
+{
+ /** next chunk. NULL if first chunk is the only chunk. */
+ char* next;
+ /** number of bytes allocated in the current chunk. */
+ size_t allocated;
+ /** initial chunk size */
+ size_t first_size;
+ /** current chunk size */
+ size_t size;
+ /** total large size */
+ size_t total_large;
+ /**
+ * current chunk
+ * can be cast to char** to obtain next chunk pointer.
+ */
+ char *data;
+ /** first large object, cast to char** to obtain next ptr */
+ char* large_list;
+};
+
+/**
+ * Create a new regional.
+ */
+struct regional* regional_create();
+
+/**
+ * Create a new region, with custom settings.
+ * @param block: initial data block
+ * The regional returned is allocated in the block (start of it).
+ * @param size: length of block.
+ */
+struct regional* regional_create_custom(void* block, size_t size);
+
+/**
+ * Free all memory associated with REGION. Only keeps the first block with
+ * the regional inside it.
+ * @param r: the region.
+ */
+void regional_free_all(struct regional *r);
+
+/**
+ * Destroy regional. All memory associated with regional is freed as if
+ * regional_free_all was called, as well as destroying the regional struct.
+ * @param r: to delete.
+ */
+void regional_destroy(struct regional *r);
+
+/**
+ * Allocate SIZE bytes of memory inside REGION. The memory is
+ * deallocated when region_free_all is called for this region.
+ * @param r: the region.
+ * @param size: number of bytes.
+ * @return: pointer to memory allocated.
+ */
+void *regional_alloc(struct regional *r, size_t size);
+
+/**
+ * Allocate SIZE bytes of memory inside REGION and copy INIT into it.
+ * The memory is deallocated when region_free_all is called for this
+ * region.
+ * @param r: the region.
+ * @param init: to copy.
+ * @param size: number of bytes.
+ * @return: pointer to memory allocated.
+ */
+void *regional_alloc_init(struct regional* r, const void *init, size_t size);
+
+/**
+ * Allocate SIZE bytes of memory inside REGION that are initialized to
+ * 0. The memory is deallocated when region_free_all is called for
+ * this region.
+ * @param r: the region.
+ * @param size: number of bytes.
+ * @return: pointer to memory allocated.
+ */
+void *regional_alloc_zero(struct regional *r, size_t size);
+
+/**
+ * Duplicate STRING and allocate the result in REGION.
+ * @param r: the region.
+ * @param string: null terminated string.
+ */
+char *regional_strdup(struct regional *r, const char *string);
+
+/** Debug print REGION statistics to LOG */
+void regional_log_stats(struct regional *r);
+
+/** get total memory size in use by region */
+size_t regional_get_mem(struct regional* r);
+
+#endif /* UTIL_REGIONAL_H_ */