diff -urN nsd-3.2.4/dbaccess.c nsd-3.2.4-new/dbaccess.c --- nsd-3.2.4/dbaccess.c 2009-01-08 14:44:43.000000000 +0100 +++ nsd-3.2.4-new/dbaccess.c 2010-03-05 16:47:06.000000000 +0100 @@ -282,8 +282,13 @@ DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rbnode_t) = %lu\n", (unsigned long) sizeof(rbnode_t))); +#ifdef MMAP_ALLOC + db_region = region_create_custom(mmap_alloc, mmap_free, MMAP_ALLOC_CHUNK_SIZE, + MMAP_ALLOC_LARGE_OBJECT_SIZE, MMAP_ALLOC_INITIAL_CLEANUP_SIZE, 1); +#else /* !MMAP_ALLOC */ db_region = region_create_custom(xalloc, free, DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE, DEFAULT_INITIAL_CLEANUP_SIZE, 1); +#endif /* !MMAP_ALLOC */ db = (namedb_type *) region_alloc(db_region, sizeof(struct namedb)); db->region = db_region; db->domains = domain_table_create(db->region); diff -urN nsd-3.2.4/dbcreate.c nsd-3.2.4-new/dbcreate.c --- nsd-3.2.4/dbcreate.c 2009-01-08 16:25:37.000000000 +0100 +++ nsd-3.2.4-new/dbcreate.c 2010-03-05 16:48:42.000000000 +0100 @@ -25,9 +25,17 @@ namedb_new (const char *filename) { namedb_type *db; - region_type *region = region_create_custom(xalloc, free, + region_type *region; + +#ifdef MMAP_ALLOC + region = region_create_custom(mmap_alloc, mmap_free, + MMAP_ALLOC_CHUNK_SIZE, MMAP_ALLOC_LARGE_OBJECT_SIZE, + MMAP_ALLOC_INITIAL_CLEANUP_SIZE, 1); +#else /* !MMAP_ALLOC */ + region = region_create_custom(xalloc, free, DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE, DEFAULT_INITIAL_CLEANUP_SIZE, 1); +#endif /* !MMAP_ALLOC */ /* Make a new structure... */ db = (namedb_type *) region_alloc(region, sizeof(namedb_type)); diff -urN nsd-3.2.4/region-allocator.h nsd-3.2.4-new/region-allocator.h --- nsd-3.2.4/region-allocator.h 2006-09-29 11:06:11.000000000 +0200 +++ nsd-3.2.4-new/region-allocator.h 2010-03-05 16:49:09.000000000 +0100 @@ -18,6 +18,24 @@ #define DEFAULT_LARGE_OBJECT_SIZE (DEFAULT_CHUNK_SIZE / 8) #define DEFAULT_INITIAL_CLEANUP_SIZE 16 + +/* + * mmap allocator constants + * + */ + +/* #### FIXME: make it configurable via configure script? */ +#define MMAP_ALLOC 1 + +/* header starts with size_t containing allocated size info and has at least 16 bytes to align the returned memory */ +#define MMAP_ALLOC_HEADER_SIZE (sizeof(size_t) >= 16 ? (sizeof(size_t)) : 16) + +/* mmap allocator uses chunks of 32 4kB pages */ +#define MMAP_ALLOC_CHUNK_SIZE ((32 * 4096) - MMAP_ALLOC_HEADER_SIZE) +#define MMAP_ALLOC_LARGE_OBJECT_SIZE (MMAP_ALLOC_CHUNK_SIZE / 8) +#define MMAP_ALLOC_INITIAL_CLEANUP_SIZE 16 + + /* * Create a new region. */ diff -urN nsd-3.2.4/util.c nsd-3.2.4-new/util.c --- nsd-3.2.4/util.c 2009-05-19 11:30:52.000000000 +0200 +++ nsd-3.2.4-new/util.c 2010-03-05 16:35:04.000000000 +0100 @@ -27,6 +27,10 @@ #include "namedb.h" #include "rdata.h" +#ifdef MMAP_ALLOC +#include +#endif /* MMAP_ALLOC */ + #ifndef NDEBUG unsigned nsd_debug_facilities = 0xffff; int nsd_debug_level = 0; @@ -242,6 +246,44 @@ return ptr; } +#ifdef MMAP_ALLOC + +void * +mmap_alloc(size_t size) +{ + void *base; + + size += MMAP_ALLOC_HEADER_SIZE; + base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (base == MAP_FAILED) { + log_msg(LOG_ERR, "mmap failed: %s", strerror(errno)); + exit(1); + } + + *((size_t*) base) = size; + return (void*)((uintptr_t)base + MMAP_ALLOC_HEADER_SIZE); +} + + +void +mmap_free(void *ptr) +{ + void *base; + size_t size; + + if (!ptr) return; + + base = (void*)((uintptr_t)ptr - MMAP_ALLOC_HEADER_SIZE); + size = *((size_t*) base); + + if (munmap(base, size) == -1) { + log_msg(LOG_ERR, "munmap failed: %s", strerror(errno)); + exit(1); + } +} + +#endif /* MMAP_ALLOC */ + int write_data(FILE *file, const void *data, size_t size) { diff -urN nsd-3.2.4/util.h nsd-3.2.4-new/util.h --- nsd-3.2.4/util.h 2009-05-19 11:30:52.000000000 +0200 +++ nsd-3.2.4-new/util.h 2010-03-05 17:02:29.000000000 +0100 @@ -138,6 +138,16 @@ void *xrealloc(void *ptr, size_t size); /* + * Mmap allocator routines. + * + */ + +#ifdef MMAP_ALLOC +void *mmap_alloc(size_t size); +void mmap_free(void *ptr); +#endif /* MMAP_ALLOC */ + +/* * Write SIZE bytes of DATA to FILE. Report an error on failure. * * Returns 0 on failure, 1 on success.