"Fossies" - the Fresh Open Source Software Archive

Member "FunctionCheck-3.2.0/src/fcmanager/fc_memory_manager.c" (26 May 2012, 7683 Bytes) of package /linux/privat/old/FunctionCheck-3.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.

    1 /*
    2  * FunctionCheck profiler
    3  * (C) Copyright 2000-2012 Yannick Perret
    4  * 
    5  *  This program is free software; you can redistribute it and/or
    6  *  modify it under the terms of the FC_NU FC_eneral Public License as
    7  *  published by the Free Software Foundation; either version 2 of the
    8  *  License, or (at your option) any later version.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the FC_NU
   13  *  FC_eneral Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18  */
   19 /** fc_memory.c:  **/
   20 
   21 #include <stdio.h>
   22 #include <stdlib.h>
   23 #include <limits.h>
   24 #include "fc_memory_manager.h"
   25 #include "fc_com.h"
   26 #include "fc_global.h"
   27 #include "fc_hash.h"
   28 #include "fc_tools.h"
   29 
   30 /* indicate the call-stack requested for memory actions */
   31 int fc_memory_stack_size = 4;
   32 
   33 /* set the call-stack size requested */
   34 int fc_memory_set_stack_size(int size)
   35 {
   36     if (size < FC_MAX_CALLSTACK)
   37         fc_memory_stack_size = size;
   38     else
   39         fc_memory_stack_size = FC_MAX_CALLSTACK;
   40 
   41     return (1);
   42 }
   43 
   44 /* create a memory */
   45 FC_Memory *fc_memory_create(int entry_size)
   46 {
   47     FC_Memory *tmp;
   48     int i;
   49 
   50     tmp = malloc(sizeof (FC_Memory));
   51     if (tmp == NULL)
   52     {
   53         fc_message("cannot allocate %d bytes (memory)", sizeof (FC_Memory));
   54         return (NULL);
   55     }
   56 
   57     /* allocate the list of entries */
   58     tmp->max_elements = entry_size;
   59     tmp->nb_elements = 0;
   60     tmp->entry = 0;
   61     tmp->list = malloc(sizeof (FC_MEl) * entry_size);
   62     if (tmp->list == NULL)
   63     {
   64         fc_message("cannot allocate %d bytes (memory/list)", sizeof (FC_MEl) * entry_size);
   65         free(tmp);
   66         return (NULL);
   67     }
   68 
   69     /* initialize the entry list */
   70     for (i = 0; i < entry_size; i++)
   71     {
   72         /* link for free entries */
   73         tmp->list[i].next = i + 1;
   74         tmp->list[i].self = i;
   75         tmp->list[i].set = 0;
   76         tmp->list[i].alloc_stack[0] = NULL;
   77         tmp->list[i].pointer = NULL;
   78     }
   79 
   80     /* create the hash-table for access */
   81     tmp->hash = fc_hash_new();
   82     /* I need to check the NULL result ? */
   83 
   84     return (tmp);
   85 }
   86 
   87 /* destroy a memory */
   88 int fc_memory_delete(FC_Memory *mem)
   89 {
   90     if (mem == NULL)
   91         return 0;
   92 
   93     /* free the list of elements */
   94     if (mem->list != NULL)
   95         free(mem->list);
   96     /* remove the hash-table */
   97     if (mem->hash != NULL)
   98         fc_hash_destroy(mem->hash);
   99     free(mem);
  100 
  101     return 1;
  102 }
  103 
  104 /* add an element in a memory/list (with reallocation if needed) and
  105      return the address of the element for the hash-table */
  106 FC_MEl *fc_memory_list_add(FC_Memory *mem)
  107 {
  108     int i;
  109 
  110     /* with have to reallocate */
  111     if (mem->nb_elements == mem->max_elements)
  112     {
  113         mem->list = realloc(mem->list, sizeof (FC_MEl)*2 * mem->max_elements);
  114         if (mem->list == NULL)
  115         {
  116             /* argl! */
  117             mem->nb_elements = 0;
  118             mem->max_elements = 0;
  119             mem->entry = 0;
  120             fc_message("cannot reallocate entry list for memory managment");
  121             fc_message("memory profile data lost.");
  122             return (NULL);
  123         }
  124 
  125         /* init the available links */
  126         for (i = mem->max_elements; i < mem->max_elements * 2; i++)
  127         {
  128             mem->list[i].next = i + 1;
  129             mem->list[i].self = i;
  130             mem->list[i].set = 0;
  131             mem->list[i].alloc_stack[0] = NULL;
  132             mem->list[i].pointer = NULL;
  133         }
  134 
  135         mem->max_elements *= 2;
  136     }
  137 
  138     /* now the entry is 'entry' */
  139     i = mem->entry;
  140     /* next available */
  141     mem->entry = mem->list[mem->entry].next;
  142     mem->nb_elements++;
  143 
  144     mem->list[i].set = 1;
  145 
  146     return (&(mem->list[i]));
  147 }
  148 
  149 /* remove an element from the memory/list */
  150 int fc_memory_list_remove(FC_Memory *mem, FC_MEl *el)
  151 {
  152     /* still removed */
  153     if (el->pointer == NULL)
  154         return (0);
  155 
  156     /* remove the element */
  157     el->pointer = NULL;
  158     el->set = 0;
  159     el->next = mem->entry; /* next free is the actual entry */
  160     mem->entry = el->self; /* new entry */
  161 
  162     return (1);
  163 }
  164 
  165 /* record a 'malloc' entry */
  166 int fc_memory_add_malloc(void *ctx, void *ptr, unsigned int size, void *where)
  167 {
  168     FC_MEl *el;
  169     FC_Memory *mem;
  170     void *tmp, *b;
  171     int ret, a;
  172 
  173     mem = ((FC_Context*) ctx)->memory;
  174 
  175     /* allocation failed */
  176     if (ptr == NULL)
  177     {
  178         /* nothing to record */
  179         return 1;
  180     }
  181 
  182     /* first check if this pointer is available */
  183     ret = fc_hash_lookup(mem->hash, ptr, &a, &tmp, &b);
  184     if (ret)
  185     {
  186         fc_message("warning: pointer %p is still present as an active block!");
  187         fc_message("         overwriting previous entry.");
  188         el = (FC_MEl*) tmp;
  189     }
  190     else
  191     {
  192         /* prepare a new entry */
  193         el = fc_memory_list_add(mem);
  194         /* add the reference in the hash-table */
  195         fc_hash_insert(mem->hash, ptr, 0, (void*) el, NULL);
  196     }
  197 
  198     /* now set the fields */
  199     el->pointer = ptr;
  200     el->size = size;
  201     el->alloc_place = where;
  202     fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
  203     el->realloc_place = NULL;
  204 
  205     return 1;
  206 }
  207 
  208 /* record a 'memalign' entry */
  209 int fc_memory_add_memalign(void *ctx, void *ptr, unsigned int align, unsigned int size, void *where)
  210 {
  211     /* we treat it as a malloc action (align info is dropped) */
  212     return (fc_memory_add_malloc(ctx, ptr, size, where));
  213 }
  214 
  215 /* record a 'free' action */
  216 int fc_memory_add_free(void *ctx, void *ptr, void *where)
  217 {
  218     FC_MEl *el;
  219     FC_Memory *mem;
  220     int ret, a;
  221     void *tmp, *b;
  222 
  223     mem = ((FC_Context*) ctx)->memory;
  224 
  225     /* search the entry */
  226     ret = fc_hash_lookup(mem->hash, ptr, &a, &tmp, &b);
  227     if (!ret)
  228     {
  229         /* free on a unreferenced pointer */
  230         /* prepare a new entry */
  231         el = fc_memory_list_add(mem);
  232         el->pointer = ptr;
  233         el->alloc_place = where;
  234         el->realloc_place = NULL;
  235         fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
  236         el->size = UINT_MAX;
  237         /* remove the original from the hash-table */
  238         fc_hash_remove(mem->hash, ptr);
  239         return 1;
  240     }
  241 
  242     /* no more needs of this entry. remove */
  243     el = (FC_MEl*) tmp;
  244     fc_hash_remove(mem->hash, ptr);
  245     el->pointer = NULL;
  246     el->size = 0;
  247     el->set = 0;
  248     el->alloc_place = NULL;
  249     el->realloc_place = NULL;
  250     fc_memory_list_remove(mem, el);
  251 
  252     return 1;
  253 }
  254 
  255 /* record a 'realloc' entry */
  256 int fc_memory_add_realloc(void *ctx, void *ptr, void *inc, unsigned int size, void *where)
  257 {
  258     FC_MEl *el;
  259     FC_Memory *mem;
  260     void *tmp, *b;
  261     int a, ret;
  262 
  263     mem = ((FC_Context*) ctx)->memory;
  264 
  265     /* search the entry */
  266     ret = fc_hash_lookup(mem->hash, inc, &a, &tmp, &b);
  267     if (!ret)
  268     {/* realloc on a unreferenced pointer */
  269         /* prepare a new entry */
  270         el = fc_memory_list_add(mem);
  271         el->pointer = inc;
  272         el->realloc_place = where;
  273         fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
  274         el->alloc_place = NULL;
  275         el->size = UINT_MAX;
  276         return 1;
  277     }
  278 
  279     /* update the data */
  280     el = (FC_MEl*) tmp;
  281     el->realloc_place = where;
  282     el->pointer = ptr;
  283     /* just modify the hash-table entry */
  284     if (inc != ptr)
  285     {
  286         fc_hash_remove(mem->hash, inc);
  287         fc_hash_insert(mem->hash, ptr, 0, (void *) el, NULL);
  288     }
  289 
  290     return 1;
  291 }
  292