14 #pragma warning (disable:4996)
15 #ifndef WIN32_LEAN_AND_MEAN
16 #define WIN32_LEAN_AND_MEAN
19 #define __thread __declspec(thread)
20 #define pthread_mutex_t CRITICAL_SECTION
21 #define pthread_mutex_init(a, b) InitializeCriticalSection(a)
22 #define pthread_mutex_lock(a) EnterCriticalSection(a)
23 #define pthread_mutex_unlock(a) LeaveCriticalSection(a)
24 #define pthread_mutex_destroy(a) DeleteCriticalSection(a)
32 #define __STDC_FORMAT_MACROS
38 #define ATTR_NORETURN __attribute__((noreturn))
43 #define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
80 #define STRING_POOL_SIZE 100
94 return (
int)GetCurrentThreadId();
97 return (
int)GetCurrentProcessId();
100 static uint64_t _frequency = 0;
101 static uint64_t _starttime = 0;
103 if (_frequency == 0) {
104 QueryPerformanceFrequency((LARGE_INTEGER*)&_frequency);
105 QueryPerformanceCounter((LARGE_INTEGER*)&_starttime);
108 QueryPerformanceCounter((LARGE_INTEGER*)&time);
109 return ((
double) (time - _starttime) / (
double) _frequency);
113 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) {
114 if (
is_tracing && fdwCtrlType == CTRL_C_EVENT) {
115 printf(
"Ctrl-C detected! Flushing trace and shutting down.\n\n");
124 SetConsoleCtrlHandler(&CtrlHandler,
TRUE);
130 return (
int)(intptr_t)pthread_self();
133 return (
int)getpid();
136 #if defined(BLACKBERRY)
138 struct timespec time;
139 clock_gettime(CLOCK_MONOTONIC, &time);
140 return time.tv_sec + time.tv_nsec / 1.0e9;
146 gettimeofday(&tv, NULL);
151 return (
double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
153 #endif // !BLACKBERRY
159 printf(
"Ctrl-C detected! Flushing trace and shutting down.\n\n");
161 fwrite(
"\n]}\n", 1, 4,
f);
173 signal(SIGINT, SIG_IGN);
187 const char *header =
"{\"traceEvents\":[\n";
188 fwrite(header, 1, strlen(header),
f);
191 pthread_mutex_init(&
mutex, 0);
207 pthread_mutex_lock(&
mutex);
209 pthread_mutex_unlock(&
mutex);
212 fwrite(
"\n]}\n", 1, 4,
f);
214 pthread_mutex_destroy(&
mutex);
231 str_pool[i] = (
char*)malloc(strlen(str) + 1);
239 return "string pool full";
246 pthread_mutex_lock(&
mutex);
248 pthread_mutex_unlock(&
mutex);
255 pthread_mutex_lock(&
mutex);
257 pthread_mutex_unlock(&
mutex);
273 int event_count_copy = 0;
274 int events_in_progress_copy = 1;
281 pthread_mutex_lock(&
mutex);
284 pthread_mutex_unlock(&
mutex);
294 while (events_in_progress_copy != 0) {
299 pthread_mutex_unlock(&
mutex);
301 for (i = 0; i < event_count_copy; i++) {
312 if (strlen(raw->
a_str) > 700) {
328 snprintf(id_buf,
ARRAY_SIZE(id_buf),
",\"id\":\"0x%08x\"", (uint32_t)(uintptr_t)raw->
id);
337 const char *
cat = raw->
cat;
342 int len = (int)strlen(
cat);
344 if (len > 255) len = 255;
345 for (i = 0; i < len; i++) {
346 temp[i] =
cat[i] ==
'\\' ?
'/' :
cat[i];
353 len = snprintf(linebuf,
ARRAY_SIZE(linebuf),
"%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64
",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}",
356 fwrite(linebuf, 1, len,
f);
360 free((
void*)raw->
a_str);
362 #ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
368 pthread_mutex_lock(&
mutex);
370 pthread_mutex_unlock(&
mutex);
381 pthread_mutex_lock(&
mutex);
383 pthread_mutex_unlock(&
mutex);
391 pthread_mutex_unlock(&
mutex);
401 #ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
402 const size_t category_len = strlen(
category);
403 ev->
cat = malloc(category_len + 1);
406 const size_t name_len = strlen(name);
407 ev->
name = malloc(name_len + 1);
408 strcpy(ev->
name, name);
419 memcpy(&x,
id,
sizeof(
double));
420 ev->
ts = (int64_t)(x * 1000000);
423 ev->
ts = (int64_t)(ts * 1000000);
438 pthread_mutex_lock(&
mutex);
440 pthread_mutex_unlock(&
mutex);
448 pthread_mutex_unlock(&
mutex);
458 #ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
459 const size_t category_len = strlen(
category);
460 ev->
cat = malloc(category_len + 1);
463 const size_t name_len = strlen(name);
464 ev->
name = malloc(name_len + 1);
465 strcpy(ev->
name, name);
473 ev->
ts = (int64_t)(ts * 1000000);