162ac0c33Sjakob /* 262ac0c33Sjakob * region-allocator.h -- region based memory allocator. 362ac0c33Sjakob * 4d3fecca9Ssthen * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 562ac0c33Sjakob * 662ac0c33Sjakob * See LICENSE for the license. 762ac0c33Sjakob * 862ac0c33Sjakob */ 962ac0c33Sjakob 10*3efee2e1Sflorian #ifndef REGION_ALLOCATOR_H 11*3efee2e1Sflorian #define REGION_ALLOCATOR_H 1262ac0c33Sjakob 1362ac0c33Sjakob #include <stdio.h> 1462ac0c33Sjakob 1562ac0c33Sjakob typedef struct region region_type; 1662ac0c33Sjakob 1762ac0c33Sjakob #define DEFAULT_CHUNK_SIZE 4096 1862ac0c33Sjakob #define DEFAULT_LARGE_OBJECT_SIZE (DEFAULT_CHUNK_SIZE / 8) 1962ac0c33Sjakob #define DEFAULT_INITIAL_CLEANUP_SIZE 16 2062ac0c33Sjakob 21a8b34139Sjakob 22a8b34139Sjakob /* 23a8b34139Sjakob * mmap allocator constants 24a8b34139Sjakob * 25a8b34139Sjakob */ 26a8b34139Sjakob #ifdef USE_MMAP_ALLOC 27a8b34139Sjakob 28a8b34139Sjakob /* header starts with size_t containing allocated size info and has at least 16 bytes to align the returned memory */ 29a8b34139Sjakob #define MMAP_ALLOC_HEADER_SIZE (sizeof(size_t) >= 16 ? (sizeof(size_t)) : 16) 30a8b34139Sjakob 31a8b34139Sjakob /* mmap allocator uses chunks of 32 4kB pages */ 32a8b34139Sjakob #define MMAP_ALLOC_CHUNK_SIZE ((32 * 4096) - MMAP_ALLOC_HEADER_SIZE) 33a8b34139Sjakob #define MMAP_ALLOC_LARGE_OBJECT_SIZE (MMAP_ALLOC_CHUNK_SIZE / 8) 34a8b34139Sjakob #define MMAP_ALLOC_INITIAL_CLEANUP_SIZE 16 35a8b34139Sjakob 36a8b34139Sjakob #endif /* USE_MMAP_ALLOC */ 37a8b34139Sjakob 3862ac0c33Sjakob /* 3962ac0c33Sjakob * Create a new region. 4062ac0c33Sjakob */ 4162ac0c33Sjakob region_type *region_create(void *(*allocator)(size_t), 4262ac0c33Sjakob void (*deallocator)(void *)); 4362ac0c33Sjakob 4462ac0c33Sjakob 4562ac0c33Sjakob /* 4662ac0c33Sjakob * Create a new region, with chunk size and large object size. 4762ac0c33Sjakob * Note that large_object_size must be <= chunk_size. 4862ac0c33Sjakob * Anything larger than the large object size is individually alloced. 4962ac0c33Sjakob * large_object_size = chunk_size/8 is reasonable; 502fd875a4Ssthen * initial_cleanup_size is the number of preallocated ptrs for cleanups. 5162ac0c33Sjakob * The cleanups are in a growing array, and it must start larger than zero. 5262ac0c33Sjakob * If recycle is true, environmentally friendly memory recycling is be enabled. 5362ac0c33Sjakob */ 5462ac0c33Sjakob region_type *region_create_custom(void *(*allocator)(size_t), 5562ac0c33Sjakob void (*deallocator)(void *), 5662ac0c33Sjakob size_t chunk_size, 5762ac0c33Sjakob size_t large_object_size, 5862ac0c33Sjakob size_t initial_cleanup_size, 5962ac0c33Sjakob int recycle); 6062ac0c33Sjakob 6162ac0c33Sjakob 6262ac0c33Sjakob /* 6362ac0c33Sjakob * Destroy REGION. All memory associated with REGION is freed as if 6462ac0c33Sjakob * region_free_all was called. 6562ac0c33Sjakob */ 6662ac0c33Sjakob void region_destroy(region_type *region); 6762ac0c33Sjakob 6862ac0c33Sjakob 6962ac0c33Sjakob /* 7062ac0c33Sjakob * Add a cleanup to REGION. ACTION will be called with DATA as 7162ac0c33Sjakob * parameter when the region is freed or destroyed. 7262ac0c33Sjakob * 7362ac0c33Sjakob * Returns 0 on failure. 7462ac0c33Sjakob */ 7562ac0c33Sjakob size_t region_add_cleanup(region_type *region, 7662ac0c33Sjakob void (*action)(void *), 7762ac0c33Sjakob void *data); 7862ac0c33Sjakob 79217deabeSjakob /* 80217deabeSjakob * Remove cleanup, both action and data must match exactly. 81217deabeSjakob */ 82217deabeSjakob void region_remove_cleanup(region_type *region, 83217deabeSjakob void (*action)(void *), void *data); 8462ac0c33Sjakob 8562ac0c33Sjakob /* 8662ac0c33Sjakob * Allocate SIZE bytes of memory inside REGION. The memory is 8762ac0c33Sjakob * deallocated when region_free_all is called for this region. 8862ac0c33Sjakob */ 8962ac0c33Sjakob void *region_alloc(region_type *region, size_t size); 9062ac0c33Sjakob 91c939baa4Ssthen /** Allocate array with integer overflow checks, in region */ 92c939baa4Ssthen void *region_alloc_array(region_type *region, size_t num, size_t size); 9362ac0c33Sjakob 9462ac0c33Sjakob /* 9562ac0c33Sjakob * Allocate SIZE bytes of memory inside REGION and copy INIT into it. 9662ac0c33Sjakob * The memory is deallocated when region_free_all is called for this 9762ac0c33Sjakob * region. 9862ac0c33Sjakob */ 9962ac0c33Sjakob void *region_alloc_init(region_type *region, const void *init, size_t size); 10062ac0c33Sjakob 101c939baa4Ssthen /** 102c939baa4Ssthen * Allocate array (with integer overflow check on sizes), and init with 103c939baa4Ssthen * the given array copied into it. Allocated in the region 104c939baa4Ssthen */ 105c939baa4Ssthen void *region_alloc_array_init(region_type *region, const void *init, 106c939baa4Ssthen size_t num, size_t size); 10762ac0c33Sjakob 10862ac0c33Sjakob /* 10962ac0c33Sjakob * Allocate SIZE bytes of memory inside REGION that are initialized to 11062ac0c33Sjakob * 0. The memory is deallocated when region_free_all is called for 11162ac0c33Sjakob * this region. 11262ac0c33Sjakob */ 11362ac0c33Sjakob void *region_alloc_zero(region_type *region, size_t size); 11462ac0c33Sjakob 115c939baa4Ssthen /** 116c939baa4Ssthen * Allocate array (with integer overflow check on sizes), and zero it. 117c939baa4Ssthen * Allocated in the region. 118c939baa4Ssthen */ 119c939baa4Ssthen void *region_alloc_array_zero(region_type *region, size_t num, size_t size); 12062ac0c33Sjakob 12162ac0c33Sjakob /* 12262ac0c33Sjakob * Run the cleanup actions and free all memory associated with REGION. 12362ac0c33Sjakob */ 12462ac0c33Sjakob void region_free_all(region_type *region); 12562ac0c33Sjakob 12662ac0c33Sjakob 12762ac0c33Sjakob /* 12862ac0c33Sjakob * Duplicate STRING and allocate the result in REGION. 12962ac0c33Sjakob */ 13062ac0c33Sjakob char *region_strdup(region_type *region, const char *string); 13162ac0c33Sjakob 13262ac0c33Sjakob /* 13362ac0c33Sjakob * Recycle an allocated memory block. Pass size used to alloc it. 13462ac0c33Sjakob * Does nothing if recycling is not enabled for the region. 13562ac0c33Sjakob */ 13662ac0c33Sjakob void region_recycle(region_type *region, void *block, size_t size); 13762ac0c33Sjakob 13862ac0c33Sjakob /* 13962ac0c33Sjakob * Print some REGION statistics to OUT. 14062ac0c33Sjakob */ 14162ac0c33Sjakob void region_dump_stats(region_type *region, FILE *out); 14262ac0c33Sjakob 14362ac0c33Sjakob /* get size of recyclebin */ 14462ac0c33Sjakob size_t region_get_recycle_size(region_type* region); 145d3fecca9Ssthen /* get size of region memory in use */ 146d3fecca9Ssthen size_t region_get_mem(region_type* region); 147d3fecca9Ssthen /* get size of region memory unused */ 148d3fecca9Ssthen size_t region_get_mem_unused(region_type* region); 14962ac0c33Sjakob 15062ac0c33Sjakob /* Debug print REGION statistics to LOG. */ 15162ac0c33Sjakob void region_log_stats(region_type *region); 15262ac0c33Sjakob 153*3efee2e1Sflorian #endif /* REGION_ALLOCATOR_H */ 154