1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "error/error.hh"
|
---|
10 | #include "time/profile.hh"
|
---|
11 | #include "file/file.hh"
|
---|
12 | #include "time/time.hh"
|
---|
13 | #include "file/file.hh"
|
---|
14 | #include "time/profile_stack.hh"
|
---|
15 | #include "memory/malloc.hh"
|
---|
16 | #include "string/string.hh"
|
---|
17 | #include "threads/threads.hh"
|
---|
18 |
|
---|
19 | #include <stdio.h>
|
---|
20 |
|
---|
21 | #ifdef I4_PROFILING
|
---|
22 |
|
---|
23 |
|
---|
24 | i4_profile_stack_struct i4_profile_stack;
|
---|
25 | i4_profile_stack_item i4_profile_stack_struct::stack[I4_MAX_PROFILE_STACK_DEPTH];
|
---|
26 | i4_profile_class *i4_profile_class::list;
|
---|
27 | int i4_profile_on=0;
|
---|
28 | int i4_profile_stack_top=0;
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 | void i4_profile_stack_struct::overflow()
|
---|
33 | {
|
---|
34 | i4_debug->printf("items on stack end :\n");
|
---|
35 | for (int i=top()-1; i>top()-30; i--)
|
---|
36 | i4_debug->printf(" '%s'\n",stack[i].item->name);
|
---|
37 |
|
---|
38 | i4_error("profile stack overflow");
|
---|
39 |
|
---|
40 |
|
---|
41 |
|
---|
42 | }
|
---|
43 |
|
---|
44 | void i4_profile_stack_struct::underflow()
|
---|
45 | {
|
---|
46 | i4_error("unbalanced profile start/stop");
|
---|
47 | }
|
---|
48 |
|
---|
49 | i4_profile_class::i4_profile_class(char *debug_name)
|
---|
50 | : name(debug_name)
|
---|
51 | {
|
---|
52 | for (i4_profile_class *p=list; p; p=p->next)
|
---|
53 | if (p==this)
|
---|
54 | i4_error("already in list?");
|
---|
55 |
|
---|
56 | total_time=0;
|
---|
57 | next=list;
|
---|
58 | list=this;
|
---|
59 | active=1;
|
---|
60 | }
|
---|
61 |
|
---|
62 |
|
---|
63 |
|
---|
64 |
|
---|
65 | void i4_profile_class::called_start()
|
---|
66 | {
|
---|
67 | w64 current_clock=i4_get_system_clock();
|
---|
68 | if (i4_get_thread_id()==i4_get_main_thread_id())
|
---|
69 | {
|
---|
70 | i4_profile_stack_item *top=i4_profile_stack.get_top();
|
---|
71 | if (top)
|
---|
72 | top->item->total_time+=current_clock-top->start_clock;
|
---|
73 |
|
---|
74 |
|
---|
75 | i4_profile_stack.push(this, current_clock);
|
---|
76 | }
|
---|
77 |
|
---|
78 | }
|
---|
79 |
|
---|
80 | void i4_profile_class::called_stop()
|
---|
81 | {
|
---|
82 | w64 current_clock=i4_get_system_clock();
|
---|
83 |
|
---|
84 | if (i4_get_thread_id()==i4_get_main_thread_id())
|
---|
85 | {
|
---|
86 | i4_profile_stack_item *me=i4_profile_stack.pop();
|
---|
87 | if (me->item!=this)
|
---|
88 | i4_error("profile stop unmatched %s (%s on stack)",
|
---|
89 | name, me->item->name);
|
---|
90 |
|
---|
91 | total_time+=current_clock - me->start_clock;
|
---|
92 |
|
---|
93 | i4_profile_stack_item *top=i4_profile_stack.get_top();
|
---|
94 | if (top)
|
---|
95 | top->start_clock=current_clock;
|
---|
96 | }
|
---|
97 |
|
---|
98 | }
|
---|
99 |
|
---|
100 |
|
---|
101 |
|
---|
102 | i4_profile_class::~i4_profile_class()
|
---|
103 | {
|
---|
104 | if (this==list)
|
---|
105 | list=next;
|
---|
106 | else
|
---|
107 | {
|
---|
108 | i4_profile_class *last=0;
|
---|
109 | i4_profile_class *p;
|
---|
110 |
|
---|
111 | for (p=list; p && p!=this; )
|
---|
112 | {
|
---|
113 | last=p;
|
---|
114 | p=p->next;
|
---|
115 | }
|
---|
116 |
|
---|
117 | if (p!=this)
|
---|
118 | i4_warning("could not find profile entry to unlink %s", name);
|
---|
119 | else
|
---|
120 | last->next=next;
|
---|
121 | }
|
---|
122 |
|
---|
123 | }
|
---|
124 |
|
---|
125 |
|
---|
126 | // clear out any profile timing information we have so far
|
---|
127 | void i4_profile_clear()
|
---|
128 | {
|
---|
129 | i4_profile_stack.flush_stack();
|
---|
130 | for (i4_profile_class *p=i4_profile_class::list; p; p=p->next)
|
---|
131 | p->total_time=0;
|
---|
132 |
|
---|
133 | }
|
---|
134 |
|
---|
135 | static int profile_compare(const void *a, const void *b)
|
---|
136 | {
|
---|
137 | i4_profile_class *ap=*((i4_profile_class **)a);
|
---|
138 | i4_profile_class *bp=*((i4_profile_class **)b);
|
---|
139 |
|
---|
140 | if (ap->total_time<bp->total_time)
|
---|
141 | return 1;
|
---|
142 | else if (ap->total_time>bp->total_time)
|
---|
143 | return -1;
|
---|
144 | else return 0;
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 | static int prev_on;
|
---|
149 | void i4_profile_report_start()
|
---|
150 | {
|
---|
151 | i4_profile_clear();
|
---|
152 | prev_on=i4_profile_on;
|
---|
153 | i4_profile_on=i4_T;
|
---|
154 | }
|
---|
155 |
|
---|
156 |
|
---|
157 | // print a report to about timing since the last clear or program start
|
---|
158 | void i4_profile_report(char *filename)
|
---|
159 | {
|
---|
160 | i4_profile_stack.flush_stack();
|
---|
161 |
|
---|
162 | double total_time=0;
|
---|
163 | int t=0,i=0;
|
---|
164 | i4_profile_class *p;
|
---|
165 |
|
---|
166 | for (p=i4_profile_class::list; p; p=p->next, t++)
|
---|
167 | total_time+=(double)(sw64)p->total_time;
|
---|
168 |
|
---|
169 | // put them all in a list and sort them by clocks
|
---|
170 | i4_profile_class **plist;
|
---|
171 | plist=(i4_profile_class **)i4_malloc(sizeof(i4_profile_class *)*t,"");
|
---|
172 | for (p=i4_profile_class::list; p; p=p->next)
|
---|
173 | plist[i++]=p;
|
---|
174 |
|
---|
175 |
|
---|
176 | qsort(plist, t, sizeof(i4_profile_class *), profile_compare);
|
---|
177 |
|
---|
178 |
|
---|
179 | double oo_total=1.0/total_time;
|
---|
180 | char buf[100];
|
---|
181 |
|
---|
182 | i4_file_class *fp=i4_open(filename, I4_WRITE);
|
---|
183 | if (fp)
|
---|
184 | {
|
---|
185 | sprintf(buf,"%2.2f total clocks\n", total_time);
|
---|
186 | fp->write(buf, strlen(buf));
|
---|
187 |
|
---|
188 | for (i=0; i<t; i++)
|
---|
189 | {
|
---|
190 | double percent= (sw64)plist[i]->total_time * oo_total;
|
---|
191 | double t_clocks=(sw64)plist[i]->total_time;
|
---|
192 |
|
---|
193 | sprintf(buf,"%2.2f%% %2.0f clocks %s\n", percent * 100.0, t_clocks, plist[i]->name);
|
---|
194 | fp->write(buf, strlen(buf));
|
---|
195 | }
|
---|
196 | delete fp;
|
---|
197 | }
|
---|
198 |
|
---|
199 |
|
---|
200 |
|
---|
201 |
|
---|
202 | i4_free(plist);
|
---|
203 | i4_profile_on=prev_on;
|
---|
204 | }
|
---|
205 |
|
---|
206 | #endif
|
---|
207 |
|
---|
208 |
|
---|
209 |
|
---|
210 |
|
---|
211 |
|
---|