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