source: trunk/src/kernel32/perfview.cpp@ 7022

Last change on this file since 7022 was 7021, checked in by phaller, 24 years ago

.

File size: 6.9 KB
Line 
1/* $Id: perfview.cpp,v 1.1 2001-10-11 17:31:12 phaller Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 performance measurement and self-profiling API functions
7 *
8 * Copyright 2001 Patrick Haller <patrick.haller@innotek.de>
9 */
10
11/****************************************************************************
12 * includes
13 ****************************************************************************/
14#include "perfview.h"
15
16
17#ifndef PROFILE
18
19// insert "nullified" dummies here to save space in the executable image
20void PerfView_RegisterCall(char* pszFunctionName,
21 unsigned long int nTicks) {}
22
23void PerfView_DumpProfile(FILE *file) {}
24void PerfView_Write() {}
25
26#else
27
28#include <ccollection.h>
29#include <win32type.h>
30
31// imported from the kernel loader (initterm)
32extern int loadNr;
33extern char kernel32Path[];
34
35
36
37typedef struct tagFUNCTION
38{
39 char* pszFunctionName;
40 unsigned long int nCalled;
41 unsigned long int nTotalTicks;
42} PERFVIEW_FUNCTION, *PPERFVIEW_FUNCTION;
43
44
45// the map keeps track of all called methods and functions
46static CHashtableLookup* pProfileMap = new CHashtableLookup(1021);
47static BOOL flagLock = FALSE;
48
49// register a call to a function
50void _Optlink PerfView_RegisterCall(char* pszFunctionName,
51 unsigned long int nTicks)
52{
53 // don't record call if currently locked
54 if (flagLock)
55 return;
56
57 // check if that particular function is registered already
58 PPERFVIEW_FUNCTION p = (PPERFVIEW_FUNCTION)pProfileMap->getElement(pszFunctionName);
59 if (NULL == p)
60 {
61 // new function call
62 p = (PPERFVIEW_FUNCTION)malloc( sizeof( PERFVIEW_FUNCTION ) );
63 p->pszFunctionName = strdup( pszFunctionName );
64 p->nCalled = 0;
65 p->nTotalTicks = 0;
66
67 // add to the hashtable
68 pProfileMap->addElement(pszFunctionName, p);
69 }
70
71 // update statistical data
72 p->nCalled++;
73 p->nTotalTicks += nTicks;
74}
75
76
77int _Optlink sortHashtableEntries0(const void *arg1,const void *arg2)
78{
79 PHASHTABLEENTRY pHTE1 = (PHASHTABLEENTRY)arg1;
80 PHASHTABLEENTRY pHTE2 = (PHASHTABLEENTRY)arg2;
81
82 PPERFVIEW_FUNCTION p1 = (PPERFVIEW_FUNCTION)pHTE1->pObject;
83 PPERFVIEW_FUNCTION p2 = (PPERFVIEW_FUNCTION)pHTE2->pObject;
84
85 return strcmp(p1->pszFunctionName, p2->pszFunctionName);
86}
87
88int _Optlink sortHashtableEntries1(const void *arg1,const void *arg2)
89{
90 PHASHTABLEENTRY pHTE1 = (PHASHTABLEENTRY)arg1;
91 PHASHTABLEENTRY pHTE2 = (PHASHTABLEENTRY)arg2;
92
93 PPERFVIEW_FUNCTION p1 = (PPERFVIEW_FUNCTION)pHTE1->pObject;
94 PPERFVIEW_FUNCTION p2 = (PPERFVIEW_FUNCTION)pHTE2->pObject;
95
96 // return strcmp(pHTE1->pszName, pHTE2->pszName);
97 return p1->nTotalTicks - p2->nTotalTicks;
98}
99
100int _Optlink sortHashtableEntries2(const void *arg1,const void *arg2)
101{
102 PHASHTABLEENTRY pHTE1 = (PHASHTABLEENTRY)arg1;
103 PHASHTABLEENTRY pHTE2 = (PHASHTABLEENTRY)arg2;
104
105 PPERFVIEW_FUNCTION p1 = (PPERFVIEW_FUNCTION)pHTE1->pObject;
106 PPERFVIEW_FUNCTION p2 = (PPERFVIEW_FUNCTION)pHTE2->pObject;
107
108 return p1->nCalled - p2->nCalled;
109}
110
111int _Optlink sortHashtableEntries3(const void *arg1,const void *arg2)
112{
113 PHASHTABLEENTRY pHTE1 = (PHASHTABLEENTRY)arg1;
114 PHASHTABLEENTRY pHTE2 = (PHASHTABLEENTRY)arg2;
115
116 PPERFVIEW_FUNCTION p1 = (PPERFVIEW_FUNCTION)pHTE1->pObject;
117 PPERFVIEW_FUNCTION p2 = (PPERFVIEW_FUNCTION)pHTE2->pObject;
118
119 unsigned long int iAvg1 = p1->nTotalTicks / p1->nCalled;
120 unsigned long int iAvg2 = p2->nTotalTicks / p2->nCalled;
121
122 return iAvg1 - iAvg2;
123}
124
125
126// dump the collected profile to the specified file
127void _Optlink PerfView_DumpProfile(FILE *file)
128{
129 flagLock = TRUE; // lock recording
130
131 int iEntries = pProfileMap->getSize();
132
133 // get a list of all entries of the hashtable
134 PHASHTABLEENTRY arrEntries = (PHASHTABLEENTRY)malloc( iEntries * sizeof(HASHTABLEENTRY) );
135 iEntries = pProfileMap->getElementMap(arrEntries);
136
137 // sort the list by function name
138 qsort(arrEntries,
139 iEntries,
140 sizeof( HASHTABLEENTRY ),
141 sortHashtableEntries0);
142
143 // write to file
144 fprintf(file,
145 "Sorted by function name\n"
146 "Ticks ---- Called --- Average -- Function ---------------------------------\n");
147 for(int i = 0;
148 i < iEntries;
149 i++)
150 {
151 PPERFVIEW_FUNCTION p = (PPERFVIEW_FUNCTION)arrEntries[i].pObject;
152 fprintf(file,
153 "%10d %10d %10d %s\n",
154 p->nTotalTicks,
155 p->nCalled,
156 p->nTotalTicks / p->nCalled,
157 p->pszFunctionName);
158 }
159
160
161 // sort the list by nTotalTicks
162 qsort(arrEntries,
163 iEntries,
164 sizeof( HASHTABLEENTRY ),
165 sortHashtableEntries1);
166
167 // write to file
168 fprintf(file,
169 "\nSorted by total call time\n"
170 "Ticks ---- Called --- Average -- Function ---------------------------------\n");
171 for(i = 0;
172 i < iEntries;
173 i++)
174 {
175 PPERFVIEW_FUNCTION p = (PPERFVIEW_FUNCTION)arrEntries[i].pObject;
176 fprintf(file,
177 "%10d %10d %10d %s\n",
178 p->nTotalTicks,
179 p->nCalled,
180 p->nTotalTicks / p->nCalled,
181 p->pszFunctionName);
182 }
183
184
185 // sort the list by nCalled
186 qsort(arrEntries,
187 iEntries,
188 sizeof( HASHTABLEENTRY ),
189 sortHashtableEntries2);
190
191 // write to file
192 fprintf(file,
193 "\nSorted by total calls\n"
194 "Called --- Ticks ---- Average -- Function ---------------------------------\n");
195 for(i = 0;
196 i < iEntries;
197 i++)
198 {
199 PPERFVIEW_FUNCTION p = (PPERFVIEW_FUNCTION)arrEntries[i].pObject;
200 fprintf(file,
201 "%10d %10d %10d %s\n",
202 p->nCalled,
203 p->nTotalTicks,
204 p->nTotalTicks / p->nCalled,
205 p->pszFunctionName);
206 }
207
208
209 // sort the list by average call time
210 qsort(arrEntries,
211 iEntries,
212 sizeof( HASHTABLEENTRY ),
213 sortHashtableEntries3);
214
215 // write to file
216 fprintf(file,
217 "\nSorted by average call time\n"
218 "Average -- Calls ---- Ticks ---- Function ---------------------------------\n");
219 for(i = 0;
220 i < iEntries;
221 i++)
222 {
223 PPERFVIEW_FUNCTION p = (PPERFVIEW_FUNCTION)arrEntries[i].pObject;
224 fprintf(file,
225 "%10d %10d %10d %s\n",
226 p->nTotalTicks / p->nCalled,
227 p->nCalled,
228 p->nTotalTicks,
229 p->pszFunctionName);
230 }
231
232
233 flagLock = FALSE; // lock recording
234}
235
236
237//use a different logfile
238#define PRIVATE_LOGGING
239#include <misc.h>
240
241
242void PerfView_Write()
243{
244 FILE* _privateLogFile;
245 char szFilename[260];
246
247 sprintf(szFilename, "perf_%d.log", loadNr);
248 _privateLogFile = fopen(szFilename, "w");
249
250 if(_privateLogFile == NULL)
251 {
252 sprintf(szFilename, "%spe_%d.log", kernel32Path, loadNr);
253 _privateLogFile = fopen(szFilename, "w");
254 }
255
256 dprintfGlobal(("PE PERFFILE : %s", szFilename));
257
258 // dump the gathered data
259 PerfView_DumpProfile(_privateLogFile);
260
261 if(_privateLogFile)
262 {
263 fclose(_privateLogFile);
264 _privateLogFile = NULL;
265 }
266}
267
268
269
270#endif /* PROFILE */
Note: See TracBrowser for help on using the repository browser.