23
23
24
24
#include < stdio.h>
25
25
26
+ #ifdef __QT_DRIVER__
27
+ #include < QThread>
28
+ #endif
29
+
26
30
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
27
31
#include < unistd.h>
28
32
#endif
37
41
38
42
namespace FCEU
39
43
{
44
+ static thread_local profileExecVector execList;
40
45
static thread_local profilerFuncMap threadProfileMap;
41
46
42
47
FILE *profilerManager::pLog = nullptr ;
@@ -64,10 +69,8 @@ void timeStampRecord::readNew(void)
64
69
{
65
70
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
66
71
clock_gettime ( CLOCK_REALTIME, &ts );
67
- #elif defined(WIN32)
68
- QueryPerformanceCounter ((LARGE_INTEGER*)&ts);
69
72
#else
70
- ts = 0 ;
73
+ QueryPerformanceCounter ((LARGE_INTEGER*)&ts) ;
71
74
#endif
72
75
tsc = rdtsc ();
73
76
}
@@ -121,16 +124,19 @@ funcProfileRecord::funcProfileRecord(const char *fileNameStringLiteral,
121
124
: fileLineNum(fileLineNumber), fileName(fileNameStringLiteral),
122
125
funcName (funcNameStringLiteral), comment(commentStringLiteral)
123
126
{
124
- min.zero ( );
127
+ min.fromSeconds ( 9 );
125
128
max.zero ();
126
129
sum.zero ();
127
130
numCalls = 0 ;
128
131
recursionCount = 0 ;
132
+
133
+ threadProfileMap.addRecord ( fileNameStringLiteral, fileLineNumber,
134
+ funcNameStringLiteral, commentStringLiteral, this );
129
135
}
130
136
// -------------------------------------------------------------------------
131
137
void funcProfileRecord::reset (void )
132
138
{
133
- min.zero ( );
139
+ min.fromSeconds ( 9 );
134
140
max.zero ();
135
141
sum.zero ();
136
142
numCalls = 0 ;
@@ -149,20 +155,9 @@ double funcProfileRecord::average(void)
149
155
// -------------------------------------------------------------------------
150
156
// ---- Profile Scoped Function Class
151
157
// -------------------------------------------------------------------------
152
- profileFuncScoped::profileFuncScoped (const char *fileNameStringLiteral,
153
- const int fileLineNumber,
154
- const char *funcNameStringLiteral,
155
- const char *commentStringLiteral)
158
+ profileFuncScoped::profileFuncScoped ( funcProfileRecord *recordIn )
156
159
{
157
- rec = nullptr ;
158
-
159
- // if (threadProfileMap == nullptr)
160
- // {
161
- // threadProfileMap = new profilerFuncMap();
162
- // }
163
-
164
- rec = threadProfileMap.findRecord ( fileNameStringLiteral, fileLineNumber,
165
- funcNameStringLiteral, commentStringLiteral, true );
160
+ rec = recordIn;
166
161
167
162
if (rec)
168
163
{
@@ -181,17 +176,70 @@ profileFuncScoped::~profileFuncScoped(void)
181
176
ts.readNew ();
182
177
dt = ts - start;
183
178
179
+ rec->last = dt;
184
180
rec->sum += dt;
185
181
if (dt < rec->min ) rec->min = dt;
186
182
if (dt > rec->max ) rec->max = dt;
187
183
188
184
rec->recursionCount --;
189
185
190
- // printf("%s: %u %f %f %f %f\n", rec->funcName, rec->numCalls, dt.toSeconds(), rec->average(), rec->min.toSeconds(), rec->max.toSeconds());
186
+ execList._vec .push_back (*rec);
187
+
191
188
threadProfileMap.popStack (rec);
192
189
}
193
190
}
194
191
// -------------------------------------------------------------------------
192
+ // ---- Profile Execution Vector
193
+ // -------------------------------------------------------------------------
194
+ profileExecVector::profileExecVector (void )
195
+ {
196
+ _vec.reserve ( 10000 );
197
+
198
+ char threadName[128 ];
199
+ char fileName[256 ];
200
+
201
+ strcpy ( threadName, " MainThread" );
202
+
203
+ #ifdef __QT_DRIVER__
204
+ QThread *thread = QThread::currentThread ();
205
+
206
+ if (thread)
207
+ {
208
+ // printf("Thread: %s\n", thread->objectName().toStdString().c_str());
209
+ strcpy ( threadName, thread->objectName ().toStdString ().c_str ());
210
+ }
211
+ #endif
212
+ sprintf ( fileName, " fceux-profile-%s.log" , threadName);
213
+
214
+ logFp = ::fopen (fileName, " w" );
215
+
216
+ if (logFp == nullptr )
217
+ {
218
+ printf (" Error: Failed to create profiler logfile: %s\n " , fileName);
219
+ }
220
+ }
221
+ // -------------------------------------------------------------------------
222
+ profileExecVector::~profileExecVector (void )
223
+ {
224
+ if (logFp)
225
+ {
226
+ ::fclose (logFp);
227
+ }
228
+ }
229
+ // -------------------------------------------------------------------------
230
+ void profileExecVector::update (void )
231
+ {
232
+ size_t n = _vec.size ();
233
+
234
+ for (size_t i=0 ; i<n; i++)
235
+ {
236
+ funcProfileRecord &rec = _vec[i];
237
+
238
+ fprintf ( logFp, " %s: %u %f %f %f %f\n " , rec.funcName , rec.numCalls , rec.last .toSeconds (), rec.average (), rec.min .toSeconds (), rec.max .toSeconds ());
239
+ }
240
+ _vec.clear ();
241
+ }
242
+ // -------------------------------------------------------------------------
195
243
// ---- Profile Function Record Map
196
244
// -------------------------------------------------------------------------
197
245
profilerFuncMap::profilerFuncMap (void )
@@ -207,15 +255,15 @@ profilerFuncMap::~profilerFuncMap(void)
207
255
// printf("profilerFuncMap Destructor: %p\n", this);
208
256
pMgr.removeThreadProfiler (this );
209
257
210
- {
211
- autoScopedLock aLock (_mapMtx);
258
+ // {
259
+ // autoScopedLock aLock(_mapMtx);
212
260
213
- for (auto it = _map.begin (); it != _map.end (); it++)
214
- {
215
- delete it->second ;
216
- }
217
- _map.clear ();
218
- }
261
+ // for (auto it = _map.begin(); it != _map.end(); it++)
262
+ // {
263
+ // delete it->second;
264
+ // }
265
+ // _map.clear();
266
+ // }
219
267
}
220
268
// -------------------------------------------------------------------------
221
269
void profilerFuncMap::pushStack (funcProfileRecord *rec)
@@ -228,6 +276,26 @@ void profilerFuncMap::popStack(funcProfileRecord *rec)
228
276
stack.pop_back ();
229
277
}
230
278
// -------------------------------------------------------------------------
279
+ int profilerFuncMap::addRecord (const char *fileNameStringLiteral,
280
+ const int fileLineNumber,
281
+ const char *funcNameStringLiteral,
282
+ const char *commentStringLiteral,
283
+ funcProfileRecord *rec )
284
+ {
285
+ autoScopedLock aLock (_mapMtx);
286
+ char lineString[64 ];
287
+
288
+ sprintf ( lineString, " :%i" , fileLineNumber);
289
+
290
+ std::string fname (fileNameStringLiteral);
291
+
292
+ fname.append ( lineString );
293
+
294
+ _map[fname] = rec;
295
+
296
+ return 0 ;
297
+ }
298
+ // -------------------------------------------------------------------------
231
299
funcProfileRecord *profilerFuncMap::findRecord (const char *fileNameStringLiteral,
232
300
const int fileLineNumber,
233
301
const char *funcNameStringLiteral,
@@ -363,6 +431,12 @@ int profilerManager::removeThreadProfiler( profilerFuncMap *m, bool shouldDestro
363
431
return result;
364
432
}
365
433
// -------------------------------------------------------------------------
366
- //
434
+ } // namespace FCEU
435
+
436
+ // -------------------------------------------------------------------------
437
+ int FCEU_profiler_log_thread_activity (void )
438
+ {
439
+ FCEU::execList.update ();
440
+ return 0 ;
367
441
}
368
442
#endif // __FCEU_PROFILER_ENABLE__
0 commit comments