Watt-32 tcp/ip  2.2 dev-rel.10
profile.c
Go to the documentation of this file.
1 
6 /* Copyright (c) 1997-2007 Gisle Vanem <gvanem@yahoo.no>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  * must display the following acknowledgement:
18  * This product includes software developed by Gisle Vanem
19  * Bergen, Norway.
20  *
21  * THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <math.h>
36 
37 #include "wattcp.h"
38 #include "cpumodel.h"
39 #include "timer.h"
40 #include "misc.h"
41 #include "run.h"
42 #include "strings.h"
43 #include "language.h"
44 #include "pcconfig.h"
45 #include "profile.h"
46 
47 #if defined(USE_PROFILER)
48 
49 #if defined(WIN32)
50  #undef GET_RDTSC
51  #define GET_RDTSC() win_get_perf_count()
52 #endif
53 
54 /*
55  * A simple execution profiler
56  */
57 BOOL profile_enable = FALSE;
58 char profile_file [MAX_PATHLEN+1] = ".\\WATTCP.PRO";
59 
60 static FILE *prof_fout;
61 static uint64 prof_start;
62 static uint64 num_profs;
63 
64 /*
65  * Called on entry of something to profile.
66  */
67 void profile_start (const char *str)
68 {
69  if (prof_fout)
70  {
71  if (str)
72  fprintf (prof_fout, " profiling %-12.12s ", str);
73  prof_start = GET_RDTSC();
74  num_profs++;
75  }
76 }
77 
78 /*
79  * Dumps the time taken (milli-sec and CPU clocks).
80  */
81 void profile_stop (void)
82 {
83  if (prof_fout && clocks_per_usec)
84  {
85  int64 clocks = (int64) (GET_RDTSC() - prof_start);
86  double msec = (double)clocks / ((double)clocks_per_usec * 1000.0);
87  fprintf (prof_fout, "%10.3f msec (%10" S64_FMT " clk)\n", msec, clocks);
88  }
89 }
90 
91 static void profile_exit (void)
92 {
93  if (prof_fout)
94  {
95  FCLOSE (prof_fout);
96  prof_fout = NULL;
97  if (num_profs)
98  (*_printf) ("profiling info written to \"%s\"\n", profile_file);
99  }
100 }
101 
102 /*
103  * Dump some arbitrary data-array to profile dump file.
104  */
105 void profile_dump (const uint64 *data, size_t num)
106 {
107  unsigned i;
108 
109  if (!prof_fout || !clocks_per_usec)
110  return;
111 
112  for (i = 0; i < num; i++)
113  {
114  double msec = (double)data[i] / ((double)clocks_per_usec * 1000.0);
115 
116  fprintf (prof_fout, "profile_dump: %3u: %12.3f msec (%10" U64_FMT " clk)\n",
117  i, msec, data[i]);
118  }
119 }
120 
121 /*
122  * Profile speed of receiving a packet. Write the difference of
123  * put - DOS: timestamp for 2nd packet upcall.
124  * WIN32: timestamp when recv-thread captured the packet.
125  * get - timestamp when we called pkt_poll_recv().
126  *
127  * DOS: the 'put' and 'get' are CPU clock timestamps (rdtsc).
128  * WIN32: these are values from QueryPerformanceCounter().
129  */
130 void profile_recv (uint64 put, uint64 get)
131 {
132  if (!prof_fout || !clocks_per_usec)
133  return;
134 
135  fputs (" profiling pkt_receiver ", prof_fout);
136  if (get == U64_SUFFIX(0) || put == U64_SUFFIX(0))
137  fputs ("<not enabled>\n", prof_fout);
138  else
139  {
140  int64 clocks = (int64) (get - put);
141  double msec = (double)clocks / ((double)clocks_per_usec * 1000.0);
142  fprintf (prof_fout, "%10.3f msec (%10" S64_FMT " clk)\n", msec, clocks);
143  }
144 }
145 
146 /*
147  * Must be called after init_timers() or init_misc().
148  */
149 int profile_init (void)
150 {
151  uint64 overhead, start;
152  time_t now;
153  char ct_buf [30];
154 
155  if (!profile_enable || !profile_file[0])
156  return (0);
157 
158  if (!has_rdtsc || !clocks_per_usec)
159  {
160  profile_enable = FALSE;
161  (*_printf) (_LANG("Profiling not available (no RDTSC or $USE_RDTSC=1)\n"));
162  return (0);
163  }
164 
165  if (!FOPEN_APP(prof_fout,profile_file))
166  {
167  (*_printf) (_LANG("Failed to open %s: %s\n"),
168  profile_file, strerror(errno));
169  return (0);
170  }
171 
172 #if !defined(__BORLANDC__) /* buggy output with this */
173  {
174  static char fbuf [256];
175  setvbuf (prof_fout, fbuf, _IOLBF, sizeof(fbuf)); /* line-buffered */
176  }
177 #endif
178 
179  now = time (NULL);
180  fprintf (prof_fout, "\nProfiling %s, %.15s, %s\n",
181  get_argv0(), ctime_r(&now, ct_buf) + 4, dos_extender_name());
182 
183  num_profs = 0;
184  start = GET_RDTSC();
185  profile_start ("dummy");
186  profile_stop();
187  overhead = GET_RDTSC() - start;
188 
189  fprintf (prof_fout, " CPU-speed %lu MHz, overhead %" U64_FMT " clocks\n",
190  clocks_per_usec, overhead);
191  RUNDOWN_ADD (profile_exit, 90);
192  return (1);
193 }
194 
195 int profile_on (void)
196 {
197  return (prof_fout != NULL);
198 }
199 #endif /* USE_PROFILER */
200 
const char * get_argv0(void)
Return argv[0] as passed to main().
Definition: pcconfig.c:668
BOOL has_rdtsc
Never set in Watt-32.
Definition: timer.c:52
DWORD clocks_per_usec
Measured CPU speed (MHz)
Definition: timer.c:62
Core definitions.
unsigned long long uint64
our unsigned "long long" type
Definition: wattcp.h:60
long long int64
our signed "long long" type
Definition: wattcp.h:61
char * ctime_r(const time_t *t, char *res)
A reentrant ctime().
Definition: misc.c:878