13
13
#include <stdio.h>
14
14
#include <string.h>
15
15
16
+ #include <pspprof.h>
17
+
16
18
#define GMON_PROF_ON 0
17
19
#define GMON_PROF_BUSY 1
18
20
#define GMON_PROF_ERROR 2
@@ -78,8 +80,11 @@ extern int _ftext;
78
80
extern int _etext ;
79
81
80
82
/* forward declarations */
83
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
81
84
void __gprof_cleanup (void );
85
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
82
86
void __mcount (unsigned int , unsigned int );
87
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
83
88
static SceUInt timer_handler (SceUID uid , SceKernelSysClock * c1 , SceKernelSysClock * c2 , void * common );
84
89
85
90
/** Initializes pg library
@@ -89,6 +94,7 @@ static SceUInt timer_handler(SceUID uid, SceKernelSysClock *c1, SceKernelSysCloc
89
94
for sampling statistics. Note that this also installs a timer that
90
95
runs at 1000 hert.
91
96
*/
97
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
92
98
static void initialize ()
93
99
{
94
100
initialized = 1 ;
@@ -122,6 +128,15 @@ static void initialize()
122
128
memset ((void * )gp .samples , '\0' , gp .nsamples * (sizeof (unsigned int )));
123
129
124
130
gp .timer = sceKernelCreateVTimer ("gprof timer" , NULL );
131
+ if (gp .timer < 0 )
132
+ {
133
+ free (gp .arcs );
134
+ free (gp .samples );
135
+ gp .arcs = 0 ;
136
+ gp .samples = 0 ;
137
+ gp .state = GMON_PROF_ERROR ;
138
+ return ;
139
+ }
125
140
126
141
SceKernelSysClock sc ;
127
142
sc .hi = 0 ;
@@ -151,12 +166,17 @@ static void initialize()
151
166
}
152
167
}
153
168
154
- /** Writes gmon.out dump file and stops profiling
169
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
170
+ void gprof_start (void ) {
171
+ // There is already a profiling session running, let's stop it and ignore the result
172
+ if (gp .state == GMON_PROF_ON ) {
173
+ gprof_stop (NULL , 0 );
174
+ }
175
+ initialize ();
176
+ }
155
177
156
- Called from atexit() handler; will dump out a host:gmon.out file
157
- with all collected information.
158
- */
159
- void __gprof_cleanup ()
178
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
179
+ void gprof_stop (const char * filename , int should_dump )
160
180
{
161
181
FILE * fp ;
162
182
int i ;
@@ -171,29 +191,47 @@ void __gprof_cleanup()
171
191
/* disable profiling before we make plenty of libc calls */
172
192
gp .state = GMON_PROF_OFF ;
173
193
194
+ // Delete timer
174
195
sceKernelStopVTimer (gp .timer );
175
-
176
- fp = fopen ( "gmon.out" , "wb" );
177
- hdr . lpc = gp . lowpc ;
178
- hdr . hpc = gp . highpc ;
179
- hdr . ncnt = sizeof ( hdr ) + ( sizeof ( unsigned int ) * gp .nsamples ) ;
180
- hdr .version = GMONVERSION ;
181
- hdr .profrate = SAMPLE_FREQ ;
182
- hdr .resv [ 0 ] = 0 ;
183
- hdr .resv [ 1 ] = 0 ;
184
- hdr .resv [2 ] = 0 ;
185
- fwrite ( & hdr , 1 , sizeof ( hdr ), fp ) ;
186
- fwrite ( gp . samples , gp . nsamples , sizeof ( unsigned int ), fp ) ;
187
-
188
- for ( i = 0 ; i < gp .narcs ; i ++ )
189
- {
190
- if ( gp .arcs [ i ]. count > 0 )
196
+ sceKernelDeleteVTimer ( gp . timer );
197
+
198
+ if ( should_dump ) {
199
+ fp = fopen ( filename , "wb" ) ;
200
+ hdr . lpc = gp .lowpc ;
201
+ hdr .hpc = gp . highpc ;
202
+ hdr .ncnt = sizeof ( hdr ) + ( sizeof ( unsigned int ) * gp . nsamples ) ;
203
+ hdr .version = GMONVERSION ;
204
+ hdr .profrate = SAMPLE_FREQ ;
205
+ hdr .resv [0 ] = 0 ;
206
+ hdr . resv [ 1 ] = 0 ;
207
+ hdr . resv [ 2 ] = 0 ;
208
+ fwrite ( & hdr , 1 , sizeof ( hdr ), fp );
209
+ fwrite ( gp . samples , gp .nsamples , sizeof ( unsigned int ), fp );
210
+
211
+ for ( i = 0 ; i < gp .narcs ; i ++ )
191
212
{
192
- fwrite (gp .arcs + i , sizeof (struct rawarc ), 1 , fp );
213
+ if (gp .arcs [i ].count > 0 )
214
+ {
215
+ fwrite (gp .arcs + i , sizeof (struct rawarc ), 1 , fp );
216
+ }
193
217
}
218
+
219
+ fclose (fp );
194
220
}
195
221
196
- fclose (fp );
222
+ // Free memory
223
+ free (gp .arcs );
224
+ free (gp .samples );
225
+ }
226
+
227
+ /** Writes gmon.out dump file and stops profiling
228
+ Called from atexit() handler; will dump out a gmon.out file
229
+ at cwd with all collected information.
230
+ */
231
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
232
+ void __gprof_cleanup ()
233
+ {
234
+ gprof_stop ("gmon.out" , 1 );
197
235
}
198
236
199
237
/** Internal C handler for _mcount()
@@ -205,6 +243,7 @@ void __gprof_cleanup()
205
243
beginning of each compiled routine, which eventually brings the
206
244
control to here.
207
245
*/
246
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
208
247
void __mcount (unsigned int frompc , unsigned int selfpc )
209
248
{
210
249
int e ;
@@ -238,6 +277,7 @@ void __mcount(unsigned int frompc, unsigned int selfpc)
238
277
239
278
/** Internal timer handler
240
279
*/
280
+ __attribute__((__no_instrument_function__ , __no_profile_instrument_function__ ))
241
281
static SceUInt timer_handler (SceUID uid , SceKernelSysClock * requested , SceKernelSysClock * actual , void * common )
242
282
{
243
283
unsigned int frompc = gp .pc ;
0 commit comments