1 /* $NetBSD: pool.h,v 1.1.1.1 2008/12/22 00:18:35 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of the device-mapper userspace tools. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #ifndef _DM_POOL_H 19 #define _DM_POOL_H 20 21 #include <string.h> 22 #include <stdlib.h> 23 24 /* 25 * The pool allocator is useful when you are going to allocate 26 * lots of memory, use the memory for a bit, and then free the 27 * memory in one go. A surprising amount of code has this usage 28 * profile. 29 * 30 * You should think of the pool as an infinite, contiguous chunk 31 * of memory. The front of this chunk of memory contains 32 * allocated objects, the second half is free. pool_alloc grabs 33 * the next 'size' bytes from the free half, in effect moving it 34 * into the allocated half. This operation is very efficient. 35 * 36 * pool_free frees the allocated object *and* all objects 37 * allocated after it. It is important to note this semantic 38 * difference from malloc/free. This is also extremely 39 * efficient, since a single pool_free can dispose of a large 40 * complex object. 41 * 42 * pool_destroy frees all allocated memory. 43 * 44 * eg, If you are building a binary tree in your program, and 45 * know that you are only ever going to insert into your tree, 46 * and not delete (eg, maintaining a symbol table for a 47 * compiler). You can create yourself a pool, allocate the nodes 48 * from it, and when the tree becomes redundant call pool_destroy 49 * (no nasty iterating through the tree to free nodes). 50 * 51 * eg, On the other hand if you wanted to repeatedly insert and 52 * remove objects into the tree, you would be better off 53 * allocating the nodes from a free list; you cannot free a 54 * single arbitrary node with pool. 55 */ 56 57 struct pool; 58 59 /* constructor and destructor */ 60 struct pool *pool_create(const char *name, size_t chunk_hint); 61 void pool_destroy(struct pool *p); 62 63 /* simple allocation/free routines */ 64 void *pool_alloc(struct pool *p, size_t s); 65 void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment); 66 void pool_empty(struct pool *p); 67 void pool_free(struct pool *p, void *ptr); 68 69 /* 70 * Object building routines: 71 * 72 * These allow you to 'grow' an object, useful for 73 * building strings, or filling in dynamic 74 * arrays. 75 * 76 * It's probably best explained with an example: 77 * 78 * char *build_string(struct pool *mem) 79 * { 80 * int i; 81 * char buffer[16]; 82 * 83 * if (!pool_begin_object(mem, 128)) 84 * return NULL; 85 * 86 * for (i = 0; i < 50; i++) { 87 * snprintf(buffer, sizeof(buffer), "%d, ", i); 88 * if (!pool_grow_object(mem, buffer, strlen(buffer))) 89 * goto bad; 90 * } 91 * 92 * // add null 93 * if (!pool_grow_object(mem, "\0", 1)) 94 * goto bad; 95 * 96 * return pool_end_object(mem); 97 * 98 * bad: 99 * 100 * pool_abandon_object(mem); 101 * return NULL; 102 *} 103 * 104 * So start an object by calling pool_begin_object 105 * with a guess at the final object size - if in 106 * doubt make the guess too small. 107 * 108 * Then append chunks of data to your object with 109 * pool_grow_object. Finally get your object with 110 * a call to pool_end_object. 111 * 112 */ 113 int pool_begin_object(struct pool *p, size_t hint); 114 int pool_grow_object(struct pool *p, const void *extra, size_t delta); 115 void *pool_end_object(struct pool *p); 116 void pool_abandon_object(struct pool *p); 117 118 /* utilities */ 119 char *pool_strdup(struct pool *p, const char *str); 120 char *pool_strndup(struct pool *p, const char *str, size_t n); 121 void *pool_zalloc(struct pool *p, size_t s); 122 123 #endif 124