"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