summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-11-10 01:01:38 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-11-10 01:01:38 +0900
commitde55d0048a1c2491c711fa4d5e4089dff5cee114 (patch)
treeb7bffa50173f5bf3a8c200f3f641439635fb5ad1
parentc4ad4ece028971f2a66c746d01973d1af8eee796 (diff)
evlog tool - read cpu usage and cpufreq info 7 display now
-rwxr-xr-xbuild.sh8
-rw-r--r--evlog.c518
-rw-r--r--evlog.edc24
3 files changed, 479 insertions, 71 deletions
diff --git a/build.sh b/build.sh
index 34c1c2e..6672418 100755
--- a/build.sh
+++ b/build.sh
@@ -1,5 +1,9 @@
1#!/bin/sh 1#!/bin/sh -e
2gcc evlog.c -o evlog `pkg-config --cflags --libs elementary` -g 2gcc \
3 evlog.c \
4 -o evlog \
5 -O2 -march=native -g \
6 `pkg-config --cflags --libs elementary`
3edje_cc evlog.edc -id ./img 7edje_cc evlog.edc -id ./img
4 8
5### minimal docs! 9### minimal docs!
diff --git a/evlog.c b/evlog.c
index 71a8c54..dc1118f 100644
--- a/evlog.c
+++ b/evlog.c
@@ -13,31 +13,55 @@ Evas_Object *zoom_slider;
13typedef struct _Evlog Evlog; 13typedef struct _Evlog Evlog;
14typedef struct _Evlog_Thread Evlog_Thread; 14typedef struct _Evlog_Thread Evlog_Thread;
15typedef struct _Evlog_Event Evlog_Event; 15typedef struct _Evlog_Event Evlog_Event;
16typedef struct _Evlog_Cpu_Use Evlog_Cpu_Use;
17typedef struct _Evlog_Cpu_Freq Evlog_Cpu_Freq;
16 18
17struct _Evlog 19struct _Evlog
18{ 20{
19 FILE *file; 21 FILE *file;
20 double first_timestamp; 22 double first_timestamp;
21 double last_timestamp; 23 double last_timestamp;
22 int state_num; 24 int state_uniq;
23 int thread_num; 25 int state_num;
24 Evlog_Event *states; 26 int cpucores;
25 Evlog_Thread *threads; 27 int cpumhzmax;
28 int thread_num;
29 int cpufreq_num;
30 Evlog_Event *states;
31 Evlog_Thread *threads;
32 Evlog_Cpu_Freq *cpufreqs;
33 char **state_uniq_str;
34 int cpumhzlast[64];
26}; 35};
27 36
28struct _Evlog_Event 37struct _Evlog_Event
29{ 38{
30 const char *event; 39 const char *event;
31// const char *detail; 40 const char *detail;
32 double timestamp; 41 double timestamp;
33 double latency; 42 double latency;
34}; 43};
35 44
45struct _Evlog_Cpu_Use
46{
47 int usage;
48 double timestamp;
49};
50
51struct _Evlog_Cpu_Freq
52{
53 int core;
54 int mhz;
55 double timestamp;
56};
57
36struct _Evlog_Thread 58struct _Evlog_Thread
37{ 59{
38 unsigned long long id; 60 unsigned long long id;
39 int event_num; 61 int event_num;
62 int cpuused_num;
40 Evlog_Event *events; 63 Evlog_Event *events;
64 Evlog_Cpu_Use *cpuused;
41}; 65};
42 66
43typedef struct 67typedef struct
@@ -48,6 +72,7 @@ typedef struct
48 Evas_Object *table; 72 Evas_Object *table;
49 struct { 73 struct {
50 Evas_Object *state; 74 Evas_Object *state;
75 Evas_Object *cpufreq;
51 Evas_Object **thread; 76 Evas_Object **thread;
52 Evas_Object *over; 77 Evas_Object *over;
53 } grid; 78 } grid;
@@ -56,7 +81,7 @@ typedef struct
56 Ecore_Job *job; 81 Ecore_Job *job;
57 Ecore_Thread *thread; 82 Ecore_Thread *thread;
58 double t0, t1, tmin; 83 double t0, t1, tmin;
59 Eina_Bool redo : 1; 84 volatile Eina_Bool redo;
60 Eina_List *remobjs; 85 Eina_List *remobjs;
61 } update; 86 } update;
62} Inf; 87} Inf;
@@ -65,11 +90,13 @@ typedef struct
65{ 90{
66 void *src; 91 void *src;
67 char *event; 92 char *event;
93 char *detail;
68 Evas_Object *obj; 94 Evas_Object *obj;
69 double t0, t1; 95 double t0, t1;
70 int n; 96 int n, n2;
71 int slot; 97 int slot;
72 Eina_Bool nuke : 1; 98 Eina_Bool nuke : 1;
99 Eina_Bool cpu_use : 1;
73} Event; 100} Event;
74 101
75#define ROUND_AMOUNT 1024 102#define ROUND_AMOUNT 1024
@@ -95,8 +122,19 @@ static void _fill_begin(Inf *inf);
95static void 122static void
96evlog_state_event_register(Evlog *evlog, Evlog_Event *ev) 123evlog_state_event_register(Evlog *evlog, Evlog_Event *ev)
97{ 124{
98 int n0, n; 125 int n0, n, j;
99 126
127 for (j = 0; j < evlog->state_uniq; j++)
128 {
129 if (!strcmp(evlog->state_uniq_str[j], ev->event + 1)) break;
130 }
131 if (j == evlog->state_uniq)
132 {
133 evlog->state_uniq++;
134 evlog->state_uniq_str = realloc(evlog->state_uniq_str,
135 evlog->state_uniq * sizeof(char *));
136 evlog->state_uniq_str[evlog->state_uniq - 1] = strdup(ev->event + 1);
137 }
100 n0 = evlog->state_num; 138 n0 = evlog->state_num;
101 evlog->state_num++; 139 evlog->state_num++;
102 n = evlog->state_num; 140 n = evlog->state_num;
@@ -110,6 +148,7 @@ evlog_state_event_register(Evlog *evlog, Evlog_Event *ev)
110 if (!tmp) 148 if (!tmp)
111 { 149 {
112 eina_stringshare_del(ev->event); 150 eina_stringshare_del(ev->event);
151 eina_stringshare_del(ev->detail);
113 return; 152 return;
114 } 153 }
115 evlog->states = tmp; 154 evlog->states = tmp;
@@ -135,6 +174,7 @@ evlog_thread_event_register(Evlog_Thread *th, Evlog_Event *ev)
135 if (!tmp) 174 if (!tmp)
136 { 175 {
137 eina_stringshare_del(ev->event); 176 eina_stringshare_del(ev->event);
177 eina_stringshare_del(ev->detail);
138 return; 178 return;
139 } 179 }
140 th->events = tmp; 180 th->events = tmp;
@@ -143,6 +183,85 @@ evlog_thread_event_register(Evlog_Thread *th, Evlog_Event *ev)
143} 183}
144 184
145static void 185static void
186evlog_thread_cpu_freq(Evlog *evlog, double timestamp, int core, int mhz)
187{
188 int n0, n;
189
190 n0 = evlog->cpufreq_num;
191 evlog->cpufreq_num++;
192 n = evlog->cpufreq_num;
193 n0 = ROUND(n0);
194 n = ROUND(n);
195 if (n != n0)
196 {
197 Evlog_Cpu_Freq *tmp;
198
199 tmp = realloc(evlog->cpufreqs, n * sizeof(Evlog_Cpu_Freq));
200 if (!tmp) return;
201 evlog->cpufreqs = tmp;
202 }
203 evlog->cpufreqs[evlog->cpufreq_num - 1].core = core;
204 evlog->cpufreqs[evlog->cpufreq_num - 1].mhz = mhz;
205 evlog->cpufreqs[evlog->cpufreq_num - 1].timestamp = timestamp;
206 if (evlog->cpucores <= core) evlog->cpucores = core + 1;
207 if (mhz > evlog->cpumhzmax) evlog->cpumhzmax = mhz;
208 evlog->cpumhzlast[core] = mhz;
209}
210
211static void
212evlog_thread_cpu_use(Evlog_Thread *th, double timestamp, int cpu)
213{
214 int n0, n;
215
216 n0 = th->cpuused_num;
217 th->cpuused_num++;
218 n = th->cpuused_num;
219 n0 = ROUND(n0);
220 n = ROUND(n);
221 if (n != n0)
222 {
223 Evlog_Cpu_Use *tmp;
224
225 tmp = realloc(th->cpuused, n * sizeof(Evlog_Cpu_Use));
226 if (!tmp) return;
227 th->cpuused = tmp;
228 }
229 th->cpuused[th->cpuused_num - 1].usage = cpu;
230 th->cpuused[th->cpuused_num - 1].timestamp = timestamp;
231}
232
233static Eina_Bool
234evlog_thread_push(Evlog *evlog, int slot, unsigned long long thread)
235{
236 Evlog_Thread *tmp;
237
238 if (slot < evlog->thread_num) return EINA_TRUE;
239
240 evlog->thread_num = slot + 1;
241 tmp = realloc(evlog->threads, evlog->thread_num * sizeof(Evlog_Thread));
242 if (!tmp) return EINA_FALSE;
243 evlog->threads = tmp;
244 evlog->threads[slot].id = thread;
245 evlog->threads[slot].event_num = 0;
246 evlog->threads[slot].events = NULL;
247 evlog->threads[slot].cpuused_num = 0;
248 evlog->threads[slot].cpuused = NULL;
249 return EINA_TRUE;
250}
251
252static int
253evlog_thread_slot_find(Evlog *evlog, unsigned long long thread)
254{
255 int i;
256
257 for (i = 0; i < evlog->thread_num; i++)
258 {
259 if (evlog->threads[i].id == thread) return i;
260 }
261 return i;
262}
263
264static void
146evlog_event_register(Evlog *evlog, unsigned long long thread, Evlog_Event *ev) 265evlog_event_register(Evlog *evlog, unsigned long long thread, Evlog_Event *ev)
147{ 266{
148 int i; 267 int i;
@@ -151,28 +270,36 @@ evlog_event_register(Evlog *evlog, unsigned long long thread, Evlog_Event *ev)
151 { 270 {
152 evlog_state_event_register(evlog, ev); 271 evlog_state_event_register(evlog, ev);
153 } 272 }
154 else 273 else if (ev->event[0] == '*')
155 { 274 {
156 for (i = 0; i < evlog->thread_num; i++) 275 if ((!strncmp(ev->event, "*CPUFREQ ", 9)) && (ev->detail))
157 { 276 {
158 if (evlog->threads[i].id == thread) break; 277 int cpu = atoi(ev->event + 9);
278 int freq = atoi(ev->detail);
279
280 evlog_thread_cpu_freq(evlog, ev->timestamp, cpu, freq);
159 } 281 }
160 if (i >= evlog->thread_num) 282 else if ((!strncmp(ev->event, "*CPUUSED ", 9)) && (ev->detail))
161 { 283 {
162 Evlog_Thread *tmp; 284 unsigned long long thcpu = atoll(ev->event + 9);
285 int cpu = atoi(ev->detail);
163 286
164 evlog->thread_num++; 287 i = evlog_thread_slot_find(evlog, thcpu);
165 tmp = realloc(evlog->threads, 288 if (!evlog_thread_push(evlog, i, thcpu)) return;
166 evlog->thread_num * sizeof(Evlog_Thread)); 289 for (int j = 0; j < i; j++) printf(" ");
167 if (!tmp) 290 evlog_thread_cpu_use(&(evlog->threads[i]), ev->timestamp, cpu);
168 { 291 }
169 eina_stringshare_del(ev->event); 292 eina_stringshare_del(ev->event);
170 return; 293 eina_stringshare_del(ev->detail);
171 } 294 }
172 evlog->threads = tmp; 295 else
173 evlog->threads[i].id = thread; 296 {
174 evlog->threads[i].event_num = 0; 297 i = evlog_thread_slot_find(evlog, thread);
175 evlog->threads[i].events = NULL; 298 if (!evlog_thread_push(evlog, i, thread))
299 {
300 eina_stringshare_del(ev->event);
301 eina_stringshare_del(ev->detail);
302 return;
176 } 303 }
177 evlog_thread_event_register(&(evlog->threads[i]), ev); 304 evlog_thread_event_register(&(evlog->threads[i]), ev);
178 } 305 }
@@ -198,6 +325,10 @@ evlog_event_read(Evlog *evlog, void *ptr, void *end)
198 { 325 {
199 Evlog_Event ev; 326 Evlog_Event ev;
200 ev.event = eina_stringshare_add(eventstr); 327 ev.event = eina_stringshare_add(eventstr);
328 if (detailstr)
329 ev.detail = eina_stringshare_add(detailstr);
330 else
331 ev.detail = NULL;
201 ev.timestamp = (item.srctim == 0.0) ? item.tim : item.srctim; 332 ev.timestamp = (item.srctim == 0.0) ? item.tim : item.srctim;
202 ev.latency = (item.srctim != 0.0) ? item.tim - item.srctim : 0.0; 333 ev.latency = (item.srctim != 0.0) ? item.tim - item.srctim : 0.0;
203 if (evlog->first_timestamp == 0.0) 334 if (evlog->first_timestamp == 0.0)
@@ -215,6 +346,7 @@ evlog_event_read(Evlog *evlog, void *ptr, void *end)
215static Eina_Bool 346static Eina_Bool
216evlog_block_read(Evlog *evlog) 347evlog_block_read(Evlog *evlog)
217{ 348{
349 int i;
218 unsigned int header[3]; 350 unsigned int header[3];
219 Eina_Bool bigendian = EINA_FALSE; 351 Eina_Bool bigendian = EINA_FALSE;
220 352
@@ -241,6 +373,11 @@ evlog_block_read(Evlog *evlog)
241 while ((ptr = evlog_event_read(evlog, ptr, end))); 373 while ((ptr = evlog_event_read(evlog, ptr, end)));
242 free(buf); 374 free(buf);
243 } 375 }
376 for (i = 0; i < evlog->cpucores; i++)
377 {
378 evlog_thread_cpu_freq(evlog, evlog->last_timestamp,
379 i, evlog->cpumhzlast[i]);
380 }
244 } 381 }
245 else 382 else
246 { 383 {
@@ -307,7 +444,7 @@ _create_log_states(Evas_Object *win, Evlog *evlog, Evas_Object *zoom)
307{ 444{
308 Evas_Object *o, *oo; 445 Evas_Object *o, *oo;
309 double len = evlog->last_timestamp - evlog->first_timestamp; 446 double len = evlog->last_timestamp - evlog->first_timestamp;
310 int i; 447 int i, j;
311 int h = 0; 448 int h = 0;
312 Eina_List *events = NULL, *l; 449 Eina_List *events = NULL, *l;
313 Event *ev; 450 Event *ev;
@@ -326,9 +463,17 @@ _create_log_states(Evas_Object *win, Evlog *evlog, Evas_Object *zoom)
326 { 463 {
327 ev->src = e; 464 ev->src = e;
328 ev->event = strdup(e->event + 1); 465 ev->event = strdup(e->event + 1);
466 if (e->detail) ev->detail = strdup(e->detail);
329 ev->t0 = t; 467 ev->t0 = t;
330 events = eina_list_append(events, ev); 468 events = eina_list_append(events, ev);
331 ev->n = eina_list_count(events) - 1; 469 for (j = 0; j < evlog->state_uniq; j++)
470 {
471 if (!strcmp(evlog->state_uniq_str[j], ev->event))
472 {
473 ev->n = j;
474 break;
475 }
476 }
332 if ((ev->n + 1) > h) h = ev->n + 1; 477 if ((ev->n + 1) > h) h = ev->n + 1;
333 } 478 }
334 } 479 }
@@ -340,6 +485,7 @@ _create_log_states(Evas_Object *win, Evlog *evlog, Evas_Object *zoom)
340 { 485 {
341 ev->t1 = t; 486 ev->t1 = t;
342 free(ev->event); 487 free(ev->event);
488 free(ev->detail);
343 free(ev); 489 free(ev);
344 events = eina_list_remove_list(events, l); 490 events = eina_list_remove_list(events, l);
345 break; 491 break;
@@ -352,6 +498,7 @@ _create_log_states(Evas_Object *win, Evlog *evlog, Evas_Object *zoom)
352 { 498 {
353 ev->t1 = t; 499 ev->t1 = t;
354 free(ev->event); 500 free(ev->event);
501 free(ev->detail);
355 free(ev); 502 free(ev);
356 } 503 }
357 504
@@ -379,6 +526,7 @@ _add_log_state(Inf *inf, Event *ev)
379 if (ev2->src == ev->src) 526 if (ev2->src == ev->src)
380 { 527 {
381 free(ev->event); 528 free(ev->event);
529 free(ev->detail);
382 free(ev); 530 free(ev);
383 return; 531 return;
384 } 532 }
@@ -387,13 +535,51 @@ _add_log_state(Inf *inf, Event *ev)
387} 535}
388 536
389static void 537static void
538_add_log_event(Inf *inf, Event *ev)
539{
540 Eina_List *l;
541 Event *ev2;
542
543 EINA_LIST_FOREACH(inf->objs, l, ev2)
544 {
545 if (ev2->src == ev->src)
546 {
547 free(ev->event);
548 free(ev->detail);
549 free(ev);
550 return;
551 }
552 }
553 inf->objs = eina_list_append(inf->objs, ev);
554}
555
556static Evas_Object *
557_create_cpufreq_states(Evas_Object *win, Evlog *evlog)
558{
559 Evas_Object *o, *oo;
560 double len = evlog->last_timestamp - evlog->first_timestamp;
561
562 o = elm_grid_add(win);
563 elm_grid_size_set(o, len * RES, evlog->cpucores);
564 evas_object_size_hint_min_set(o, 1, evlog->cpucores * 10);
565
566 oo = evas_object_rectangle_add(evas_object_evas_get(win));
567 evas_object_color_set(oo, 16, 16, 16, 255);
568 elm_grid_pack(o, oo, 0, 0, len * RES, evlog->cpucores * 4);
569 evas_object_show(oo);
570 return o;
571}
572
573static void
390_fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin) 574_fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin)
391{ 575{
392 int i; 576 int i, j;
393 Eina_List *events = NULL, *l; 577 Eina_List *events = NULL, *l;
394 Event *ev; 578 Event *ev;
579 char buf[256];
395 Evlog_Event *e; 580 Evlog_Event *e;
396 double t; 581 double t;
582 double *ct;
397 583
398 for (i = 0; i < evlog->state_num; i++) 584 for (i = 0; i < evlog->state_num; i++)
399 { 585 {
@@ -406,9 +592,17 @@ _fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin)
406 { 592 {
407 ev->src = e; 593 ev->src = e;
408 ev->event = strdup(e->event + 1); 594 ev->event = strdup(e->event + 1);
595 if (e->detail) ev->detail = strdup(e->detail);
409 ev->t0 = t; 596 ev->t0 = t;
410 events = eina_list_append(events, ev); 597 events = eina_list_append(events, ev);
411 ev->n = eina_list_count(events) - 1; 598 for (j = 0; j < evlog->state_uniq; j++)
599 {
600 if (!strcmp(evlog->state_uniq_str[j], ev->event))
601 {
602 ev->n = j;
603 break;
604 }
605 }
412 ev->slot = 0; 606 ev->slot = 0;
413 } 607 }
414 } 608 }
@@ -424,6 +618,7 @@ _fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin)
424 else 618 else
425 { 619 {
426 free(ev->event); 620 free(ev->event);
621 free(ev->detail);
427 free(ev); 622 free(ev);
428 } 623 }
429 events = eina_list_remove_list(events, l); 624 events = eina_list_remove_list(events, l);
@@ -432,6 +627,33 @@ _fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin)
432 } 627 }
433 } 628 }
434 } 629 }
630 ct = calloc(evlog->cpucores, sizeof(double));
631 for (i = 0; i < evlog->cpufreq_num; i++)
632 {
633 Evlog_Cpu_Freq *f = &(evlog->cpufreqs[i]);
634 double tt = f->timestamp - evlog->first_timestamp;
635
636 if (_can_see(t0, t1, tmin, ct[f->core], tt))
637 {
638 ev = calloc(1, sizeof(Event));
639 if (ev)
640 {
641 ev->src = f;
642 ev->event = strdup("*CPUFREQ");
643 snprintf(buf, sizeof(buf), "%iMHz", f->mhz);
644 ev->detail = strdup(buf);
645 ev->n = f->core;
646 ev->n2 = f->mhz;
647 ev->t0 = ct[f->core];
648 ev->t1 = tt;
649 ev->slot = -2;
650 _add_log_event(inf, ev);
651 }
652 }
653 ct[f->core] = tt;
654 }
655 free(ct);
656
435 t = evlog->last_timestamp - evlog->first_timestamp; 657 t = evlog->last_timestamp - evlog->first_timestamp;
436 EINA_LIST_FREE(events, ev) 658 EINA_LIST_FREE(events, ev)
437 { 659 {
@@ -441,6 +663,7 @@ _fill_log_states(Inf *inf, Evlog *evlog, double t0, double t1, double tmin)
441 else 663 else
442 { 664 {
443 free(ev->event); 665 free(ev->event);
666 free(ev->detail);
444 free(ev); 667 free(ev);
445 } 668 }
446 } 669 }
@@ -479,6 +702,7 @@ _create_log_thread(Evas_Object *win, Evlog *evlog, Evlog_Thread *th, int slot, E
479 ev->src = e; 702 ev->src = e;
480 stack = eina_list_append(stack, ev); 703 stack = eina_list_append(stack, ev);
481 ev->event = strdup(e->event + 1); 704 ev->event = strdup(e->event + 1);
705 if (e->detail) ev->detail = strdup(e->detail);
482 ev->t0 = t; 706 ev->t0 = t;
483 ev->n = eina_list_count(stack) - 1; 707 ev->n = eina_list_count(stack) - 1;
484 if ((ev->n + 1) > h) h = ev->n + 1; 708 if ((ev->n + 1) > h) h = ev->n + 1;
@@ -501,6 +725,9 @@ _create_log_thread(Evas_Object *win, Evlog *evlog, Evlog_Thread *th, int slot, E
501 } 725 }
502 else if (e->event[0] == '*') 726 else if (e->event[0] == '*')
503 { 727 {
728 // XXX: handle:
729 // 'CPUFREQ [X]' (CPU core) | [N] (Mhz)
730 // 'CPUUSED [X]' (Thread ID) | [N] (percent CPU used)
504 } 731 }
505 } 732 }
506 t = evlog->last_timestamp - evlog->first_timestamp; 733 t = evlog->last_timestamp - evlog->first_timestamp;
@@ -508,39 +735,22 @@ _create_log_thread(Evas_Object *win, Evlog *evlog, Evlog_Thread *th, int slot, E
508 { 735 {
509 ev->t1 = t; 736 ev->t1 = t;
510 free(ev->event); 737 free(ev->event);
738 free(ev->detail);
511 free(ev); 739 free(ev);
512 } 740 }
513 if (h < 1) h = 1; 741 if (h < 1) h = 1;
514 elm_grid_size_set(o, len * RES, h); 742 elm_grid_size_set(o, len * RES, (h * 2) + 1);
515 evas_object_size_hint_min_set(o, 1, h * 20); 743 evas_object_size_hint_min_set(o, 1, (h * 20) + 10);
516 744
517 oo = evas_object_rectangle_add(evas_object_evas_get(win)); 745 oo = evas_object_rectangle_add(evas_object_evas_get(win));
518 c = 32 + ((slot % 2) * 16); 746 c = 32 + ((slot % 2) * 16);
519 evas_object_color_set(oo, c, c, c, 255); 747 evas_object_color_set(oo, c, c, c, 255);
520 elm_grid_pack(o, oo, 0, 0, len * RES, h); 748 elm_grid_pack(o, oo, 0, 0, len * RES, (h * 2) + 1);
521 evas_object_show(oo); 749 evas_object_show(oo);
522 return o; 750 return o;
523} 751}
524 752
525static void 753static void
526_add_log_event(Inf *inf, Event *ev)
527{
528 Eina_List *l;
529 Event *ev2;
530
531 EINA_LIST_FOREACH(inf->objs, l, ev2)
532 {
533 if (ev2->src == ev->src)
534 {
535 free(ev->event);
536 free(ev);
537 return;
538 }
539 }
540 inf->objs = eina_list_append(inf->objs, ev);
541}
542
543static void
544_fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0, double t1, double tmin) 754_fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0, double t1, double tmin)
545{ 755{
546 Eina_List *stack = NULL, *l; 756 Eina_List *stack = NULL, *l;
@@ -549,6 +759,8 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
549 int h = 0; 759 int h = 0;
550 Evlog_Event *e; 760 Evlog_Event *e;
551 double t; 761 double t;
762 char buf[256];
763 void *psrc;
552 764
553 for (i = 0; i < th->event_num; i++) 765 for (i = 0; i < th->event_num; i++)
554 { 766 {
@@ -562,6 +774,7 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
562 ev->src = e; 774 ev->src = e;
563 stack = eina_list_append(stack, ev); 775 stack = eina_list_append(stack, ev);
564 ev->event = strdup(e->event + 1); 776 ev->event = strdup(e->event + 1);
777 if (e->detail) ev->detail = strdup(e->detail);
565 ev->t0 = t; 778 ev->t0 = t;
566 ev->n = eina_list_count(stack) - 1; 779 ev->n = eina_list_count(stack) - 1;
567 ev->slot = slot; 780 ev->slot = slot;
@@ -580,6 +793,7 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
580 else 793 else
581 { 794 {
582 free(ev->event); 795 free(ev->event);
796 free(ev->detail);
583 free(ev); 797 free(ev);
584 } 798 }
585 stack = eina_list_remove_list(stack, l); 799 stack = eina_list_remove_list(stack, l);
@@ -592,6 +806,7 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
592 { 806 {
593 ev->src = e; 807 ev->src = e;
594 ev->event = strdup(e->event + 1); 808 ev->event = strdup(e->event + 1);
809 if (e->detail) ev->detail = strdup(e->detail);
595 ev->t0 = t; 810 ev->t0 = t;
596 ev->t1 = -1.0; 811 ev->t1 = -1.0;
597 ev->n = 0; 812 ev->n = 0;
@@ -601,13 +816,17 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
601 else 816 else
602 { 817 {
603 free(ev->event); 818 free(ev->event);
819 free(ev->detail);
604 free(ev); 820 free(ev);
605 } 821 }
606 } 822 }
607 } 823 }
608 else if (e->event[0] == '*') 824// else if (e->event[0] == '*')
609 { 825// {
610 } 826 // XXX: handle:
827 // 'CPUFREQ [X]' (CPU core) | [N] (Mhz)
828 // 'CPUUSED [X]' (Thread ID) | [N] (percent CPU used)
829// }
611 } 830 }
612 t = evlog->last_timestamp - evlog->first_timestamp; 831 t = evlog->last_timestamp - evlog->first_timestamp;
613 EINA_LIST_FREE(stack, ev) 832 EINA_LIST_FREE(stack, ev)
@@ -618,9 +837,34 @@ _fill_log_thread(Inf *inf, Evlog *evlog, Evlog_Thread *th, int slot, double t0,
618 else 837 else
619 { 838 {
620 free(ev->event); 839 free(ev->event);
840 free(ev->detail);
621 free(ev); 841 free(ev);
622 } 842 }
623 } 843 }
844 t = 0.0;
845 for (i = 0; i < th->cpuused_num; i++)
846 {
847 double tt = th->cpuused[i].timestamp - evlog->first_timestamp;
848
849 if (_can_see(t0, t1, tmin, t, tt))
850 {
851 ev = calloc(1, sizeof(Event));
852 if (ev)
853 {
854 ev->src = &(th->cpuused[i]);
855 ev->event = strdup("*CPUUSED");
856 snprintf(buf, sizeof(buf), "%i%%", th->cpuused[i].usage);
857 ev->detail = strdup(buf);
858 ev->t0 = t;
859 ev->t1 = tt;
860 ev->n = th->cpuused[i].usage;
861 ev->slot = slot;
862 ev->cpu_use = 1;
863 _add_log_event(inf, ev);
864 }
865 }
866 t = tt;
867 }
624} 868}
625 869
626static void 870static void
@@ -659,6 +903,20 @@ _fill_log_table(Evas_Object *win, Evas_Object *tb, Evlog *evlog, Evas_Object *zo
659 int i, y = 0; 903 int i, y = 0;
660 904
661 o = elm_label_add(win); 905 o = elm_label_add(win);
906 elm_object_text_set(o, "<b>CPU FREQ</b>");
907 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
908 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
909 elm_table_pack(tb, o, 0, y, 1, 1);
910 evas_object_show(o);
911
912 o = _create_cpufreq_states(win, evlog);
913 inf->grid.cpufreq = o;
914 evas_object_size_hint_weight_set(o, 0.0, 0.0);
915 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
916 elm_table_pack(tb, o, 2, y++, 1, 1);
917 evas_object_show(o);
918
919 o = elm_label_add(win);
662 elm_object_text_set(o, "<b>STATES</b>"); 920 elm_object_text_set(o, "<b>STATES</b>");
663 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); 921 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
664 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); 922 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
@@ -750,7 +1008,8 @@ static Evas_Object *
750_add_log_state_object(Evas_Object *win, Evas_Object *grid, Event *ev) 1008_add_log_state_object(Evas_Object *win, Evas_Object *grid, Event *ev)
751{ 1009{
752 Evas_Object *o, *oe; 1010 Evas_Object *o, *oe;
753 int col[4] = {255, 255, 255, 255}, i; 1011 unsigned char col[4] = {255, 255, 255, 255};
1012 int i;
754 char *s; 1013 char *s;
755 char buf[512]; 1014 char buf[512];
756 1015
@@ -763,13 +1022,30 @@ _add_log_state_object(Evas_Object *win, Evas_Object *grid, Event *ev)
763 col[i % 3] ^= *s; 1022 col[i % 3] ^= *s;
764 i++; 1023 i++;
765 } 1024 }
1025 if (ev->detail)
1026 {
1027 for (s = ev->detail; *s; s++)
1028 {
1029 col[i % 3] ^= ((*s << 3) | (i << 1));
1030 i++;
1031 }
1032 }
766 edje_object_color_class_set(oe, "state", 1033 edje_object_color_class_set(oe, "state",
767 col[0] / 2, col[1] / 2, col[2] / 2, col[3], 1034 col[0] / 2, col[1] / 2, col[2] / 2, col[3],
768 255, 255, 255, 255, 1035 255, 255, 255, 255,
769 255, 255, 255, 255); 1036 255, 255, 255, 255);
770 edje_object_part_text_set(oe, "text", ev->event); 1037 if (ev->detail)
1038 {
1039 snprintf(buf, sizeof(buf), "%s (%s)", ev->event, ev->detail);
1040 edje_object_part_text_set(oe, "text", buf);
1041 }
1042 else
1043 edje_object_part_text_set(oe, "text", ev->event);
771 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1); 1044 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1);
772 snprintf(buf, sizeof(buf), "%s - %1.9fms ~ %1.9fms", ev->event, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0); 1045 if (ev->detail)
1046 snprintf(buf, sizeof(buf), "%s (%s) - %1.5fms [%1.5fms]", ev->event, ev->detail, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
1047 else
1048 snprintf(buf, sizeof(buf), "%s - %1.5fms [%1.5fms]", ev->event, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
773 elm_object_tooltip_text_set(o, buf); 1049 elm_object_tooltip_text_set(o, buf);
774 evas_object_show(o); 1050 evas_object_show(o);
775 return o; 1051 return o;
@@ -796,9 +1072,56 @@ _add_log_event_object(Evas_Object *win, Evas_Object *grid, Event *ev)
796 col[0] / 2, col[1] / 2, col[2] / 2, col[3], 1072 col[0] / 2, col[1] / 2, col[2] / 2, col[3],
797 255, 255, 255, 255, 1073 255, 255, 255, 255,
798 255, 255, 255, 255); 1074 255, 255, 255, 255);
799 edje_object_part_text_set(oe, "text", ev->event); 1075 if (ev->detail)
800 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1); 1076 {
801 snprintf(buf, sizeof(buf), "%s - %1.9fms ~ %1.9fms", ev->event, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0); 1077 snprintf(buf, sizeof(buf), "%s (%s)", ev->event, ev->detail);
1078 edje_object_part_text_set(oe, "text", buf);
1079 }
1080 else
1081 edje_object_part_text_set(oe, "text", ev->event);
1082 elm_grid_pack(grid, o, ev->t0 * RES, 1 + (ev->n * 2), (ev->t1 - ev->t0) * RES, 2);
1083 if (ev->detail)
1084 snprintf(buf, sizeof(buf), "%s (%s) - %1.5fms [%1.5fms]", ev->event, ev->detail, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
1085 else
1086 snprintf(buf, sizeof(buf), "%s - %1.5fms [%1.5fms]", ev->event, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
1087 elm_object_tooltip_text_set(o, buf);
1088 evas_object_show(o);
1089 return o;
1090}
1091
1092static Evas_Object *
1093_add_log_cpuused_object(Evas_Object *win, Evas_Object *grid, Event *ev)
1094{
1095 Evas_Object *o, *oe;
1096 int col[4] = {0, 0, 0, 255}, i;
1097 char buf[512];
1098
1099 o = elm_layout_add(win);
1100 oe = elm_layout_edje_get(o);
1101 elm_layout_file_set(o, "./evlog.edj", "cpuused");
1102 i = 0;
1103 if (ev->n <= 33)
1104 {
1105 col[0] = (ev->n * 255) / 33;
1106 }
1107 else if (ev->n <= 67)
1108 {
1109 col[0] = 255;
1110 col[1] = ((ev->n - 33) * 255) / 24;
1111 }
1112 else
1113 {
1114 col[0] = 255;
1115 col[1] = 255;
1116 col[2] = ((ev->n - 67) * 255) / 33;
1117 }
1118 edje_object_color_class_set(oe, "range",
1119 col[0], col[1], col[2], col[3],
1120 255, 255, 255, 255,
1121 255, 255, 255, 255);
1122 elm_grid_pack(grid, o, ev->t0 * RES, 0, (ev->t1 - ev->t0) * RES, 1);
1123 if (ev->detail)
1124 snprintf(buf, sizeof(buf), "%i%% - %1.5fms [%1.5fms]", ev->n, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
802 elm_object_tooltip_text_set(o, buf); 1125 elm_object_tooltip_text_set(o, buf);
803 evas_object_show(o); 1126 evas_object_show(o);
804 return o; 1127 return o;
@@ -814,7 +1137,47 @@ _add_log_frame_object(Evas_Object *win, Evas_Object *grid, Event *ev)
814 oe = elm_layout_edje_get(o); 1137 oe = elm_layout_edje_get(o);
815 elm_layout_file_set(o, "./evlog.edj", "frame"); 1138 elm_layout_file_set(o, "./evlog.edj", "frame");
816 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1); 1139 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1);
817 snprintf(buf, sizeof(buf), "%s - %1.9fms", ev->event, ev->t0 * 1000.0); 1140 snprintf(buf, sizeof(buf), "%s - %1.5fms", ev->event, ev->t0 * 1000.0);
1141 elm_object_tooltip_text_set(o, buf);
1142 evas_object_show(o);
1143 return o;
1144}
1145
1146static Evas_Object *
1147_add_log_cpufreq_object(Evas_Object *win, Evas_Object *grid, Event *ev, int mhzmax)
1148{
1149 Evas_Object *o, *oe;
1150 int col[4] = {0, 0, 0, 255}, i, n;
1151 char buf[512];
1152
1153 o = elm_layout_add(win);
1154 oe = elm_layout_edje_get(o);
1155 elm_layout_file_set(o, "./evlog.edj", "cpufreq");
1156 i = 0;
1157
1158 n = (ev->n2 * 100) / mhzmax;
1159 if (n <= 33)
1160 {
1161 col[0] = (n * 255) / 33;
1162 }
1163 else if (n <= 67)
1164 {
1165 col[0] = 255;
1166 col[1] = ((n - 33) * 255) / 24;
1167 }
1168 else
1169 {
1170 col[0] = 255;
1171 col[1] = 255;
1172 col[2] = ((n - 67) * 255) / 33;
1173 }
1174 edje_object_color_class_set(oe, "range",
1175 col[0], col[1], col[2], col[3],
1176 255, 255, 255, 255,
1177 255, 255, 255, 255);
1178 elm_grid_pack(grid, o, ev->t0 * RES, ev->n, (ev->t1 - ev->t0) * RES, 1);
1179 if (ev->detail)
1180 snprintf(buf, sizeof(buf), "%iMHz - %1.5fms [%1.5fms]", ev->n2, ev->t0 * 1000.0, (ev->t1 - ev->t0) * 1000.0);
818 elm_object_tooltip_text_set(o, buf); 1181 elm_object_tooltip_text_set(o, buf);
819 evas_object_show(o); 1182 evas_object_show(o);
820 return o; 1183 return o;
@@ -842,9 +1205,14 @@ _cb_fill_end(void *data, Ecore_Thread *thread)
842 } 1205 }
843 else if (ev->slot > 0) // thread 1206 else if (ev->slot > 0) // thread
844 { 1207 {
845 o = _add_log_event_object(inf->win, 1208 if (!strcmp(ev->event, "*CPUUSED"))
846 inf->grid.thread[ev->slot - 1], 1209 o = _add_log_cpuused_object(inf->win,
847 ev); 1210 inf->grid.thread[ev->slot - 1],
1211 ev);
1212 else
1213 o = _add_log_event_object(inf->win,
1214 inf->grid.thread[ev->slot - 1],
1215 ev);
848 ev->obj = o; 1216 ev->obj = o;
849 } 1217 }
850 else if (ev->slot == -1) // frames 1218 else if (ev->slot == -1) // frames
@@ -857,6 +1225,17 @@ _cb_fill_end(void *data, Ecore_Thread *thread)
857 ev->obj = o; 1225 ev->obj = o;
858 } 1226 }
859 } 1227 }
1228 else if (ev->slot == -2) // cpufreq
1229 {
1230 if (!strcmp(ev->event, "*CPUFREQ"))
1231 {
1232 o = _add_log_cpufreq_object(inf->win,
1233 inf->grid.cpufreq,
1234 ev,
1235 inf->evlog->cpumhzmax);
1236 ev->obj = o;
1237 }
1238 }
860 } 1239 }
861 } 1240 }
862 EINA_LIST_FREE(inf->update.remobjs, ev) 1241 EINA_LIST_FREE(inf->update.remobjs, ev)
@@ -864,6 +1243,7 @@ _cb_fill_end(void *data, Ecore_Thread *thread)
864 inf->objs = eina_list_remove(inf->objs, ev); 1243 inf->objs = eina_list_remove(inf->objs, ev);
865 if (ev->obj) evas_object_del(ev->obj); 1244 if (ev->obj) evas_object_del(ev->obj);
866 free(ev->event); 1245 free(ev->event);
1246 free(ev->detail);
867 free(ev); 1247 free(ev);
868 } 1248 }
869 if (inf->update.redo) 1249 if (inf->update.redo)
@@ -913,7 +1293,7 @@ _fill_begin(Inf *inf)
913 t0 = inf->evlog->first_timestamp; 1293 t0 = inf->evlog->first_timestamp;
914 t1 = inf->evlog->last_timestamp; 1294 t1 = inf->evlog->last_timestamp;
915 1295
916 inf->update.tmin = (1.0 * (double)gw) / ((double)w * RES); 1296 inf->update.tmin = (3.0 * (double)gw) / ((double)w * RES);
917 1297
918 wx -= 100; 1298 wx -= 100;
919 ww += 200; 1299 ww += 200;
@@ -1037,7 +1417,7 @@ elm_main(int argc, char **argv)
1037 evas_object_data_set(o, "inf", inf); 1417 evas_object_data_set(o, "inf", inf);
1038 elm_slider_min_max_set(o, 1.0, 1000.0); 1418 elm_slider_min_max_set(o, 1.0, 1000.0);
1039 elm_slider_step_set(o, 0.1); 1419 elm_slider_step_set(o, 0.1);
1040 elm_slider_value_set(o, 20.0); 1420 elm_slider_value_set(o, 50.0);
1041 elm_object_text_set(o, "Zoom"); 1421 elm_object_text_set(o, "Zoom");
1042 elm_slider_unit_format_set(o, "%1.1f"); 1422 elm_slider_unit_format_set(o, "%1.1f");
1043 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); 1423 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
@@ -1051,7 +1431,7 @@ elm_main(int argc, char **argv)
1051 elm_box_pack_end(box, o); 1431 elm_box_pack_end(box, o);
1052 evas_object_show(o); 1432 evas_object_show(o);
1053 1433
1054 evas_object_resize(win, 620, 400); 1434 evas_object_resize(win, 1200, 400);
1055 1435
1056 evas_object_show(win); 1436 evas_object_show(win);
1057 elm_run(); 1437 elm_run();
diff --git a/evlog.edc b/evlog.edc
index f480ee4..224259b 100644
--- a/evlog.edc
+++ b/evlog.edc
@@ -29,6 +29,30 @@ collections {
29 } 29 }
30 } 30 }
31 31
32 group { name: "cpufreq";
33 parts {
34 part { name: "bg"; type: RECT;
35 description { state: "default" 0.0;
36// rel1.offset: 1 1;
37// rel2.offset: -2 -2;
38 color_class: "range";
39 }
40 }
41 }
42 }
43
44 group { name: "cpuused";
45 parts {
46 part { name: "bg"; type: RECT;
47 description { state: "default" 0.0;
48// rel1.offset: 1 1;
49// rel2.offset: -2 -2;
50 color_class: "range";
51 }
52 }
53 }
54 }
55
32 images.image: "diagonal_stripes.png" COMP; 56 images.image: "diagonal_stripes.png" COMP;
33 57
34 group { name: "state"; 58 group { name: "state";