]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Alloc layout.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 2 Mar 2007 15:03:58 +0000 (15:03 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 2 Mar 2007 15:03:58 +0000 (15:03 +0000)
git-svn-id: file:///svn/unbound/trunk@162 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
util/alloc.c [new file with mode: 0644]
util/alloc.h [new file with mode: 0644]

index b9c215125d25ec488b4fcc86d6c8241372f33bb1..74b97d01fc4730df7ee617b72435b51c82170196 100644 (file)
@@ -5,6 +5,7 @@
        - even on systems with nonthreadsafe libevent signal handling,
          unbound will exit if given a signal.
          Reloads will not work, and exit is not graceful.
+       - start of alloc framework layout.
 
 1 March 2007: Wouter
        - Signals, libevent and threads work well, with libevent patch and
diff --git a/util/alloc.c b/util/alloc.c
new file mode 100644 (file)
index 0000000..9e17bd2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * util/alloc.c - memory allocation service. 
+ *
+ * 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
+ *
+ * This file contains memory allocation functions.
+ */
+
+#include "config.h"
+#include "util/alloc.h"
+
diff --git a/util/alloc.h b/util/alloc.h
new file mode 100644 (file)
index 0000000..d1ccd66
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * util/alloc.h - memory allocation service. 
+ *
+ * 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
+ *
+ * This file contains memory allocation functions.
+ *
+ * The reasons for this service are:
+ *     o Avoid locking costs of getting global lock to call malloc().
+ *     o The packed rrset type needs to be kept on special freelists,
+ *       so that they are reused for other packet rrset allocations.
+ *     o This service is not there to improve speed of malloc.
+ *       Some caching is performed to help avoid locking costs.
+ *      o This service does not prevent fragmentation.
+ *       The caching will help somewhat for this.
+ *
+ * Design choices:
+ *     o The global malloc/free is used to handle fragmentation, etc.
+ *       If freelists become very large, it is returned to the system.
+ *     o Only 1k and smaller is cached, bigger uses malloc.
+ *       Because DNS fragments are mostly this size.
+ *     o On startup preallocated memory can be given, so threads can
+ *       avoid contention in the startup phase.
+ */
+
+#ifndef UTIL_ALLOC_H
+#define UTIL_ALLOC_H
+
+#include "util/locks.h"
+
+/** all allocations are in multiples of this size */
+#define ALLOC_ALIGN    32      /* bytes */
+
+/** 
+ * This size and smaller is kept in cached lists by size.
+ * Must be a multiple of ALLOC_ALIGN.
+ */
+#define ALLOC_LARGESIZE        1024    /* bytes */
+
+/** number of bins */
+#define ALLOC_BINS (ALLOC_LARGESIZE / ALLOC_ALIGN)
+
+/** The special type, packed rrset. Not allowed to be used for other memory */
+typedef uint64_t alloc_special_t;
+/** clean the special type. Pass pointer. */
+#define alloc_special_clean(x) memset(x, 0, sizeof(alloc_special_t))
+/** access next pointer. (in available spot). Pass pointer. */
+#define alloc_special_next(x) ((alloc_special_t*)(*(x)))
+
+/** The number of cached items. */
+#define ALLOC_CACHENUM 10      /* memory blocks */
+
+/** Preallocated per thread. This number for every size. */
+#define ALLOC_PREALLOC 32      /* memory blocks */
+
+/** shorthand */
+typedef struct alloc_cache alloc_t;
+/**
+ * Structure that provides caching based on size. Used one per thread.
+ */
+struct alloc_cache {
+       /** global allocator above this one. NULL for none (malloc/free) */
+       struct alloc_super* super;
+       /** singly linked lists per size: [0]32, [1]64, ... [n-1]LARGESIZE */
+       void* bins[ALLOC_BINS];
+       /** the number of items per bin. */
+       size_t nums[ALLOC_BINS];
+       /** singly linked lists of special type. These are free for use. */
+       alloc_special_t* quar;
+       /** number of items in quarantine. */
+       size_t num_quar;
+
+       /* some statistics */
+       /** amount allocated. */
+       size_t bytes_allocated;
+       /** number of items allocated. */
+       size_t items_allocated;
+       /** wasted space due to assigning oversized aligned blocks. */
+       size_t internal_frag;
+       /** amount in cache. */
+       size_t bytes_in_bins;
+       /** number of special type allocated */
+       size_t special_allocated;
+};
+
+/**
+ * Structure with lock to provide global cache of special items and allocs.
+ */
+struct alloc_super {
+       /** lock for single access. */
+       lock_quick_t lock;
+       /** singly linked lists of special type. These are free for use. */
+       alloc_special_t* quar;
+       /** number of items in quarantine. */
+       size_t num_quar;
+};
+
+/**
+ * Init super alloc. (zeroes the struct, inits the lock).
+ * @param super: to init.
+ */
+void asuper_init(struct alloc_super* super);
+
+/**
+ * Init alloc (zeroes the struct).
+ * @param alloc: this parameter is allocated by the caller.
+ * @param super: super to use (init that before with super_init).
+ */
+void alloc_init(alloc_t* alloc, struct alloc_super* super);
+
+/**
+ * Free the alloc. Pushes all the cached items into the super structure.
+ * @param alloc: is almost zeroed on exit (except some stats).
+ */
+void alloc_delete(alloc_t* alloc);
+
+/**
+ * Allocate memory
+ * @param alloc: where to alloc it.
+ * @param size: how much.
+ * @return: memory block. Will not return NULL (instead fatal_exit).
+ */
+void* alloc_alloc(alloc_t* alloc, size_t size);
+
+/**
+ * Free memory.
+ * @param alloc: where to alloc it.
+ * @param mem: block to free.
+ */
+void alloc_free(alloc_t* alloc, void* mem);
+
+/**
+ * Get a new special_t element.
+ * @param alloc: where to alloc it.
+ * @return: memory block. Will not return NULL (instead fatal_exit).
+ */
+alloc_special_t* alloc_special_alloc(alloc_t* alloc);
+
+/**
+ * Return special_t back to pool.
+ * @param alloc: where to alloc it.
+ * @param mem: block to free.
+ */
+void alloc_special_free(alloc_t* alloc, alloc_special_t* mem);
+
+
+#endif /* UTIL_ALLOC_H */