"Fossies" - the Fresh Open Source Software Archive

Member "FunctionCheck-3.2.0/src/fcmanager/fc_stack.c" (29 May 2012, 5327 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 GNU General 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 GNU
   13  *  General 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_stack.c: manage stack operations  **/
   20 
   21 #include <stdio.h>
   22 #include <stdlib.h>
   23 #include "fc_stack.h"
   24 
   25 /* number of elements to add in the stack */
   26 #define FC_STACK_STEP  256
   27 
   28 /* create an epmty stack */
   29 FC_Stack *fc_stack_create(int size)
   30 {
   31     FC_Stack *tmp;
   32 
   33     if (size <= 0)
   34     {
   35         fc_message("cannot create an empty stack.");
   36         return (NULL);
   37     }
   38 
   39     tmp = malloc(sizeof (FC_Stack));
   40     if (tmp == NULL)
   41     {
   42         fc_message("cannot allocate %d bytes for a stack.", sizeof (FC_Stack));
   43         return (NULL);
   44     }
   45 
   46     /* create a first set of elements */
   47     tmp->stack = malloc(sizeof (FC_SElem) * size);
   48     if (tmp->stack == NULL)
   49     {
   50         fc_message("cannot allocate %d bytes for a stack.", sizeof (FC_SElem) * size);
   51         free(tmp);
   52         return (NULL);
   53     }
   54 
   55     tmp->nb_elements = 0;
   56     tmp->real_size = size;
   57 
   58     return (tmp);
   59 }
   60 
   61 /* destroy a stack */
   62 void fc_stack_delete(FC_Stack *stack)
   63 {
   64     if (stack == NULL)
   65         return;
   66 
   67     if (stack->stack != NULL)
   68         free(stack->stack);
   69 
   70     free(stack);
   71 }
   72 
   73 /* add an element in the stack */
   74 int fc_stack_push(FC_Stack *stack, FC_Function *el, unsigned long long time, void *call_site)
   75 {
   76     if (stack->nb_elements >= stack->real_size)
   77     {
   78         stack->stack = realloc(stack->stack, sizeof (FC_SElem)*(stack->real_size + FC_STACK_STEP));
   79         if (stack->stack == NULL)
   80         {
   81             fc_message("cannot reallocate %d bytes for a stack.", sizeof (FC_SElem)*(stack->real_size + FC_STACK_STEP));
   82             stack->nb_elements = 0;
   83             stack->real_size = 0;
   84             return 0;
   85         }
   86         stack->real_size += FC_STACK_STEP;
   87     }
   88 
   89     /* insert the element */
   90     fc_debug("stack: insert %p at %d", el->symbol, stack->nb_elements);
   91     stack->stack[stack->nb_elements].function = el;
   92     stack->stack[stack->nb_elements].call_site = call_site;
   93     stack->stack[stack->nb_elements].time = time;
   94 
   95     stack->nb_elements++;
   96 
   97     return 1;
   98 }
   99 
  100 /* remove the upper element */
  101 int fc_stack_pop(FC_Stack *stack)
  102 {
  103     if (stack->nb_elements == 0)
  104     {
  105         fc_message("pop action on an empty stack! ignored.");
  106         return 0;
  107     }
  108     stack->nb_elements--;
  109     return 1;
  110 }
  111 
  112 /* get and remove the upper element */
  113 int fc_stack_get_and_pop(FC_Stack *stack, FC_Function **el, unsigned long long *time)
  114 {
  115     if (stack->nb_elements == 0)
  116     {
  117         fc_message("pop/get action on an empty stack! ignored.");
  118         return 0;
  119     }
  120     stack->nb_elements--;
  121     *el = stack->stack[stack->nb_elements].function;
  122     *time = stack->stack[stack->nb_elements].time;
  123     return 1;
  124 }
  125 
  126 /* get the upper element */
  127 int fc_stack_get(FC_Stack *stack, FC_Function **el, unsigned long long *time, void **call_site)
  128 {
  129     if (stack->nb_elements == 0)
  130     {
  131         fc_message("get action on an empty stack! ignored.");
  132         *el = NULL;
  133         return 0;
  134     }
  135     *el = stack->stack[stack->nb_elements - 1].function;
  136     *time = stack->stack[stack->nb_elements - 1].time;
  137     *call_site = stack->stack[stack->nb_elements - 1].call_site;
  138     return 1;
  139 }
  140 
  141 /* get the upper-1 element */
  142 int fc_stack_getp(FC_Stack *stack, FC_Function **el, unsigned long long *time)
  143 {
  144     if (stack->nb_elements == 1)
  145     {
  146         fc_message("getp action on a single-element stack! ignored.");
  147         *el = NULL;
  148         return 0;
  149     }
  150     *el = stack->stack[stack->nb_elements - 2].function;
  151     *time = stack->stack[stack->nb_elements - 2].time;
  152 
  153     return 1;
  154 }
  155 
  156 /* get the number of elements in the stack */
  157 int fc_stack_size(FC_Stack *stack)
  158 {
  159     return (stack->nb_elements);
  160 }
  161 
  162 /* true if the stack is empty */
  163 int fc_stack_empty(FC_Stack *stack)
  164 {
  165     return (stack->nb_elements == 0);
  166 }
  167 
  168 /* true if the element is still present */
  169 int fc_stack_here(FC_Stack *stack, void *el)
  170 {
  171     int i;
  172 
  173     if (stack->nb_elements == 0)
  174         return 0;
  175 
  176     for (i = stack->nb_elements - 1; i >= 0; i--)
  177     {
  178         if (stack->stack[i].function == el)
  179             return 1;
  180     }
  181 
  182     return 0;
  183 }
  184 
  185 /* set the given void* list (NULL termined) with the current
  186      call-stack (real call-site, not fnc address)
  187    Note: lst must have at least nb_max elements */
  188 int fc_get_top_stack(FC_Stack *stack, int nb_max, void **lst)
  189 {
  190     int i, pos = 0;
  191 
  192     for (i = stack->nb_elements - 1; i >= 0; i--)
  193     {
  194         lst[pos++] = stack->stack[i].call_site;
  195         if (pos >= nb_max)
  196             break; /* no more needed */
  197     }
  198 
  199     /* NULL terminated (only if not full) */
  200     if (pos < nb_max)
  201         lst[pos] = NULL;
  202 
  203     return 1;
  204 }
  205