"Fossies" - the Fresh Open Source Software Archive

Member "scalpel-2.0/tre-0.7.5-win32/lib/tre-mem.c" (20 Apr 2011, 3858 Bytes) of archive /linux/misc/scalpel-2.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tre-mem.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   tre-mem.c - TRE memory allocator
    3 
    4   Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>
    5 
    6   This library is free software; you can redistribute it and/or
    7   modify it under the terms of the GNU Lesser General Public
    8   License as published by the Free Software Foundation; either
    9   version 2.1 of the License, or (at your option) any later version.
   10 
   11   This library is distributed in the hope that it will be useful,
   12   but WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14   Lesser General Public License for more details.
   15 
   16   You should have received a copy of the GNU Lesser General Public
   17   License along with this library; if not, write to the Free Software
   18   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   19 
   20 */
   21 
   22 /*
   23   This memory allocator is for allocating small memory blocks efficiently
   24   in terms of memory overhead and execution speed.  The allocated blocks
   25   cannot be freed individually, only all at once.  There can be multiple
   26   allocators, though.
   27 */
   28 
   29 #ifdef HAVE_CONFIG_H
   30 #include <config.h>
   31 #endif /* HAVE_CONFIG_H */
   32 #include <stdlib.h>
   33 #include <string.h>
   34 
   35 #include "tre-internal.h"
   36 #include "tre-mem.h"
   37 #include "xmalloc.h"
   38 
   39 
   40 /* Returns a new memory allocator or NULL if out of memory. */
   41 tre_mem_t
   42 tre_mem_new_impl(int provided, void *provided_block)
   43 {
   44   tre_mem_t mem;
   45   if (provided)
   46     {
   47       mem = provided_block;
   48       memset(mem, 0, sizeof(*mem));
   49     }
   50   else
   51     mem = xcalloc(1, sizeof(*mem));
   52   if (mem == NULL)
   53     return NULL;
   54   return mem;
   55 }
   56 
   57 
   58 /* Frees the memory allocator and all memory allocated with it. */
   59 void
   60 tre_mem_destroy(tre_mem_t mem)
   61 {
   62   tre_list_t *tmp, *l = mem->blocks;
   63 
   64   while (l != NULL)
   65     {
   66       xfree(l->data);
   67       tmp = l->next;
   68       xfree(l);
   69       l = tmp;
   70     }
   71   xfree(mem);
   72 }
   73 
   74 
   75 /* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
   76    allocated block or NULL if an underlying malloc() failed. */
   77 void *
   78 tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
   79            int zero, size_t size)
   80 {
   81   void *ptr;
   82 
   83   if (mem->failed)
   84     {
   85       DPRINT(("tre_mem_alloc: oops, called after failure?!\n"));
   86       return NULL;
   87     }
   88 
   89 #ifdef MALLOC_DEBUGGING
   90   if (!provided)
   91     {
   92       ptr = xmalloc(1);
   93       if (ptr == NULL)
   94     {
   95       DPRINT(("tre_mem_alloc: xmalloc forced failure\n"));
   96       mem->failed = 1;
   97       return NULL;
   98     }
   99       xfree(ptr);
  100     }
  101 #endif /* MALLOC_DEBUGGING */
  102 
  103   if (mem->n < size)
  104     {
  105       /* We need more memory than is available in the current block.
  106      Allocate a new block. */
  107       tre_list_t *l;
  108       if (provided)
  109     {
  110       DPRINT(("tre_mem_alloc: using provided block\n"));
  111       if (provided_block == NULL)
  112         {
  113           DPRINT(("tre_mem_alloc: provided block was NULL\n"));
  114           mem->failed = 1;
  115           return NULL;
  116         }
  117       mem->ptr = provided_block;
  118       mem->n = TRE_MEM_BLOCK_SIZE;
  119     }
  120       else
  121     {
  122       int block_size;
  123       if (size * 8 > TRE_MEM_BLOCK_SIZE)
  124         block_size = size * 8;
  125       else
  126         block_size = TRE_MEM_BLOCK_SIZE;
  127       DPRINT(("tre_mem_alloc: allocating new %d byte block\n",
  128           block_size));
  129       l = xmalloc(sizeof(*l));
  130       if (l == NULL)
  131         {
  132           mem->failed = 1;
  133           return NULL;
  134         }
  135       l->data = xmalloc(block_size);
  136       if (l->data == NULL)
  137         {
  138           xfree(l);
  139           mem->failed = 1;
  140           return NULL;
  141         }
  142       l->next = NULL;
  143       if (mem->current != NULL)
  144         mem->current->next = l;
  145       if (mem->blocks == NULL)
  146         mem->blocks = l;
  147       mem->current = l;
  148       mem->ptr = l->data;
  149       mem->n = block_size;
  150     }
  151     }
  152 
  153   /* Make sure the next pointer will be aligned. */
  154   size += ALIGN(mem->ptr + size, long);
  155 
  156   /* Allocate from current block. */
  157   ptr = mem->ptr;
  158   mem->ptr += size;
  159   mem->n -= size;
  160 
  161   /* Set to zero if needed. */
  162   if (zero)
  163     memset(ptr, 0, size);
  164 
  165   return ptr;
  166 }
  167 
  168 /* EOF */