source: golgotha/src/i4/time/profile.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 4.6 KB
Line 
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
24i4_profile_stack_struct i4_profile_stack;
25i4_profile_stack_item i4_profile_stack_struct::stack[I4_MAX_PROFILE_STACK_DEPTH];
26i4_profile_class *i4_profile_class::list;
27int i4_profile_on=0;
28int i4_profile_stack_top=0;
29
30
31
32void 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
44void i4_profile_stack_struct::underflow()
45{
46  i4_error("unbalanced profile start/stop");
47}
48
49i4_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
65void 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
80void 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
102i4_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
127void 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
135static 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
148static int prev_on;
149void 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
158void 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
Note: See TracBrowser for help on using the repository browser.