Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

mempool.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com>
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <time.h>
00028 #include <string.h>
00029 #ifdef HAVE_STRINGS_H
00030 #include <strings.h>
00031 #endif
00032 
00033 
00034 /*
00035  * This is used to allocate a list of fixed size objects in a static
00036  * memory pool aside from the concerns of alloc/free
00037  */
00038 
00039 /* $Id$ */
00040 #include "mempool.h"
00041 
00042 /* Function: int mempool_init(MemPool *mempool,
00043  *                            PoolCount num_objects, size_t obj_size)
00044  * 
00045  * Purpose: initialize a mempool object and allocate memory for it
00046  * Args: mempool - pointer to a MemPool struct
00047  *       num_objects - number of items in this pool
00048  *       obj_size    - size of the items
00049  * 
00050  * Returns: 0 on success, 1 on failure
00051  */ 
00052 
00053 int mempool_init(MemPool *mempool, PoolCount num_objects, size_t obj_size)
00054 {
00055     PoolCount i;
00056     
00057     if(mempool == NULL)
00058         return 1;
00059 
00060     if(num_objects < 1)
00061         return 1;
00062 
00063     if(obj_size < 1)
00064         return 1;
00065 
00066     mempool->obj_size = obj_size;
00067     
00068     /* this is the basis pool that represents all the *data pointers
00069        in the list */
00070     mempool->datapool = calloc(num_objects, obj_size);
00071     
00072     
00073     if(mempool->datapool == NULL)
00074     {
00075         return 1;
00076     }
00077 
00078     mempool->listpool = calloc(num_objects, sizeof(SDListItem));
00079 
00080     if(mempool->listpool == NULL)
00081     {
00082         /* well, that sucked, lets clean up */
00083         fprintf(stderr, "mempool: listpool is null\n");
00084         free(mempool->datapool);
00085         return 1;
00086     }
00087 
00088     mempool->bucketpool = calloc(num_objects, sizeof(MemBucket));
00089 
00090     if(mempool->bucketpool == NULL)
00091     {
00092         fprintf(stderr, "mempool: bucketpool is null\n");
00093         free(mempool->datapool);
00094         free(mempool->listpool);
00095         return 1;
00096     }
00097 
00098     /* sets up the 2 memory lists */
00099     if(sf_sdlist_init(&mempool->used_list, NULL))
00100     {
00101         fprintf(stderr, "mempool: used_list failed\n");
00102         free(mempool->datapool);
00103         free(mempool->listpool);
00104         free(mempool->bucketpool);
00105         return 1;
00106     }
00107 
00108     if(sf_sdlist_init(&mempool->free_list, NULL))
00109     {
00110         fprintf(stderr, "mempool: free_list failed\n");
00111         free(mempool->datapool);
00112         free(mempool->listpool);
00113         free(mempool->bucketpool);
00114         return 1;
00115     }
00116 
00117 
00118     for(i=0; i<num_objects; i++)
00119     {
00120         SDListItem *itemp;
00121         MemBucket *bp;
00122 
00123         bp = &mempool->bucketpool[i];
00124         itemp = &mempool->listpool[i];
00125         
00126         /* each bucket knows where it resides in the list */
00127         bp->key = itemp;
00128 
00129 #ifdef TEST_MEMPOOL        
00130         printf("listpool: %p itemp: %p diff: %u\n",
00131                mempool->listpool, itemp,
00132                (((char *) itemp) -
00133                 ((char *) mempool->listpool)));
00134 #endif /* TEST_MEMPOOL */
00135                
00136         bp->data = ((char *) mempool->datapool) + (i * mempool->obj_size);
00137         
00138 #ifdef TEST_MEMPOOL        
00139         printf("datapool: %p bp.data: %p diff: %u\n",
00140                mempool->datapool,
00141                mempool->datapool + (i * mempool->obj_size),
00142                (((char *) bp->data) -
00143                 ((char *) mempool->datapool)));
00144 #endif /* TEST_MEMPOOL */
00145         
00146 
00147         if(sf_sdlist_append(&mempool->free_list,                           
00148                             &mempool->bucketpool[i],
00149                             &mempool->listpool[i]))
00150         {
00151             fprintf(stderr, "mempool: free_list_append failed\n");
00152             free(mempool->datapool);
00153             free(mempool->listpool);
00154             free(mempool->bucketpool);
00155             return 1;
00156         }
00157 
00158         mempool->free++;
00159     }
00160 
00161     mempool->used = 0;
00162     mempool->total = num_objects;
00163     
00164     return 0;
00165 }
00166 
00167 /* Function: int mempool_destroy(MemPool *mempool) 
00168  * 
00169  * Purpose: destroy a set of mempool objects
00170  * Args: mempool - pointer to a MemPool struct
00171  * 
00172  * Returns: 0 on success, 1 on failure
00173  */ 
00174 int mempool_destroy(MemPool *mempool)
00175 {
00176     if(mempool == NULL)
00177         return 1;
00178 
00179     free(mempool->listpool);
00180 
00181     /* TBD - callback to free up every stray pointer */
00182     bzero(mempool, sizeof(MemPool));
00183     
00184     return 0;    
00185 }
00186 
00187 
00188 /* Function: MemBucket *mempool_alloc(MemPool *mempool);
00189  * 
00190  * Purpose: allocate a new object from the mempool
00191  * Args: mempool - pointer to a MemPool struct
00192  * 
00193  * Returns: a pointer to the mempool object on success, NULL on failure
00194  */ 
00195 MemBucket *mempool_alloc(MemPool *mempool)
00196 {
00197     SDListItem *li = NULL;
00198     MemBucket *b;
00199     
00200     if(mempool == NULL)
00201     {
00202         return NULL;
00203     }
00204 
00205     if(mempool->free <= 0)
00206     {
00207         return NULL;
00208     }
00209 
00210     /* get one item off the free_list,
00211        put one item on the usedlist
00212      */
00213 
00214     li = mempool->free_list.head;
00215 
00216     mempool->free--;
00217     if((li == NULL) || sf_sdlist_remove(&mempool->free_list, li))
00218     {
00219         printf("Failure on sf_sdlist_remove\n");
00220         return NULL;
00221     }
00222         
00223     
00224     mempool->used++;
00225 
00226     if(sf_sdlist_append(&mempool->used_list, li->data, li))
00227     {
00228         printf("Failure on sf_sdlist_append\n");
00229         return NULL;
00230     }
00231 
00232     /* TBD -- make configurable */
00233     b = li->data;
00234     bzero(b->data, mempool->obj_size);
00235     
00236     return b;
00237 }
00238 
00239 
00240 void mempool_free(MemPool *mempool, MemBucket *obj)
00241 {       
00242     if(sf_sdlist_remove(&mempool->used_list, obj->key))
00243     {
00244         printf("failure on remove from used_list");
00245         return;
00246     }
00247     
00248     mempool->used--;
00249 
00250     /* put the address of the membucket back in the list */
00251     if(sf_sdlist_append(&mempool->free_list, obj, obj->key))
00252     {
00253         printf("failure on add to free_list");
00254         return;
00255     }
00256 
00257     mempool->free++;    
00258     return;
00259 }
00260 
00261 #ifdef TEST_MEMPOOL
00262 
00263 #define SIZE 36
00264 int main(void)
00265 {
00266     MemPool test;
00267     MemBucket *bucks[SIZE];
00268     MemBucket *bucket = NULL;
00269     int i;
00270     long long a = 1;
00271 
00272     //char *stuffs[4] = { "eenie", "meenie", "minie", "moe" };
00273     char *stuffs2[36] =
00274         {  "1eenie", "2meenie", "3minie", " 4moe",
00275            "1xxxxx", "2yyyyyy", "3zzzzz", " 4qqqq",
00276            "1eenie", "2meenie", "3minie", " 4moe",
00277            "1eenie", "2meenie", "3minie", " 4moe",
00278            "1eenie", "2meenie", "3minie", " 4moe",
00279            "1eenie", "2meenie", "3minie", " 4moe",
00280            "1eenie", "2meenie", "3minie", " 4moe",
00281            "1eenie", "2meenie", "3minie", " 4moe",
00282            "1eenie", "2meenie", "3minie", " 4moe"
00283         };
00284     
00285     if(mempool_init(&test, 36, 256))
00286     {
00287         printf("error in mempool initialization\n");
00288     }
00289 
00290     for(i = 0; i < 36; i++)
00291     {
00292         if((bucks[i] = mempool_alloc(&test)) == NULL)
00293         {
00294             printf("error in mempool_alloc: i=%d\n", i);
00295             continue;
00296         }
00297 
00298         bucket = bucks[i];
00299 
00300         bucket->data = strncpy(bucket->data, stuffs2[i], 256);
00301         printf("bucket->key: %p\n", bucket->key);
00302         printf("bucket->data: %s\n", (char *) bucket->data);
00303     }
00304 
00305     for(i = 0; i < 2; i++)
00306     {
00307         mempool_free(&test, bucks[i]);
00308         bucks[i] = NULL;
00309     }
00310     
00311     for(i = 0; i < 14; i++)
00312     {
00313         if((bucks[i] = mempool_alloc(&test)) == NULL)
00314         {
00315             printf("error in mempool_alloc: i=%d\n", i);
00316             continue;
00317         }
00318 
00319         bucket = bucks[i];
00320 
00321         bucket->data = strncpy(bucket->data, stuffs2[i], 256);
00322         printf("bucket->key: %p\n", bucket->key);
00323         printf("bucket->data: %s\n", (char *) bucket->data);
00324     }
00325 
00326     printf("free: %u, used: %u\n", test.free, test.used);
00327 
00328     
00329     return 0;
00330 }
00331 #endif /* TEST_MEMPOOL */
00332 

Generated on Sun May 14 14:51:14 2006 by  doxygen 1.4.2