1 : /*
2 : Copyright (C) 2007, Bruce Ediger
3 :
4 : This file is part of cl.
5 :
6 : cl is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 2 of the License, or
9 : (at your option) any later version.
10 :
11 : cl 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
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with cl; if not, write to the Free Software
18 : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 :
20 : */
21 : #include <stdlib.h>
22 : #include <stdio.h>
23 :
24 : #include <spine_stack.h>
25 :
26 : static struct spine_stack *spine_stack_free_list = NULL;
27 :
28 : static int stack_malloc_cnt = 0;
29 : static int stack_reused_cnt = 0;
30 : static int new_stack_cnt = 0;
31 :
32 : extern int interpreter_interrupted;
33 :
34 : struct spine_stack *
35 : new_spine_stack(int sz)
36 2131 : {
37 : struct spine_stack *r;
38 :
39 2131 : ++new_stack_cnt;
40 :
41 2131 : if (spine_stack_free_list)
42 : {
43 : /* dual use of prev field: linked list of "free" spine stacks,
44 : * and FIFO stack of actually in-use spine stacks. */
45 1553 : r = spine_stack_free_list;
46 1553 : spine_stack_free_list = r->prev;
47 1553 : r->prev = NULL;
48 1553 : ++stack_reused_cnt;
49 : } else {
50 578 : r = malloc(sizeof(*r));
51 578 : r->stack = malloc(sz * sizeof(r->stack[0]));
52 578 : r->top = 0;
53 578 : r->maxdepth = 0;
54 578 : r->size = sz;
55 578 : r->prev = NULL;
56 578 : r->sn = ++stack_malloc_cnt;
57 : }
58 :
59 2131 : return r;
60 : }
61 :
62 : void
63 : delete_spine_stack(struct spine_stack *ss)
64 2130 : {
65 : /* dual use of prev field: linked list of "free" spine stacks,
66 : * and FIFO stack of actually in-use spine stacks. */
67 2130 : ss->prev = spine_stack_free_list;
68 2130 : spine_stack_free_list = ss;
69 2130 : }
70 :
71 : void
72 : push_spine_stack(struct spine_stack **ss)
73 2131 : {
74 : /* dual use of prev field: linked list of "free" spine stacks,
75 : * and FIFO stack of actually in-use spine stacks.
76 : * This constitutes the FIFO stack of in-use spine stacks usage. */
77 2131 : struct spine_stack *p = new_spine_stack(32);
78 2131 : p->prev = *ss;
79 2131 : *ss = p;
80 2131 : }
81 :
82 : void
83 : pop_spine_stack(struct spine_stack **ss)
84 2130 : {
85 : /* FIFO-stack-of-in-use-stacks use of prev field */
86 2130 : struct spine_stack *tmp = (*ss)->prev;
87 2130 : delete_spine_stack(*ss);
88 2130 : *ss = tmp;
89 2130 : }
90 :
91 : void
92 : free_all_spine_stacks(int memory_info_flag)
93 56 : {
94 56 : int maxdepth = 0;
95 56 : int maxsize = 0;
96 56 : int depth_sum = 0;
97 56 : int stack_freed_cnt = 0;
98 689 : while (spine_stack_free_list)
99 : {
100 577 : struct spine_stack *tmp = spine_stack_free_list->prev;
101 577 : if (spine_stack_free_list->maxdepth > maxdepth)
102 80 : maxdepth = spine_stack_free_list->maxdepth;
103 577 : if (spine_stack_free_list->size > maxsize)
104 58 : maxsize = spine_stack_free_list->size;
105 577 : depth_sum += spine_stack_free_list->maxdepth;
106 577 : free(spine_stack_free_list->stack);
107 577 : spine_stack_free_list->stack = NULL;
108 577 : free(spine_stack_free_list);
109 577 : spine_stack_free_list = tmp;
110 577 : ++stack_freed_cnt;
111 : }
112 :
113 56 : if (!interpreter_interrupted && stack_freed_cnt != stack_malloc_cnt)
114 0 : fprintf(stderr, "Allocated %d spine stacks, freed %d\n",
115 : stack_malloc_cnt, stack_freed_cnt);
116 :
117 56 : if (memory_info_flag)
118 : {
119 0 : float mean_depth = stack_freed_cnt? (float)depth_sum/(float)stack_freed_cnt: 0.0;
120 0 : fprintf(stderr, "Gave out %d spine stacks\n", new_stack_cnt);
121 0 : fprintf(stderr, "Allocated %d spine stacks\n", stack_malloc_cnt);
122 0 : fprintf(stderr, "Reused %d spine stacks\n", stack_reused_cnt);
123 0 : fprintf(stderr, "Maximum spine stack depth: %d\n", maxdepth);
124 0 : fprintf(stderr, "Maximum spine stack size: %d\n", maxsize);
125 0 : fprintf(stderr, "Mean spine stack depth: %.02f\n", mean_depth);
126 : }
127 56 : }
128 :
129 : void
130 : pushnode(struct spine_stack *ss, struct node *n)
131 52247269 : {
132 52247269 : ss->stack[ss->top] = n;
133 :
134 52247269 : ++ss->top;
135 :
136 52247269 : if (ss->top >= ss->size)
137 : {
138 : /* resize the allocation pointed to by stack */
139 119 : struct node **old_stack = ss->stack;
140 119 : size_t new_size = ss->size * 2; /* XXX !!! */
141 119 : ss->stack = realloc(old_stack, sizeof(struct node *)*new_size);
142 119 : if (!ss->stack)
143 0 : ss->stack = old_stack; /* realloc failed */
144 : else
145 119 : ss->size = new_size;
146 : }
147 52247269 : }
|