blob: 8a78ea4dcf8d773bbcefc81aadab75dddb40c853 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of Sun Microsystems nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/* Simple stack storage mechanism (or simple List). */
33
34/*
35 * Stack is any depth (grows as it needs to), elements are arbitrary
36 * length but known at stack init time.
37 *
38 * Stack elements can be accessed via pointers (be careful, if stack
39 * moved while you point into stack you have problems)
40 *
41 * Pointers to stack elements passed in are copied.
42 *
43 * Since the stack can be inspected, it can be used for more than just
44 * a simple stack.
45 *
46 */
47
48#include "hprof.h"
49
50static void
51resize(Stack *stack)
52{
53 void *old_elements;
54 void *new_elements;
55 int old_size;
56 int new_size;
57
58 HPROF_ASSERT(stack!=NULL);
59 HPROF_ASSERT(stack->elements!=NULL);
60 HPROF_ASSERT(stack->size>0);
61 HPROF_ASSERT(stack->elem_size>0);
62 HPROF_ASSERT(stack->incr_size>0);
63 old_size = stack->size;
64 old_elements = stack->elements;
65 if ( (stack->resizes % 10) && stack->incr_size < (old_size >> 2) ) {
66 stack->incr_size = old_size >> 2; /* 1/4 the old_size */
67 }
68 new_size = old_size + stack->incr_size;
69 new_elements = HPROF_MALLOC(new_size*stack->elem_size);
70 (void)memcpy(new_elements, old_elements, old_size*stack->elem_size);
71 stack->size = new_size;
72 stack->elements = new_elements;
73 HPROF_FREE(old_elements);
74 stack->resizes++;
75}
76
77Stack *
78stack_init(int init_size, int incr_size, int elem_size)
79{
80 Stack *stack;
81 void *elements;
82
83 HPROF_ASSERT(init_size>0);
84 HPROF_ASSERT(elem_size>0);
85 HPROF_ASSERT(incr_size>0);
86 stack = (Stack*)HPROF_MALLOC((int)sizeof(Stack));
87 elements = HPROF_MALLOC(init_size*elem_size);
88 stack->size = init_size;
89 stack->incr_size = incr_size;
90 stack->elem_size = elem_size;
91 stack->count = 0;
92 stack->elements = elements;
93 stack->resizes = 0;
94 return stack;
95}
96
97void *
98stack_element(Stack *stack, int i)
99{
100 HPROF_ASSERT(stack!=NULL);
101 HPROF_ASSERT(stack->elements!=NULL);
102 HPROF_ASSERT(stack->count>i);
103 HPROF_ASSERT(i>=0);
104 return (void*)(((char*)stack->elements) + i * stack->elem_size);
105}
106
107void *
108stack_top(Stack *stack)
109{
110 void *element;
111
112 HPROF_ASSERT(stack!=NULL);
113 element = NULL;
114 if ( stack->count > 0 ) {
115 element = stack_element(stack, (stack->count-1));
116 }
117 return element;
118}
119
120int
121stack_depth(Stack *stack)
122{
123 HPROF_ASSERT(stack!=NULL);
124 return stack->count;
125}
126
127void *
128stack_pop(Stack *stack)
129{
130 void *element;
131
132 element = stack_top(stack);
133 if ( element != NULL ) {
134 stack->count--;
135 }
136 return element;
137}
138
139void
140stack_push(Stack *stack, void *element)
141{
142 void *top_element;
143
144 HPROF_ASSERT(stack!=NULL);
145 if ( stack->count >= stack->size ) {
146 resize(stack);
147 }
148 stack->count++;
149 top_element = stack_top(stack);
150 (void)memcpy(top_element, element, stack->elem_size);
151}
152
153void
154stack_term(Stack *stack)
155{
156 HPROF_ASSERT(stack!=NULL);
157 if ( stack->elements != NULL ) {
158 HPROF_FREE(stack->elements);
159 }
160 HPROF_FREE(stack);
161}