xref: /openbsd-src/usr.sbin/nsd/region-allocator.h (revision 3efee2e132f9af6db74577d714f3304be2b3af74)
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