xref: /dragonfly/contrib/lvm2/dist/libdm/mm/pool.h (revision 25a2db75)
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