summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Biliavskyi <m.biliavskyi@samsung.com>2017-11-08 17:58:28 +0200
committerMykyta Biliavskyi <m.biliavskyi@samsung.com>2017-11-08 17:58:28 +0200
commitc9e546daafb5f8f6fb944eb97edfd51658da3bb0 (patch)
tree59bfa8ab9d25f5df5e9f8e5fb49d2aeb16d7496d
parent08696a90d3f001e4054a785b593fc2af6fdb8617 (diff)
parent36645822ac75de611b2418dca16c594ad61b6722 (diff)
Merge branch 'master' into devs/nikawhite/objectsreusedevs/nikawhite/objectsreuse
-rw-r--r--docs/requirements45
-rw-r--r--src/lib/filters.c65
-rw-r--r--src/lib/helper.h57
-rw-r--r--src/lib/interval_fill.c200
-rw-r--r--src/lib/logload.c734
-rw-r--r--src/lib/tasks/cpuuse.c1
-rw-r--r--src/lib/ui.c378
-rw-r--r--src/lib/ui_private.h1
-rw-r--r--tool/efl_event_log_parse.py54
9 files changed, 998 insertions, 537 deletions
diff --git a/docs/requirements b/docs/requirements
new file mode 100644
index 0000000..d6057a3
--- /dev/null
+++ b/docs/requirements
@@ -0,0 +1,45 @@
1 • Understandable
2 • Clear
3 • Verifiable
4 • Describes the capabilities the application must provide
5
6Requirements
7 1. Load efl_debug log file.
8 Should provide ability to load log file, which is result of efl_debug infra processing.
9 Verify? -> Display loaded data on UI. Whole data from log file should be available to see in user interface.
10 2. Processing data from efl_debugd.
11 Should provide ability to process data from efl_debug infra through clouseau application.
12 Verify? -> Display up-to-date data on the UI. Received data from stream should be available to see in user interface.
13 a. Should be able to be used inside Clouseau
14 Verify? -> Load extension into Clouseau.
15 3. Should support visual representation of various event types. Different types should have the different UI representation.
16 a. Cpu frequency.
17 Verify?
18 b. Cpu load.
19 c. User thread event
20 4. Navigation through available data. (loaded from log file or received from stream)
21 Should provide tools for easy access to the different part of available data.
22 a. Global map navigation.
23 i. Should provide UI representation of whole loaded data. Data should be approximated for provide useful information.
24 ii. Should indicate currently displayed time range interval.
25 iii. Ability change to custom time range interval in time borders of loaded data. (For example: select are on navigation map by using mouse)
26 iv. Ability to choose what data will be displayed. (For example Cpu freq bar could be hide)
27 b. Time range interval navigation
28 i. The time interval should be splited into smaller intervals by visual marks.
29 Vertical lines should have distance from one to another by configurable value (default value is 140px).
30 Lines should be aligned to rounded time (rounding depends from time interval duration).
31 It is mean that the vertical line displayed at time 431ms against 430.2ms.
32 ii. Time labels divides into two groups: the major values on given time range interval should have a bold font and contrast color.
33 For example on time range interval [1..3] seconds the 1, 2 and 3 second timemarks should be emphasized by bold font and contrast color.
34 The smaller chunks of time should be signed with regular font and color, so the time labels such as 200, 300, 400,etc ms should have
35 regular font and color.
36 The timemarks should be always visible.
37 iii. The times of begin and end of the displayed interval should be displayed.
38 iv. UI controls for change interval to the same duration in left or right direction.
39 v. Ability to drag interval by combination of Ctrl + mouse move.
40 vi. Ability to change zoom of displayed interval by combination Ctrl+Mouse wheel up/down.
41 vii. Ability to select smaller interval inside already displayed time interval through selecting area by mouse click + mouse move.
42 viii. Ability to change time interval by shortcuts Ctrl+ arrow left/right
43 ix. Double click on event object should change displayed interval accordingly to timing of clicked event.
44 x. Should be possible to scroll area in such way that any event could be accessible.
45 xi. Ability to hide chosen row of displayed events.
diff --git a/src/lib/filters.c b/src/lib/filters.c
index 2f5e135..401fe94 100644
--- a/src/lib/filters.c
+++ b/src/lib/filters.c
@@ -282,17 +282,26 @@ rule_apply(In_Thread_Data *thd, Rule *rule)
282 Event_Info *ei, *_ei; 282 Event_Info *ei, *_ei;
283 EINA_LIST_FOREACH(rule->state_events, l, ei) 283 EINA_LIST_FOREACH(rule->state_events, l, ei)
284 { 284 {
285 _ei = eina_hash_find(thd->states, ei->common.name); 285 eina_rwlock_take_read(&thd->state_events.lock);
286 _ei = eina_hash_find(thd->state_events.hash, ei->common.name);
287 eina_rwlock_release(&thd->state_events.lock);
288
286 if (_ei) _ei->common.filtered = ei->common.filtered; 289 if (_ei) _ei->common.filtered = ei->common.filtered;
287 } 290 }
288 EINA_LIST_FOREACH(rule->thread_events, l, ei) 291 EINA_LIST_FOREACH(rule->thread_events, l, ei)
289 { 292 {
290 _ei = eina_hash_find(thd->thread_events, ei->common.name); 293 eina_rwlock_take_read(&thd->thread_events.lock);
294 _ei = eina_hash_find(thd->thread_events.hash, ei->common.name);
295 eina_rwlock_release(&thd->thread_events.lock);
296
291 if (_ei) _ei->common.filtered = ei->common.filtered; 297 if (_ei) _ei->common.filtered = ei->common.filtered;
292 } 298 }
293 EINA_LIST_FOREACH(rule->single_events, l, ei) 299 EINA_LIST_FOREACH(rule->single_events, l, ei)
294 { 300 {
295 _ei = eina_hash_find(thd->single_events, ei->common.name); 301 eina_rwlock_take_read(&thd->single_events.lock);
302 _ei = eina_hash_find(thd->single_events.hash, ei->common.name);
303 eina_rwlock_release(&thd->single_events.lock);
304
296 if (_ei) _ei->common.filtered = ei->common.filtered; 305 if (_ei) _ei->common.filtered = ei->common.filtered;
297 } 306 }
298} 307}
@@ -616,8 +625,19 @@ _all_events_status_change_cb(void *data, Evas_Object *obj EINA_UNUSED, void *eve
616 { 625 {
617 In_Thread_Data *thd; 626 In_Thread_Data *thd;
618 evas_object_smart_callback_call(filter_elems.parent_win, "in,thread,data,request", &thd); 627 evas_object_smart_callback_call(filter_elems.parent_win, "in,thread,data,request", &thd);
619 eina_hash_foreach(thd->states, _hash_all_change_cb, &status); 628
620 eina_hash_foreach(thd->thread_events, _hash_all_change_cb, &status); 629 eina_rwlock_take_read(&thd->state_events.lock);
630 eina_hash_foreach(thd->state_events.hash, _hash_all_change_cb, &status);
631 eina_rwlock_release(&thd->state_events.lock);
632
633 eina_rwlock_take_read(&thd->thread_events.lock);
634 eina_hash_foreach(thd->thread_events.hash, _hash_all_change_cb, &status);
635 eina_rwlock_release(&thd->thread_events.lock);
636
637 eina_rwlock_take_read(&thd->single_events.lock);
638 eina_hash_foreach(thd->single_events.hash, _hash_all_change_cb, &status);
639 eina_rwlock_release(&thd->single_events.lock);
640
621 thd->cpufreq_filtered = status; 641 thd->cpufreq_filtered = status;
622 thd->cpuuse_filtered = status; 642 thd->cpuuse_filtered = status;
623 } 643 }
@@ -658,27 +678,33 @@ _current_log_filter_list_create(void *data EINA_UNUSED, Evas_Object *obj EINA_UN
658 elm_genlist_item_append(filter_elems.filter_list, _itc_cur_log_cpu_use, thd, 678 elm_genlist_item_append(filter_elems.filter_list, _itc_cur_log_cpu_use, thd,
659 group_parent, ELM_GENLIST_ITEM_NONE, NULL, NULL); 679 group_parent, ELM_GENLIST_ITEM_NONE, NULL, NULL);
660 680
661 if (eina_hash_population(thd->states)) 681
682 eina_rwlock_take_read(&thd->state_events.lock);
683 if (eina_hash_population(thd->state_events.hash))
662 group_parent = elm_genlist_item_append(filter_elems.filter_list, 684 group_parent = elm_genlist_item_append(filter_elems.filter_list,
663 _itc_cur_log_group, _("State events"), 685 _itc_cur_log_group, _("State events"),
664 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL); 686 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
665 evas_object_data_set(filter_elems.filter_list, "state_parent", group_parent); 687 evas_object_data_set(filter_elems.filter_list, "state_parent", group_parent);
666 eina_hash_foreach(thd->states, _log_event_genlist_item_create_cb, group_parent); 688 eina_hash_foreach(thd->state_events.hash, _log_event_genlist_item_create_cb, group_parent);
689 eina_rwlock_release(&thd->state_events.lock);
667 690
668 if (eina_hash_population(thd->single_events)) 691 eina_rwlock_take_read(&thd->single_events.lock);
692 if (eina_hash_population(thd->single_events.hash))
669 group_parent = elm_genlist_item_append(filter_elems.filter_list, 693 group_parent = elm_genlist_item_append(filter_elems.filter_list,
670 _itc_cur_log_group, _("Single events"), 694 _itc_cur_log_group, _("Single events"),
671 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL); 695 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
672 evas_object_data_set(filter_elems.filter_list, "single_parent", group_parent); 696 evas_object_data_set(filter_elems.filter_list, "single_parent", group_parent);
673 eina_hash_foreach(thd->single_events, _log_event_genlist_item_create_cb, group_parent); 697 eina_hash_foreach(thd->single_events.hash, _log_event_genlist_item_create_cb, group_parent);
698 eina_rwlock_release(&thd->single_events.lock);
674 699
675 if (eina_hash_population(thd->thread_events)) 700 eina_rwlock_take_read(&thd->thread_events.lock);
701 if (eina_hash_population(thd->thread_events.hash))
676 group_parent = elm_genlist_item_append(filter_elems.filter_list, 702 group_parent = elm_genlist_item_append(filter_elems.filter_list,
677 _itc_cur_log_group, _("Thread events"), 703 _itc_cur_log_group, _("Thread events"),
678 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL); 704 NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
679 evas_object_data_set(filter_elems.filter_list, "thread_parent", group_parent); 705 evas_object_data_set(filter_elems.filter_list, "thread_parent", group_parent);
680 706 eina_hash_foreach(thd->thread_events.hash, _log_event_genlist_item_create_cb, group_parent);
681 eina_hash_foreach(thd->thread_events, _log_event_genlist_item_create_cb, group_parent); 707 eina_rwlock_release(&thd->thread_events.lock);
682} 708}
683 709
684static void 710static void
@@ -753,9 +779,18 @@ _rule_copy_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_
753 { 779 {
754 In_Thread_Data *thd; 780 In_Thread_Data *thd;
755 evas_object_smart_callback_call(filter_elems.parent_win, "in,thread,data,request", &thd); 781 evas_object_smart_callback_call(filter_elems.parent_win, "in,thread,data,request", &thd);
756 eina_hash_foreach(thd->states, _log_events_to_rule_copy_cb, &new_rule->state_events); 782
757 eina_hash_foreach(thd->thread_events, _log_events_to_rule_copy_cb, &new_rule->thread_events); 783 eina_rwlock_take_read(&thd->state_events.lock);
758 eina_hash_foreach(thd->single_events, _log_events_to_rule_copy_cb, &new_rule->single_events); 784 eina_hash_foreach(thd->state_events.hash, _log_events_to_rule_copy_cb, &new_rule->state_events);
785 eina_rwlock_release(&thd->state_events.lock);
786
787 eina_rwlock_take_read(&thd->thread_events.lock);
788 eina_hash_foreach(thd->thread_events.hash, _log_events_to_rule_copy_cb, &new_rule->thread_events);
789 eina_rwlock_release(&thd->thread_events.lock);
790
791 eina_rwlock_take_read(&thd->single_events.lock);
792 eina_hash_foreach(thd->single_events.hash, _log_events_to_rule_copy_cb, &new_rule->single_events);
793 eina_rwlock_release(&thd->single_events.lock);
759 } 794 }
760} 795}
761 796
diff --git a/src/lib/helper.h b/src/lib/helper.h
index 723b416..a7e37fb 100644
--- a/src/lib/helper.h
+++ b/src/lib/helper.h
@@ -164,7 +164,10 @@ struct _Log_Thread
164 int cur_events; 164 int cur_events;
165 int last_cpu; 165 int last_cpu;
166 166
167 Eina_Array *cpuused_events; 167 struct {
168 Eina_Array *data;
169 Eina_RWLock lock;
170 } cpuused_events;
168}; 171};
169 172
170struct _Log_Cpu_Common 173struct _Log_Cpu_Common
@@ -199,7 +202,6 @@ struct _Active_Period
199 202
200struct _Event_Offsets 203struct _Event_Offsets
201{ 204{
202 char *name;
203 int thread_slot; 205 int thread_slot;
204 unsigned int grid_slot; 206 unsigned int grid_slot;
205 unsigned long long obj; 207 unsigned long long obj;
@@ -212,8 +214,14 @@ struct _Event_Offsets
212 214
213struct _Offsets 215struct _Offsets
214{ 216{
215 Eina_Array *cpufreqs; 217 struct {
216 Eina_Array *threads; 218 Eina_Array *data;
219 Eina_RWLock lock;
220 } cpufreqs;
221 struct {
222 Eina_Array *data;
223 Eina_RWLock lock;
224 } threads;
217}; 225};
218 226
219typedef struct _Log_Event Log_Event; 227typedef struct _Log_Event Log_Event;
@@ -290,44 +298,65 @@ struct _Event_Info
290struct _Event_Info_State 298struct _Event_Info_State
291{ 299{
292 Event_Info_Common common; 300 Event_Info_Common common;
293 int grid_slot; /**< y virtual coordinate of grid. Only for state events. */ 301 int grid_slot; /**< y virtual coordinate of grid. Only for state events. */
294 Eina_Array *pointers; /**< array contain Event_Offsets for all events with given name */ 302 struct {
303 Eina_Array *data; /**< array contain Event_Offsets for all events with given name */
304 Eina_RWLock lock;
305 } state_events;
295}; 306};
296 307
297struct _Event_Info_Thread 308struct _Event_Info_Thread
298{ 309{
299 Event_Info_Common common; 310 Event_Info_Common common;
300 Eina_Array *threads; 311 struct {
312 Eina_Array *data;
313 Eina_RWLock lock;
314 } threads;
301}; 315};
302 316
303struct _Event_Info_Single 317struct _Event_Info_Single
304{ 318{
305 Event_Info_Common common; 319 Event_Info_Common common;
306 Eina_Bool error; 320 Eina_Bool error;
307 Eina_Array *threads; 321 struct {
322 Eina_Array *data;
323 Eina_RWLock lock;
324 } threads;
308}; 325};
309 326
310typedef struct 327typedef struct
311{ 328{
312 Log_Thread *thread; 329 Log_Thread *thread;
313 Eina_Array *pointers; 330 struct {
331 Eina_Array *data;
332 Eina_RWLock lock;
333 } thread_events;
314} Thread_Events; 334} Thread_Events;
315 335
316struct _In_Thread_Data 336struct _In_Thread_Data
317{ 337{
318 char *log_path; 338 char *log_path;
319 FILE *log_file;
320 Ecore_Thread *thread;
321 Eina_List *blocks; 339 Eina_List *blocks;
322 Pointer_To_Time *default_pointer_to_time; 340 Pointer_To_Time *default_pointer_to_time;
341 Pointer_To_Time *current_pointer_to_time;
323 Evas_Object *win; 342 Evas_Object *win;
324 double start_time; 343 double start_time;
325 double duration; 344 double duration;
326 Store_Event_Data *stored_data; 345 Store_Event_Data *stored_data;
327 346
328 Eina_Hash *thread_events; 347 struct {
329 Eina_Hash *single_events; 348 Eina_Hash *hash;
330 Eina_Hash *states; 349 Eina_RWLock lock;
350 } state_events;
351 struct {
352 Eina_Hash *hash;
353 Eina_RWLock lock;
354 } thread_events;
355 struct {
356 Eina_Hash *hash;
357 Eina_RWLock lock;
358 } single_events;
359
331 Eina_Bool cpuuse_filtered; 360 Eina_Bool cpuuse_filtered;
332 Eina_Bool cpufreq_filtered; 361 Eina_Bool cpufreq_filtered;
333 362
diff --git a/src/lib/interval_fill.c b/src/lib/interval_fill.c
index b4c7ae0..09b7763 100644
--- a/src/lib/interval_fill.c
+++ b/src/lib/interval_fill.c
@@ -44,6 +44,13 @@
44 task->select = EINA_TRUE; \ 44 task->select = EINA_TRUE; \
45 } 45 }
46 46
47
48typedef struct
49{
50 In_Thread_Data *thd;
51 Eina_List *active;
52} Events_Filling_Data;
53
47void 54void
48log_event_strings_free(Log_Event ev) 55log_event_strings_free(Log_Event ev)
49{ 56{
@@ -55,19 +62,22 @@ log_event_strings_free(Log_Event ev)
55Log_Event 62Log_Event
56log_event_offset_get(In_Thread_Data *thd, long offset) 63log_event_offset_get(In_Thread_Data *thd, long offset)
57{ 64{
65 FILE *log_file = fopen(thd->log_path, "rb");
58 char *eventstr = NULL, *detailstr = NULL; 66 char *eventstr = NULL, *detailstr = NULL;
59 Eina_Evlog_Item item; 67 Eina_Evlog_Item item;
60 Log_Event res = ZERO_LOG_EVENT; 68 Log_Event res = ZERO_LOG_EVENT;
61 if (fseek(thd->log_file, offset, SEEK_SET)) 69 if (fseek(log_file, offset, SEEK_SET))
62 { 70 {
63 res.event = NULL; 71 res.event = NULL;
64 ERR("Getting event by offset failed in fseek func."); 72 ERR("Getting event by offset failed in fseek func.");
73 fclose(log_file);
65 return res; 74 return res;
66 } 75 }
67 if (fread(&item, sizeof(Eina_Evlog_Item), 1, thd->log_file) != 1) 76 if (fread(&item, sizeof(Eina_Evlog_Item), 1, log_file) != 1)
68 { 77 {
69 res.event = NULL; 78 res.event = NULL;
70 ERR("Getting event by offset failed in fread func."); 79 ERR("Getting event by offset failed in fread func.");
80 fclose(log_file);
71 return res; 81 return res;
72 } 82 }
73 unsigned int event_size, detail_size; 83 unsigned int event_size, detail_size;
@@ -82,20 +92,22 @@ log_event_offset_get(In_Thread_Data *thd, long offset)
82 /* without next event data itself (-1). */ 92 /* without next event data itself (-1). */
83 eventstr = calloc(event_size, sizeof(char)); 93 eventstr = calloc(event_size, sizeof(char));
84 detailstr = calloc(detail_size,sizeof(char)); 94 detailstr = calloc(detail_size,sizeof(char));
85 if (fread(eventstr, event_size, 1, thd->log_file) != 1) 95 if (fread(eventstr, event_size, 1, log_file) != 1)
86 { 96 {
87 free(eventstr); 97 free(eventstr);
88 free(detailstr); 98 free(detailstr);
89 res.event = NULL; 99 res.event = NULL;
90 ERR("Getting event by offset failed in fread func."); 100 ERR("Getting event by offset failed in fread func.");
101 fclose(log_file);
91 return res; 102 return res;
92 } 103 }
93 if (fread(detailstr, detail_size, 1, thd->log_file) != 1) 104 if (fread(detailstr, detail_size, 1, log_file) != 1)
94 { 105 {
95 free(eventstr); 106 free(eventstr);
96 free(detailstr); 107 free(detailstr);
97 res.event = NULL; 108 res.event = NULL;
98 ERR("Getting event by offset failed in fread func."); 109 ERR("Getting event by offset failed in fread func.");
110 fclose(log_file);
99 return res; 111 return res;
100 } 112 }
101 } 113 }
@@ -103,11 +115,12 @@ log_event_offset_get(In_Thread_Data *thd, long offset)
103 { 115 {
104 event_size = item.event_next - 1 - sizeof(Eina_Evlog_Item); 116 event_size = item.event_next - 1 - sizeof(Eina_Evlog_Item);
105 eventstr = calloc(event_size, sizeof(char)); 117 eventstr = calloc(event_size, sizeof(char));
106 if (fread(eventstr, event_size, 1, thd->log_file) != 1) 118 if (fread(eventstr, event_size, 1, log_file) != 1)
107 { 119 {
108 free(eventstr); 120 free(eventstr);
109 res.event = NULL; 121 res.event = NULL;
110 ERR("Getting event by offset failed in fread func."); 122 ERR("Getting event by offset failed in fread func.");
123 fclose(log_file);
111 return res; 124 return res;
112 } 125 }
113 } 126 }
@@ -116,6 +129,7 @@ log_event_offset_get(In_Thread_Data *thd, long offset)
116 res.detail = detailstr; 129 res.detail = detailstr;
117 res.timestamp = (item.srctim == 0.0) ? item.tim : item.srctim; 130 res.timestamp = (item.srctim == 0.0) ? item.tim : item.srctim;
118 res.timestamp -= thd->start_time; 131 res.timestamp -= thd->start_time;
132 fclose(log_file);
119 return res; 133 return res;
120} 134}
121 135
@@ -188,12 +202,6 @@ _event_compare_by_tyme(const void *data1, const void *data2)
188 return 0; 202 return 0;
189} 203}
190 204
191typedef struct
192{
193 In_Thread_Data *thd;
194 Eina_List *active;
195} Events_Filling_Data;
196
197static void 205static void
198_single_event_fill(In_Thread_Data *thd, Event_Offsets *event) 206_single_event_fill(In_Thread_Data *thd, Event_Offsets *event)
199{ 207{
@@ -237,10 +245,13 @@ static unsigned int
237_slot_filled_update(In_Thread_Data *thd, double *filled, Event_Offsets *event, int *prev_filled) 245_slot_filled_update(In_Thread_Data *thd, double *filled, Event_Offsets *event, int *prev_filled)
238{ 246{
239 unsigned int thread = event->thread_slot; 247 unsigned int thread = event->thread_slot;
240 Eina_Array *threads = thd->all_offs->threads;
241 unsigned int slot; 248 unsigned int slot;
242 Time_Range interval = thd->stored_data->interval; 249 Time_Range interval = thd->stored_data->interval;
243 Log_Thread *thr = eina_array_data_get(threads, thread); 250
251 eina_rwlock_take_read(&thd->all_offs->threads.lock);
252 Log_Thread *thr = eina_array_data_get(thd->all_offs->threads.data, thread);
253 eina_rwlock_release(&thd->all_offs->threads.lock);
254
244 unsigned int max_events = thr->max_events; 255 unsigned int max_events = thr->max_events;
245 256
246 for (slot = 0; slot < max_events; slot++) 257 for (slot = 0; slot < max_events; slot++)
@@ -287,20 +298,29 @@ _active_collect_cb(const Eina_Hash *hash EINA_UNUSED,
287 if (ei->common.type == STATE_EVENT) 298 if (ei->common.type == STATE_EVENT)
288 { 299 {
289 Event_Info_State *_ei = (Event_Info_State *)ei; 300 Event_Info_State *_ei = (Event_Info_State *)ei;
290 array = _ei->pointers; 301
302 eina_rwlock_take_read(&_ei->state_events.lock);
303 array = _ei->state_events.data;
291 _event_array_active_collect(array, fdata); 304 _event_array_active_collect(array, fdata);
305 eina_rwlock_release(&_ei->state_events.lock);
292 } 306 }
293 else if (ei->common.type == THREAD_EVENT) 307 else if (ei->common.type == THREAD_EVENT)
294 { 308 {
295 Event_Info_Thread *_ei = (Event_Info_Thread *)ei; 309 Event_Info_Thread *_ei = (Event_Info_Thread *)ei;
296 unsigned int j = 0; 310 unsigned int j = 0;
297 unsigned int thread_num = eina_array_count(_ei->threads); 311
312 eina_rwlock_take_read(&_ei->threads.lock);
313 unsigned int thread_num = eina_array_count(_ei->threads.data);
298 for (j = 0; j < thread_num; j++) 314 for (j = 0; j < thread_num; j++)
299 { 315 {
300 Thread_Events *te; 316 Thread_Events *te;
301 te = eina_array_data_get(_ei->threads, j); 317 te = eina_array_data_get(_ei->threads.data, j);
302 _event_array_active_collect(te->pointers, fdata); 318
319 eina_rwlock_take_read(&te->thread_events.lock);
320 _event_array_active_collect(te->thread_events.data, fdata);
321 eina_rwlock_release(&te->thread_events.lock);
303 } 322 }
323 eina_rwlock_release(&_ei->threads.lock);
304 } 324 }
305 else 325 else
306 { 326 {
@@ -309,6 +329,17 @@ _active_collect_cb(const Eina_Hash *hash EINA_UNUSED,
309 return EINA_TRUE; 329 return EINA_TRUE;
310} 330}
311 331
332/* TODO: Need to rework accordingly to usage with tasks mechanism */
333EINA_UNUSED static void *
334_states_register_async(void *data)
335{
336 Evas_Object *win = (Evas_Object *) data;
337 Task_State *task = NULL;
338 evas_object_smart_callback_call(win, "task,state,register",
339 &task);
340 return task;
341}
342
312static void 343static void
313_active_events_fill(Events_Filling_Data data, double **filled) 344_active_events_fill(Events_Filling_Data data, double **filled)
314{ 345{
@@ -359,6 +390,8 @@ _active_events_fill(Events_Filling_Data data, double **filled)
359 else 390 else
360 { 391 {
361 Task_State *task = NULL; 392 Task_State *task = NULL;
393 /* TODO: Need to rework accordingly to usage with tasks mechanism */
394 /* task = ecore_main_loop_thread_safe_call_sync(_states_register_async, thd->win); */
362 evas_object_smart_callback_call(thd->win, "task,state,register", &task); 395 evas_object_smart_callback_call(thd->win, "task,state,register", &task);
363 TASK_FILL; 396 TASK_FILL;
364 } 397 }
@@ -393,13 +426,19 @@ _thread_events_in_interval_collect_cb(const Eina_Hash *hash EINA_UNUSED,
393 if (ei->common.filtered) return EINA_TRUE; 426 if (ei->common.filtered) return EINA_TRUE;
394 427
395 unsigned int j = 0; 428 unsigned int j = 0;
396 unsigned int thread_num = eina_array_count(ei->threads); 429 eina_rwlock_take_read(&ei->threads.lock);
430 unsigned int thread_num = eina_array_count(ei->threads.data);
397 for (j = 0; j < thread_num; j++) 431 for (j = 0; j < thread_num; j++)
398 { 432 {
399 Thread_Events *te; 433 Thread_Events *te;
400 te = eina_array_data_get(ei->threads, j); 434 te = eina_array_data_get(ei->threads.data, j);
401 _interval_events_collect(te->pointers, fdata); 435
436 eina_rwlock_take_read(&te->thread_events.lock);
437 _interval_events_collect(te->thread_events.data, fdata);
438 eina_rwlock_release(&te->thread_events.lock);
402 } 439 }
440 eina_rwlock_release(&ei->threads.lock);
441
403 return EINA_TRUE; 442 return EINA_TRUE;
404} 443}
405 444
@@ -413,13 +452,14 @@ _states_interval_fill_cb(const Eina_Hash *hash EINA_UNUSED,
413 Event_Info_State *ei = data; 452 Event_Info_State *ei = data;
414 if (ei->common.filtered) return EINA_TRUE; 453 if (ei->common.filtered) return EINA_TRUE;
415 454
416 Eina_Array *states = ei->pointers; 455 Eina_Array *states;
417 Color rgba; 456 Color rgba;
418
419 Event_Offsets *event; 457 Event_Offsets *event;
420 Time_Range interval = thd->stored_data->interval; 458 Time_Range interval = thd->stored_data->interval;
421 Task_State *last_invis_tasks = NULL; 459 Task_State *last_invis_tasks = NULL;
422 460
461 eina_rwlock_take_read(&ei->state_events.lock);
462 states = ei->state_events.data;
423 int i = _event_offsets_time_binary_search(states, interval.start); 463 int i = _event_offsets_time_binary_search(states, interval.start);
424 for (; i < (int) eina_array_count(states); i++) 464 for (; i < (int) eina_array_count(states); i++)
425 { 465 {
@@ -459,9 +499,10 @@ _states_interval_fill_cb(const Eina_Hash *hash EINA_UNUSED,
459 } 499 }
460 else 500 else
461 { 501 {
502 /* TODO: Need to rework accordingly to usage with tasks mechanism */
503 /* task = ecore_main_loop_thread_safe_call_sync(_states_register_async, thd->win); */
462 task = NULL; 504 task = NULL;
463 evas_object_smart_callback_call(thd->win, "task,state,register", 505 evas_object_smart_callback_call(thd->win, "task,state,register", &task);
464 &task);
465 last_invis_tasks = task; 506 last_invis_tasks = task;
466 } 507 }
467 rgba.r /= 8; 508 rgba.r /= 8;
@@ -471,26 +512,43 @@ _states_interval_fill_cb(const Eina_Hash *hash EINA_UNUSED,
471 } 512 }
472 else 513 else
473 { 514 {
474 evas_object_smart_callback_call(thd->win, "event,fill", event); 515 /* TODO: Need to rework accordingly to usage with tasks mechanism */
516 /* task = ecore_main_loop_thread_safe_call_sync(_states_register_async, thd->win); */
517 task = NULL;
518 evas_object_smart_callback_call(thd->win, "task,state,register", &task);
519 TASK_FILL;
475 last_invis_tasks = NULL; 520 last_invis_tasks = NULL;
476 continue; 521 continue;
477 } 522 }
478 TASK_FILL; 523 TASK_FILL;
479 task->common.rgba = rgba; 524 task->common.rgba = rgba;
480 } 525 }
526 eina_rwlock_release(&ei->state_events.lock);
481 return EINA_TRUE; 527 return EINA_TRUE;
482} 528}
483 529
484static void 530static void
485_interval_state_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt) 531_interval_state_events_fill(void *data, Ecore_Thread *thread EINA_UNUSED)
486{ 532{
487 Eina_Hash *states_hash = thd->states; 533 eina_evlog("+interval_states", NULL, 0.0, NULL);
534 In_Thread_Data *thd = data;
535 Pointer_To_Time *ptt = thd->current_pointer_to_time;
536
537 Eina_Hash *states_hash = thd->state_events.hash;
488 Eina_List *active = eina_list_clone(ptt->active_events); 538 Eina_List *active = eina_list_clone(ptt->active_events);
489 539
490 Events_Filling_Data filling_data = {thd, active}; 540 Events_Filling_Data filling_data = {thd, active};
541
542 eina_rwlock_take_read(&thd->state_events.lock);
491 eina_hash_foreach(states_hash, _active_collect_cb, &filling_data); 543 eina_hash_foreach(states_hash, _active_collect_cb, &filling_data);
544 eina_rwlock_release(&thd->state_events.lock);
545
492 _active_events_fill(filling_data, NULL); 546 _active_events_fill(filling_data, NULL);
547
548 eina_rwlock_take_read(&thd->state_events.lock);
493 eina_hash_foreach(states_hash, _states_interval_fill_cb, &filling_data); 549 eina_hash_foreach(states_hash, _states_interval_fill_cb, &filling_data);
550 eina_rwlock_release(&thd->state_events.lock);
551 eina_evlog("-interval_states", NULL, 0.0, NULL);
494} 552}
495 553
496static void 554static void
@@ -498,18 +556,25 @@ _interval_cpuuse_events_fill(In_Thread_Data *thd)
498{ 556{
499 if (thd->cpuuse_filtered) return; 557 if (thd->cpuuse_filtered) return;
500 Store_Event_Data *sd = thd->stored_data; 558 Store_Event_Data *sd = thd->stored_data;
501 Eina_Array *threads = thd->all_offs->threads;
502 Log_Thread *thr = NULL; 559 Log_Thread *thr = NULL;
503 Task_Cpu_Use *task = NULL, *task_prev = NULL; 560 Task_Cpu_Use *task = NULL, *task_prev = NULL;
504 Eina_Array *cpuuse; 561 Eina_Array *cpuuse;
505 unsigned int index = 0, j; 562 unsigned int index = 0, j;
506 unsigned int thread_num = eina_array_count(threads); 563 unsigned int thread_num = 0;
507 Log_Cpu_Use *event; 564 Log_Cpu_Use *event;
508 565
566 eina_rwlock_take_read(&thd->all_offs->threads.lock);
567 thread_num = eina_array_count(thd->all_offs->threads.data);
568 eina_rwlock_release(&thd->all_offs->threads.lock);
569
509 for (j = 0; j < thread_num; j++) 570 for (j = 0; j < thread_num; j++)
510 { 571 {
511 thr = eina_array_data_get(threads, j); 572 eina_rwlock_take_read(&thd->all_offs->threads.lock);
512 cpuuse = thr->cpuused_events; 573 thr = eina_array_data_get(thd->all_offs->threads.data, j);
574 eina_rwlock_release(&thd->all_offs->threads.lock);
575
576 eina_rwlock_take_read(&thr->cpuused_events.lock);
577 cpuuse = thr->cpuused_events.data;
513 task_prev = NULL; 578 task_prev = NULL;
514 for (index = _event_cpu_time_binary_search(cpuuse, sd->interval.start); 579 for (index = _event_cpu_time_binary_search(cpuuse, sd->interval.start);
515 index < eina_array_count(cpuuse); 580 index < eina_array_count(cpuuse);
@@ -564,15 +629,17 @@ _interval_cpuuse_events_fill(In_Thread_Data *thd)
564 task_prev = task; 629 task_prev = task;
565 } 630 }
566 } 631 }
632 eina_rwlock_release(&thr->cpuused_events.lock);
567 } 633 }
568} 634}
569 635
570static void 636static void
571_interval_cpufreq_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt) 637_interval_cpufreq_events_fill(In_Thread_Data *thd)
572{ 638{
573 if (thd->cpufreq_filtered) return; 639 if (thd->cpufreq_filtered) return;
640 Pointer_To_Time *ptt = thd->current_pointer_to_time;
574 Store_Event_Data *sd = thd->stored_data; 641 Store_Event_Data *sd = thd->stored_data;
575 Eina_Array *cpufreqs = thd->all_offs->cpufreqs; 642 Eina_Array *cpufreqs = NULL;
576 Log_Cpu_Freq *event = NULL; 643 Log_Cpu_Freq *event = NULL;
577 Task_Cpu_Freq **tasks_prev = NULL; 644 Task_Cpu_Freq **tasks_prev = NULL;
578 Task_Cpu_Freq *task = NULL; 645 Task_Cpu_Freq *task = NULL;
@@ -584,6 +651,8 @@ _interval_cpufreq_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
584 tasks_prev = (Task_Cpu_Freq **)calloc(sd->cpucores, sizeof(Task_Cpu_Freq *)); 651 tasks_prev = (Task_Cpu_Freq **)calloc(sd->cpucores, sizeof(Task_Cpu_Freq *));
585 652
586 /* Find values of events that start before given interval */ 653 /* Find values of events that start before given interval */
654 eina_rwlock_take_read(&thd->all_offs->cpufreqs.lock);
655 cpufreqs = thd->all_offs->cpufreqs.data;
587 index = _event_cpu_time_binary_search(cpufreqs, ptt->last_event_time); 656 index = _event_cpu_time_binary_search(cpufreqs, ptt->last_event_time);
588 for (; index < eina_array_count(cpufreqs); index++) 657 for (; index < eina_array_count(cpufreqs); index++)
589 { 658 {
@@ -595,6 +664,7 @@ _interval_cpufreq_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
595 } 664 }
596 else break; 665 else break;
597 } 666 }
667 eina_rwlock_release(&thd->all_offs->cpufreqs.lock);
598 668
599 /* Fill first tasks that will start events from 0 grid cell */ 669 /* Fill first tasks that will start events from 0 grid cell */
600 for (j = 0; j < sd->cpucores; j++) 670 for (j = 0; j < sd->cpucores; j++)
@@ -610,6 +680,8 @@ _interval_cpufreq_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
610 tasks_prev[j] = task; 680 tasks_prev[j] = task;
611 } 681 }
612 682
683 eina_rwlock_take_read(&thd->all_offs->cpufreqs.lock);
684
613 for (; index < eina_array_count(cpufreqs) && 685 for (; index < eina_array_count(cpufreqs) &&
614 (event->common.timestamp < sd->interval.start + sd->interval.length); 686 (event->common.timestamp < sd->interval.start + sd->interval.length);
615 event = eina_array_data_get(cpufreqs, index++), core = event->core) 687 event = eina_array_data_get(cpufreqs, index++), core = event->core)
@@ -636,34 +708,43 @@ _interval_cpufreq_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
636 tasks_prev[core]->common.grid.x; 708 tasks_prev[core]->common.grid.x;
637 tasks_prev[core] = task; 709 tasks_prev[core] = task;
638 } 710 }
711 eina_rwlock_release(&thd->all_offs->cpufreqs.lock);
712
639 free(tasks_prev); 713 free(tasks_prev);
640} 714}
641 715
642static void 716static void
643_interval_thread_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt) 717_interval_thread_events_fill(In_Thread_Data *thd)
644{ 718{
719 Pointer_To_Time *ptt = thd->current_pointer_to_time;
645 Time_Range interval = thd->stored_data->interval; 720 Time_Range interval = thd->stored_data->interval;
646 Eina_Array *threads = thd->all_offs->threads;
647 Log_Thread *thr; 721 Log_Thread *thr;
648 Event_Offsets *event; 722 Event_Offsets *event;
649 unsigned int i, thread; 723 unsigned int i, thread;
650 Eina_Hash *thread_hash = thd->thread_events; 724 Eina_Hash *thread_hash = thd->thread_events.hash;
651 Eina_List *active = eina_list_clone(ptt->active_events); 725 Eina_List *active = eina_list_clone(ptt->active_events);
652 726
727 /* Need to lock all proccessing from adding threads. If happens new event
728 outside exist threads - it would try to write into not allocated memory area*/
729 eina_rwlock_take_read(&thd->all_offs->threads.lock);
730
653 /* alloc memory for filled array */ 731 /* alloc memory for filled array */
654 unsigned int thread_num = eina_array_count(threads); 732 unsigned int thread_num = eina_array_count(thd->all_offs->threads.data);
655 double **filled = calloc(thread_num, sizeof(double *)); 733 double **filled = calloc(thread_num, sizeof(double *));
656 Task_Thread ***last_invis_tasks = calloc(thread_num, sizeof(Task_Thread **)); 734 Task_Thread ***last_invis_tasks = calloc(thread_num, sizeof(Task_Thread **));
657 int *prev_filled = calloc(thread_num, sizeof(int)); 735 int *prev_filled = calloc(thread_num, sizeof(int));
658 for (i = 0; i < thread_num; i++) 736 for (i = 0; i < thread_num; i++)
659 { 737 {
660 thr = eina_array_data_get(threads, i); 738 thr = eina_array_data_get(thd->all_offs->threads.data, i);
661 filled[i] = calloc(thr->max_events, sizeof(double)); 739 filled[i] = calloc(thr->max_events, sizeof(double));
662 last_invis_tasks[i] = calloc(thr->max_events, sizeof(Task_Thread *)); 740 last_invis_tasks[i] = calloc(thr->max_events, sizeof(Task_Thread *));
663 } 741 }
664 742
665 Events_Filling_Data filling_data = {thd, active}; 743 Events_Filling_Data filling_data = {thd, active};
744
745 eina_rwlock_take_read(&thd->thread_events.lock);
666 eina_hash_foreach(thread_hash, _active_collect_cb, &filling_data); 746 eina_hash_foreach(thread_hash, _active_collect_cb, &filling_data);
747 eina_rwlock_release(&thd->thread_events.lock);
667 748
668 unsigned int slot; 749 unsigned int slot;
669 750
@@ -671,7 +752,11 @@ _interval_thread_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
671 752
672 /* after foreach filing_data.active will contain all events only from interval */ 753 /* after foreach filing_data.active will contain all events only from interval */
673 filling_data.active = NULL; 754 filling_data.active = NULL;
755
756 eina_rwlock_take_read(&thd->thread_events.lock);
674 eina_hash_foreach(thread_hash, _thread_events_in_interval_collect_cb, &filling_data); 757 eina_hash_foreach(thread_hash, _thread_events_in_interval_collect_cb, &filling_data);
758 eina_rwlock_release(&thd->thread_events.lock);
759
675 Eina_List *events_in_interval = eina_list_sort(filling_data.active, 0, _event_compare_by_tyme); 760 Eina_List *events_in_interval = eina_list_sort(filling_data.active, 0, _event_compare_by_tyme);
676 761
677 EINA_LIST_FREE(events_in_interval, event) 762 EINA_LIST_FREE(events_in_interval, event)
@@ -718,6 +803,7 @@ _interval_thread_events_fill(In_Thread_Data *thd, Pointer_To_Time *ptt)
718 } 803 }
719 TASK_FILL; 804 TASK_FILL;
720 } 805 }
806 eina_rwlock_release(&thd->all_offs->threads.lock);
721 807
722 for (i = 0; i < thread_num; i++) 808 for (i = 0; i < thread_num; i++)
723 { 809 {
@@ -740,12 +826,17 @@ _single_events_in_interval_collect_cb(const Eina_Hash *hash EINA_UNUSED,
740 826
741 Thread_Events *te; 827 Thread_Events *te;
742 unsigned int j = 0; 828 unsigned int j = 0;
743 unsigned int thread_num = eina_array_count(ei->threads); 829 eina_rwlock_take_read(&ei->threads.lock);
830 unsigned int thread_num = eina_array_count(ei->threads.data);
744 for (j = 0; j < thread_num; j++) 831 for (j = 0; j < thread_num; j++)
745 { 832 {
746 te = eina_array_data_get(ei->threads, j); 833 te = eina_array_data_get(ei->threads.data, j);
747 _interval_events_collect(te->pointers, fdata); 834
835 eina_rwlock_take_read(&te->thread_events.lock);
836 _interval_events_collect(te->thread_events.data, fdata);
837 eina_rwlock_release(&te->thread_events.lock);
748 } 838 }
839 eina_rwlock_release(&ei->threads.lock);
749 return EINA_TRUE; 840 return EINA_TRUE;
750} 841}
751 842
@@ -777,14 +868,21 @@ _interval_single_events_fill(In_Thread_Data *thd)
777{ 868{
778 Event_Offsets *event = NULL; 869 Event_Offsets *event = NULL;
779 int thread_slot = 0; 870 int thread_slot = 0;
780 Eina_Hash *single_hash = thd->single_events;
781 Eina_List *events_in_interval = NULL; 871 Eina_List *events_in_interval = NULL;
782 Events_Filling_Data filling_data = {thd, NULL}; 872 Events_Filling_Data filling_data = {thd, NULL};
783 unsigned int thread_num = eina_array_count(thd->all_offs->threads); 873 int *last_event_coords = NULL;
784 int *last_event_coords = calloc(thread_num, sizeof(int)); 874 unsigned int thread_num;
875
876 eina_rwlock_take_read(&thd->all_offs->threads.lock);
877 thread_num = eina_array_count(thd->all_offs->threads.data);
878 eina_rwlock_release(&thd->all_offs->threads.lock);
879 last_event_coords = calloc(thread_num, sizeof(int));
785 880
786 /* after foreach filing_data.active will contain all events only from interval */ 881 /* after foreach filing_data.active will contain all events only from interval */
787 eina_hash_foreach(single_hash, _single_events_in_interval_collect_cb, &filling_data); 882 eina_rwlock_take_read(&thd->single_events.lock);
883 eina_hash_foreach(thd->single_events.hash, _single_events_in_interval_collect_cb, &filling_data);
884 eina_rwlock_release(&thd->single_events.lock);
885
788 events_in_interval = eina_list_sort(filling_data.active, 0, _event_compare_by_tyme); 886 events_in_interval = eina_list_sort(filling_data.active, 0, _event_compare_by_tyme);
789 887
790 EINA_LIST_FREE(events_in_interval, event) 888 EINA_LIST_FREE(events_in_interval, event)
@@ -862,13 +960,17 @@ _interval_fill(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
862 In_Thread_Data *thd = event_info; 960 In_Thread_Data *thd = event_info;
863 evas_object_smart_callback_del(thd->win, "event,fill", _event_fill_cb); 961 evas_object_smart_callback_del(thd->win, "event,fill", _event_fill_cb);
864 evas_object_smart_callback_add(thd->win, "event,fill", _event_fill_cb, thd); 962 evas_object_smart_callback_add(thd->win, "event,fill", _event_fill_cb, thd);
865 Pointer_To_Time *ptt = _start_ptt_get(thd); 963 thd->current_pointer_to_time = _start_ptt_get(thd);
866 964
965/* TODO: Need to rework accordingly to usage with tasks mechanism */
966/* ecore_thread_feedback_run(_interval_state_events_fill, NULL, NULL, NULL,
967 * thd, EINA_FALSE);
968 */
969 _interval_cpufreq_events_fill(thd);
867 _interval_single_events_fill(thd); 970 _interval_single_events_fill(thd);
868 _interval_thread_events_fill(thd, ptt); 971 _interval_thread_events_fill(thd);
869 _interval_cpuuse_events_fill(thd); 972 _interval_cpuuse_events_fill(thd);
870 _interval_state_events_fill(thd, ptt); 973 _interval_state_events_fill(thd, NULL);
871 _interval_cpufreq_events_fill(thd, ptt);
872} 974}
873 975
874 976
diff --git a/src/lib/logload.c b/src/lib/logload.c
index a099a80..0d749b2 100644
--- a/src/lib/logload.c
+++ b/src/lib/logload.c
@@ -21,33 +21,36 @@
21#include "logload.h" 21#include "logload.h"
22 22
23#define MAGIC_LOG_CHECK 0x0ffee211 23#define MAGIC_LOG_CHECK 0x0ffee211
24#define ADD_PER_REALLOC 1024
24 25
25Ecore_Thread *th = NULL;
26Time_Range start_range = DEFAULT_START_RANGE; 26Time_Range start_range = DEFAULT_START_RANGE;
27static void *log_block_event_read(In_Thread_Data *thd, void *ptr, void *end, 27
28 long start_pointer, Navigation_Graphs *feedback, 28static Eina_Bool _log_block_process(In_Thread_Data *thd);
29 Eina_Bool realtime_status);
30 29
31enum _Stream_Status { 30enum _Stream_Status {
32 DATA_STREAM_ACTIVE = 0, 31 DATA_STREAM_ACTIVE = 0,
33 DATA_STREAM_PAUSED 32 DATA_STREAM_PAUSED
34}; 33};
35 34
35enum _Log_Source_Type {
36 LOG_SOURCE_STREAM = 0,
37 LOG_SOURCE_FILE
38};
39
36typedef enum _Stream_Status Stream_Status; 40typedef enum _Stream_Status Stream_Status;
41typedef enum _Log_Source_Type Log_Source_Type;
37 42
38typedef struct _Realtime_Data 43typedef struct _Logload_Data
39{ 44{
40 In_Thread_Data *thd; 45 In_Thread_Data *thd;
41 FILE *file; 46 FILE *file;
42 char path[STRING_LENGTH];
43 Eina_Bool first_block_drawed; 47 Eina_Bool first_block_drawed;
44 Stream_Status status; 48 Stream_Status status;
45} Realtime_Data; 49 Ecore_Thread *log_read_thread;
50} Logload_Data;
46 51
47static Realtime_Data *rd = NULL; 52static Logload_Data *logload_data = NULL;
48 53static int graph_update_rate = 1500;
49#define ADD_PER_REALLOC 1024
50static int graph_update_rate = 40;
51 54
52static void 55static void
53offset_array_free(Eina_Array *arr) 56offset_array_free(Eina_Array *arr)
@@ -67,18 +70,15 @@ graph_data_free(Graph_Data *graph)
67} 70}
68 71
69static void 72static void
70global_stored_data_free(Store_Event_Data *sd)
71{
72 unsigned int i;
73 for (i = 0; i < sd->cpucores; i++)
74 sd->cpumhzlast[i] = 0;
75}
76
77static void
78hash_states_free(void *data) 73hash_states_free(void *data)
79{ 74{
80 Event_Info_State *ei = data; 75 Event_Info_State *ei = data;
81 offset_array_free(ei->pointers); 76
77 eina_rwlock_take_write(&ei->state_events.lock);
78 offset_array_free(ei->state_events.data);
79 eina_rwlock_release(&ei->state_events.lock);
80
81 eina_rwlock_free(&ei->state_events.lock);
82 free(ei->common.name); 82 free(ei->common.name);
83 free(ei); 83 free(ei);
84} 84}
@@ -87,13 +87,23 @@ static void
87hash_threads_free(void *data) 87hash_threads_free(void *data)
88{ 88{
89 Event_Info_Thread *ei = data; 89 Event_Info_Thread *ei = data;
90 while (eina_array_count(ei->threads)) 90
91 eina_rwlock_take_write(&ei->threads.lock);
92 while (eina_array_count(ei->threads.data))
91 { 93 {
92 Thread_Events *te = eina_array_pop(ei->threads); 94 Thread_Events *te = eina_array_pop(ei->threads.data);
93 offset_array_free(te->pointers); 95
96 eina_rwlock_take_write(&te->thread_events.lock);
97 offset_array_free(te->thread_events.data);
98 eina_rwlock_release(&te->thread_events.lock);
99
100 eina_rwlock_free(&te->thread_events.lock);
94 free(te); 101 free(te);
95 } 102 }
96 eina_array_free(ei->threads); 103 eina_array_free(ei->threads.data);
104 eina_rwlock_release(&ei->threads.lock);
105
106 eina_rwlock_free(&ei->threads.lock);
97 free(ei->common.name); 107 free(ei->common.name);
98 free(ei); 108 free(ei);
99} 109}
@@ -102,13 +112,23 @@ static void
102hash_single_free(void *data) 112hash_single_free(void *data)
103{ 113{
104 Event_Info_Single *ei = data; 114 Event_Info_Single *ei = data;
105 while (eina_array_count(ei->threads)) 115
116 eina_rwlock_take_write(&ei->threads.lock);
117 while (eina_array_count(ei->threads.data))
106 { 118 {
107 Thread_Events *te = eina_array_pop(ei->threads); 119 Thread_Events *te = eina_array_pop(ei->threads.data);
108 offset_array_free(te->pointers); 120
121 eina_rwlock_take_write(&te->thread_events.lock);
122 offset_array_free(te->thread_events.data);
123 eina_rwlock_release(&te->thread_events.lock);
124
125 eina_rwlock_free(&te->thread_events.lock);
109 free(te); 126 free(te);
110 } 127 }
111 eina_array_free(ei->threads); 128 eina_array_free(ei->threads.data);
129 eina_rwlock_release(&ei->threads.lock);
130
131 eina_rwlock_free(&ei->threads.lock);
112 free(ei->common.name); 132 free(ei->common.name);
113 free(ei); 133 free(ei);
114} 134}
@@ -129,11 +149,16 @@ in_thread_data_init(void)
129 thd->navi->cpufreq = (Graph_Data *) calloc(1, sizeof(Graph_Data)); 149 thd->navi->cpufreq = (Graph_Data *) calloc(1, sizeof(Graph_Data));
130 thd->stored_data = (Store_Event_Data*) calloc(1, sizeof(Store_Event_Data)); 150 thd->stored_data = (Store_Event_Data*) calloc(1, sizeof(Store_Event_Data));
131 thd->all_offs = (Offsets *) calloc(1, sizeof(Offsets)); 151 thd->all_offs = (Offsets *) calloc(1, sizeof(Offsets));
132 thd->all_offs->cpufreqs = eina_array_new(ADD_PER_REALLOC); 152 thd->all_offs->cpufreqs.data = eina_array_new(ADD_PER_REALLOC);
133 thd->states = eina_hash_string_superfast_new(hash_states_free); 153 eina_rwlock_new(&thd->all_offs->cpufreqs.lock);
134 thd->thread_events = eina_hash_string_superfast_new(hash_threads_free); 154 thd->state_events.hash = eina_hash_string_superfast_new(hash_states_free);
135 thd->single_events = eina_hash_string_superfast_new(hash_single_free); 155 eina_rwlock_new(&thd->state_events.lock);
136 thd->all_offs->threads = eina_array_new(4); 156 thd->thread_events.hash = eina_hash_string_superfast_new(hash_threads_free);
157 eina_rwlock_new(&thd->thread_events.lock);
158 thd->single_events.hash = eina_hash_string_superfast_new(hash_single_free);
159 eina_rwlock_new(&thd->single_events.lock);
160 thd->all_offs->threads.data = eina_array_new(4);
161 eina_rwlock_new(&thd->all_offs->threads.lock);
137 thd->default_pointer_to_time = (Pointer_To_Time *) calloc(1, sizeof(Pointer_To_Time)); 162 thd->default_pointer_to_time = (Pointer_To_Time *) calloc(1, sizeof(Pointer_To_Time));
138 return thd; 163 return thd;
139} 164}
@@ -142,24 +167,49 @@ static void
142in_thread_data_free(In_Thread_Data *thd) 167in_thread_data_free(In_Thread_Data *thd)
143{ 168{
144 if (!thd) return; 169 if (!thd) return;
145 eina_hash_free(thd->states); 170
146 eina_hash_free(thd->thread_events); 171 eina_rwlock_take_write(&thd->state_events.lock);
147 eina_hash_free(thd->single_events); 172 eina_hash_free(thd->state_events.hash);
148 offset_array_free(thd->all_offs->cpufreqs); 173 eina_rwlock_release(&thd->state_events.lock);
149 Eina_Array *threads = thd->all_offs->threads; 174 eina_rwlock_free(&thd->state_events.lock);
175
176 eina_rwlock_take_write(&thd->thread_events.lock);
177 eina_hash_free(thd->thread_events.hash);
178 eina_rwlock_release(&thd->thread_events.lock);
179 eina_rwlock_free(&thd->thread_events.lock);
180
181 eina_rwlock_take_write(&thd->single_events.lock);
182 eina_hash_free(thd->single_events.hash);
183 eina_rwlock_release(&thd->single_events.lock);
184 eina_rwlock_free(&thd->single_events.lock);
185
186 eina_rwlock_take_write(&thd->all_offs->cpufreqs.lock);
187 offset_array_free(thd->all_offs->cpufreqs.data);
188 eina_rwlock_release(&thd->all_offs->cpufreqs.lock);
189 eina_rwlock_free(&thd->all_offs->cpufreqs.lock);
190
191 eina_rwlock_take_write(&thd->all_offs->threads.lock);
192 Eina_Array *threads = thd->all_offs->threads.data;
193
150 while (eina_array_count(threads)) 194 while (eina_array_count(threads))
151 { 195 {
152 Log_Thread *thr = eina_array_pop(threads); 196 Log_Thread *thr = eina_array_pop(threads);
153 offset_array_free(thr->cpuused_events); 197
198 eina_rwlock_take_write(&thr->cpuused_events.lock);
199 offset_array_free(thr->cpuused_events.data);
200 eina_rwlock_release(&thr->cpuused_events.lock);
201
202 eina_rwlock_free(&thr->cpuused_events.lock);
154 free(thr); 203 free(thr);
155 } 204 }
156 eina_array_free(threads); 205 eina_array_free(threads);
206 eina_rwlock_release(&thd->all_offs->threads.lock);
207 eina_rwlock_free(&thd->all_offs->threads.lock);
157 free(thd->all_offs); 208 free(thd->all_offs);
158 209
159 fclose(thd->log_file);
160 free(thd->log_path); 210 free(thd->log_path);
211 thd->log_path = NULL;
161 212
162 global_stored_data_free(thd->stored_data);
163 free(thd->stored_data); 213 free(thd->stored_data);
164 214
165 Pointer_To_Time *list_data; 215 Pointer_To_Time *list_data;
@@ -170,7 +220,7 @@ in_thread_data_free(In_Thread_Data *thd)
170 eina_list_free(list_data->active_events); 220 eina_list_free(list_data->active_events);
171 free(list_data); 221 free(list_data);
172 } 222 }
173 thd->thread = NULL; 223 thd->blocks = NULL;
174 224
175 graph_data_free(thd->navi->cpuuse); 225 graph_data_free(thd->navi->cpuuse);
176 graph_data_free(thd->navi->cpufreq); 226 graph_data_free(thd->navi->cpufreq);
@@ -183,6 +233,27 @@ in_thread_data_free(In_Thread_Data *thd)
183 thd = NULL; 233 thd = NULL;
184} 234}
185 235
236static void
237_log_read_thread_cancel()
238{
239 Ecore_Thread *th = logload_data->log_read_thread;
240 if (th && !ecore_thread_check(th))
241 ecore_thread_cancel(th);
242}
243
244static void
245_logload_data_free()
246{
247 if (!logload_data) return;
248 _log_read_thread_cancel();
249 in_thread_data_free(logload_data->thd);
250 if (logload_data->file) fclose(logload_data->file);
251 logload_data->file = NULL;
252 logload_data->first_block_drawed = EINA_FALSE;
253 free(logload_data);
254 logload_data = NULL;
255}
256
186/** 257/**
187 * 258 *
188 * @brief Function finds data from thread with choosen id; 259 * @brief Function finds data from thread with choosen id;
@@ -209,22 +280,29 @@ log_thread_slot_find(Eina_Array *threads, unsigned long long thread)
209static void 280static void
210log_thread_push(In_Thread_Data *thd, unsigned long long thread) 281log_thread_push(In_Thread_Data *thd, unsigned long long thread)
211{ 282{
212 Eina_Array *threads = thd->all_offs->threads; 283 unsigned int slot;
213 unsigned int slot = log_thread_slot_find(threads, thread); 284 unsigned int count;
214 285
215 if (slot < eina_array_count(threads)) return; 286 eina_rwlock_take_read(&thd->all_offs->threads.lock);
287 slot = log_thread_slot_find(thd->all_offs->threads.data, thread);
288 count = eina_array_count(thd->all_offs->threads.data);
289 eina_rwlock_release(&thd->all_offs->threads.lock);
216 290
291 if (slot < count) return;
217 Log_Thread *new = (Log_Thread *) calloc(1, sizeof(Log_Thread)); 292 Log_Thread *new = (Log_Thread *) calloc(1, sizeof(Log_Thread));
218 if (!new) 293 if (!new)
219 { 294 {
220 CRITICAL("Allocation memory for storing thread is failed"); 295 CRITICAL("Allocation memory for storing thread is failed");
221 if (!ecore_thread_check(thd->thread)) 296 _log_read_thread_cancel();
222 ecore_thread_cancel(thd->thread);
223 return; 297 return;
224 } 298 }
225 eina_array_push(threads, new);
226 new->id = thread; 299 new->id = thread;
227 new->cpuused_events = eina_array_new(ADD_PER_REALLOC); 300 new->cpuused_events.data = eina_array_new(ADD_PER_REALLOC);
301 eina_rwlock_new(&new->cpuused_events.lock);
302
303 eina_rwlock_take_write(&thd->all_offs->threads.lock);
304 eina_array_push(thd->all_offs->threads.data, new);
305 eina_rwlock_release(&thd->all_offs->threads.lock);
228} 306}
229 307
230static void 308static void
@@ -235,42 +313,64 @@ global_log_info_update(In_Thread_Data *thd, char *eventstr, char *detailstr, lon
235 if ((*eventstr == '<') || (*eventstr == '>')) 313 if ((*eventstr == '<') || (*eventstr == '>'))
236 { 314 {
237 Event_Info_State *ei; 315 Event_Info_State *ei;
238 ei = eina_hash_find(thd->states, eventstr + 1); 316
317 eina_rwlock_take_read(&thd->state_events.lock);
318 ei = eina_hash_find(thd->state_events.hash, eventstr + 1);
319 eina_rwlock_release(&thd->state_events.lock);
320
239 if (!ei) 321 if (!ei)
240 { 322 {
241
242 ei = calloc(1, sizeof(Event_Info_State)); 323 ei = calloc(1, sizeof(Event_Info_State));
243 ei->common.name = strdup(eventstr + 1); 324 ei->common.name = strdup(eventstr + 1);
244 ei->grid_slot = eina_hash_population(thd->states);
245 ei->common.type = STATE_EVENT; 325 ei->common.type = STATE_EVENT;
326 ei->state_events.data = eina_array_new(ADD_PER_REALLOC);
327 eina_rwlock_new(&ei->state_events.lock);
328
329 eina_rwlock_take_write(&thd->state_events.lock);
330 ei->grid_slot = eina_hash_population(thd->state_events.hash);
246 ei->common.color = rgb_to_rgba_convert(event_colors[(ei->grid_slot * 23) % COLORS_NUM]); 331 ei->common.color = rgb_to_rgba_convert(event_colors[(ei->grid_slot * 23) % COLORS_NUM]);
247 ei->pointers = eina_array_new(ADD_PER_REALLOC); 332 eina_hash_add(thd->state_events.hash, ei->common.name, ei);
248 eina_hash_add(thd->states, ei->common.name, ei); 333 eina_rwlock_release(&thd->state_events.lock);
249 } 334 }
250 } 335 }
251 else if ((*eventstr == '+') || (*eventstr == '-')) 336 else if ((*eventstr == '+') || (*eventstr == '-'))
252 { 337 {
253 Event_Info_Thread *ei; 338 Event_Info_Thread *ei;
254 ei = eina_hash_find(thd->thread_events, eventstr + 1); 339
340 eina_rwlock_take_read(&thd->thread_events.lock);
341 ei = eina_hash_find(thd->thread_events.hash, eventstr + 1);
342 eina_rwlock_release(&thd->thread_events.lock);
343
255 if (!ei) 344 if (!ei)
256 { 345 {
257 ei = calloc(1, sizeof(Event_Info_Thread)); 346 ei = calloc(1, sizeof(Event_Info_Thread));
258 ei->common.name = strdup(eventstr + 1); 347 ei->common.name = strdup(eventstr + 1);
259 ei->common.type = THREAD_EVENT; 348 ei->common.type = THREAD_EVENT;
260 unsigned int list_size = eina_hash_population(thd->thread_events); 349 ei->threads.data = eina_array_new(ADD_PER_REALLOC);
350 eina_rwlock_new(&ei->threads.lock);
351
352 eina_rwlock_take_write(&thd->thread_events.lock);
353 unsigned int list_size = eina_hash_population(thd->thread_events.hash);
261 ei->common.color = rgb_to_rgba_convert(event_colors[(list_size * 17) % COLORS_NUM]); 354 ei->common.color = rgb_to_rgba_convert(event_colors[(list_size * 17) % COLORS_NUM]);
262 ei->threads = eina_array_new(ADD_PER_REALLOC); 355 eina_hash_add(thd->thread_events.hash, ei->common.name, ei);
263 eina_hash_add(thd->thread_events, ei->common.name, ei); 356 eina_rwlock_release(&thd->thread_events.lock);
264 } 357 }
265 log_thread_push(thd, thread_id); 358 log_thread_push(thd, thread_id);
266 } 359 }
267 else if (*eventstr == '!') 360 else if (*eventstr == '!')
268 { 361 {
269 Event_Info_Single *ei; 362 Event_Info_Single *ei;
270 ei = eina_hash_find(thd->single_events, eventstr + 1); 363
364 eina_rwlock_take_read(&thd->single_events.lock);
365 ei = eina_hash_find(thd->single_events.hash, eventstr + 1);
366 eina_rwlock_release(&thd->single_events.lock);
367
271 if (!ei) 368 if (!ei)
272 { 369 {
273 ei = calloc(1, sizeof(Event_Info_Single)); 370 ei = calloc(1, sizeof(Event_Info_Single));
371 ei->common.name = strdup(eventstr + 1);
372 ei->common.type = SINGLE_EVENT;
373 ei->threads.data = eina_array_new(ADD_PER_REALLOC);
274 unsigned int error_check; 374 unsigned int error_check;
275 for (error_check = 0; error_list[error_check] != NULL; error_check++) 375 for (error_check = 0; error_list[error_check] != NULL; error_check++)
276 { 376 {
@@ -282,13 +382,12 @@ global_log_info_update(In_Thread_Data *thd, char *eventstr, char *detailstr, lon
282 } 382 }
283 } 383 }
284 384
285 unsigned int list_size = eina_hash_population(thd->single_events); 385 eina_rwlock_take_write(&thd->single_events.lock);
386 unsigned int list_size = eina_hash_population(thd->single_events.hash);
286 if (!ei->error) 387 if (!ei->error)
287 ei->common.color = rgb_to_rgba_convert(event_colors[(list_size * 17) % COLORS_NUM]); 388 ei->common.color = rgb_to_rgba_convert(event_colors[(list_size * 17) % COLORS_NUM]);
288 ei->common.name = strdup(eventstr + 1); 389 eina_hash_add(thd->single_events.hash, ei->common.name, ei);
289 ei->common.type = SINGLE_EVENT; 390 eina_rwlock_release(&thd->single_events.lock);
290 ei->threads = eina_array_new(ADD_PER_REALLOC);
291 eina_hash_add(thd->single_events, ei->common.name, ei);
292 } 391 }
293 log_thread_push(thd, thread_id); 392 log_thread_push(thd, thread_id);
294 } 393 }
@@ -303,10 +402,14 @@ global_log_info_update(In_Thread_Data *thd, char *eventstr, char *detailstr, lon
303 else if ((!strncmp(eventstr, "*CPUUSED ", 9)) && (detailstr)) 402 else if ((!strncmp(eventstr, "*CPUUSED ", 9)) && (detailstr))
304 { 403 {
305 unsigned long long thcpu = atoll(eventstr + 9); 404 unsigned long long thcpu = atoll(eventstr + 9);
306 Eina_Array *threads = thd->all_offs->threads;
307 log_thread_push(thd, thcpu); 405 log_thread_push(thd, thcpu);
406
407 eina_rwlock_take_read(&thd->all_offs->threads.lock);
408 Eina_Array *threads = thd->all_offs->threads.data;
308 i = log_thread_slot_find(threads, thcpu); 409 i = log_thread_slot_find(threads, thcpu);
309 Log_Thread *thr = (Log_Thread *)eina_array_data_get(threads, i); 410 Log_Thread *thr = (Log_Thread *)eina_array_data_get(threads, i);
411 eina_rwlock_release(&thd->all_offs->threads.lock);
412
310 thr->last_cpu = atoi(detailstr); 413 thr->last_cpu = atoi(detailstr);
311 } 414 }
312} 415}
@@ -319,22 +422,20 @@ event_close(Event_Offsets *event, Eina_List **events)
319 Eina_Bool event_found = EINA_FALSE; 422 Eina_Bool event_found = EINA_FALSE;
320 EINA_LIST_FOREACH(*events, l, active) 423 EINA_LIST_FOREACH(*events, l, active)
321 { 424 {
322 if (strlen(event->name) == strlen(active->name)) 425 if (event->event_info == active->event_info)
323 if (!strncmp(event->name + 1, active->name + 1, strlen(event->name) - 1)) 426 if ((active->obj == event->obj) && (active->thread_slot == event->thread_slot))
324 if ((active->obj == event->obj) && (active->thread_slot == event->thread_slot)) 427 {
325 { 428 if (!event_found)
326 if (!event_found) 429 {
327 { 430 active->offset_finish = event->offset_finish;
328 active->offset_finish = event->offset_finish; 431 active->time_end = event->time_end;
329 active->time_end = event->time_end; 432 }
330 } 433 *events = eina_list_remove(*events, active);
331 *events = eina_list_remove(*events, active); 434 event_found = EINA_TRUE;
332 free(active->name); 435 }
333 event_found = EINA_TRUE;
334 }
335 } 436 }
336 if (!event_found) 437 if (!event_found)
337 ERR("Unexpected end of event %s in first read", event->name); 438 DBG("Unexpected end of event %s in first read", event->event_info->common.name);
338 return event_found; 439 return event_found;
339} 440}
340 441
@@ -370,43 +471,67 @@ eina_array_sort_insert(Eina_Array *arr, Event_Offsets *event)
370 eina_array_data_set(arr, neighbour_index, event); 471 eina_array_data_set(arr, neighbour_index, event);
371} 472}
372 473
474static Thread_Events *
475_thread_events_array_get(Eina_Array *threads, Log_Thread *thr)
476{
477 Thread_Events *te;
478 unsigned int i;
479 for (i = 0; i < eina_array_count(threads); i++)
480 {
481 te = eina_array_data_get(threads, i);
482 if (thr == te->thread) break;
483 }
484 if (i == eina_array_count(threads))
485 {
486 te = calloc(1, sizeof(Thread_Events));
487 te->thread = thr;
488 te->thread_events.data = eina_array_new(ADD_PER_REALLOC);
489 eina_rwlock_new(&te->thread_events.lock);
490 eina_array_push(threads, te);
491 }
492 return te;
493}
494
373static void 495static void
374event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt, 496event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
375 char *eventstr, char *detailstr, long event_offset, 497 char *eventstr, char *detailstr, long event_offset,
376 Eina_Evlog_Item item, double event_time) 498 Eina_Evlog_Item item, double event_time)
377{ 499{
378 thd->last_event_is_unexpected_end = EINA_FALSE; 500 thd->last_event_is_unexpected_end = EINA_FALSE;
379 Eina_Array *threads = thd->all_offs->threads; 501 Eina_Array *threads;
502 Log_Thread *thr;
380 unsigned int i; 503 unsigned int i;
381 if (*eventstr == '+') 504 if (*eventstr == '+')
382 { 505 {
383 Event_Offsets *event = calloc(1, sizeof(Event_Offsets)); 506 Event_Offsets *event = calloc(1, sizeof(Event_Offsets));
384 event->offset_start = event_offset; 507 event->offset_start = event_offset;
385 event->time_start = event_time; 508 event->time_start = event_time;
386 event->name = strdup(eventstr);
387 i = log_thread_slot_find(threads, item.thread);
388 event->thread_slot = i;
389 event->obj = item.obj; 509 event->obj = item.obj;
390 ptt->active_events = eina_list_append(ptt->active_events, event); 510 ptt->active_events = eina_list_append(ptt->active_events, event);
391 Log_Thread *thr = eina_array_data_get(threads, i); 511
512 eina_rwlock_take_read(&thd->all_offs->threads.lock);
513 threads = thd->all_offs->threads.data;
514 i = log_thread_slot_find(threads, item.thread);
515 thr = eina_array_data_get(threads, i);
516 eina_rwlock_release(&thd->all_offs->threads.lock);
517
518 event->thread_slot = i;
392 519
393 Event_Info_Thread *ei; 520 Event_Info_Thread *ei;
394 Thread_Events *te; 521 Thread_Events *te;
395 ei = eina_hash_find(thd->thread_events, eventstr + 1); 522
396 for (i = 0; i < eina_array_count(ei->threads); i++) 523 eina_rwlock_take_read(&thd->thread_events.lock);
397 { 524 ei = eina_hash_find(thd->thread_events.hash, eventstr + 1);
398 te = eina_array_data_get(ei->threads, i); 525 eina_rwlock_release(&thd->thread_events.lock);
399 if (thr == te->thread) break;
400 }
401 if (i == eina_array_count(ei->threads))
402 {
403 te = calloc(1, sizeof(Thread_Events));
404 te->thread = thr;
405 te->pointers = eina_array_new(ADD_PER_REALLOC);
406 eina_array_push(ei->threads, te);
407 }
408 eina_array_sort_insert(te->pointers, event);
409 event->event_info = (Event_Info *)ei; 526 event->event_info = (Event_Info *)ei;
527
528 eina_rwlock_take_write(&ei->threads.lock);
529 te = _thread_events_array_get(ei->threads.data, thr);
530 eina_rwlock_release(&ei->threads.lock);
531
532 eina_rwlock_take_write(&te->thread_events.lock);
533 eina_array_sort_insert(te->thread_events.data, event);
534 eina_rwlock_release(&te->thread_events.lock);
410 } 535 }
411 else if (*eventstr == '>') 536 else if (*eventstr == '>')
412 { 537 {
@@ -414,25 +539,41 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
414 Event_Info_State *ei; 539 Event_Info_State *ei;
415 event->offset_start = event_offset; 540 event->offset_start = event_offset;
416 event->time_start = event_time; 541 event->time_start = event_time;
417 event->name = strdup(eventstr);
418 event->thread_slot = -1; 542 event->thread_slot = -1;
419 event->obj = item.obj; 543 event->obj = item.obj;
420 ei = eina_hash_find(thd->states, eventstr + 1); 544
545
546 eina_rwlock_take_read(&thd->state_events.lock);
547 ei = eina_hash_find(thd->state_events.hash, eventstr + 1);
548 eina_rwlock_release(&thd->state_events.lock);
549
421 ptt->active_events = eina_list_append(ptt->active_events, event); 550 ptt->active_events = eina_list_append(ptt->active_events, event);
551
552 eina_rwlock_take_write(&ei->state_events.lock);
553 eina_array_sort_insert(ei->state_events.data, event);
554 eina_rwlock_release(&ei->state_events.lock);
555
422 event->grid_slot = ei->grid_slot * 2; 556 event->grid_slot = ei->grid_slot * 2;
423 eina_array_sort_insert(ei->pointers, event);
424 event->event_info = (Event_Info *)ei; 557 event->event_info = (Event_Info *)ei;
425 } 558 }
426 else if (*eventstr == '-') 559 else if (*eventstr == '-')
427 { 560 {
561 eina_rwlock_take_read(&thd->all_offs->threads.lock);
562 threads = thd->all_offs->threads.data;
428 i = log_thread_slot_find(threads, item.thread); 563 i = log_thread_slot_find(threads, item.thread);
564 eina_rwlock_release(&thd->all_offs->threads.lock);
565
429 Event_Offsets event; 566 Event_Offsets event;
430 event.offset_finish = event_offset; 567 event.offset_finish = event_offset;
431 event.time_end = event_time; 568 event.time_end = event_time;
432 569
433 event.name = eventstr;
434 event.thread_slot = i; 570 event.thread_slot = i;
435 event.obj = item.obj; 571 event.obj = item.obj;
572
573 eina_rwlock_take_read(&thd->thread_events.lock);
574 event.event_info = eina_hash_find(thd->thread_events.hash, eventstr + 1);
575 eina_rwlock_release(&thd->thread_events.lock);
576
436 if (!event_close(&event, &(ptt->active_events))) 577 if (!event_close(&event, &(ptt->active_events)))
437 thd->last_event_is_unexpected_end = EINA_TRUE; 578 thd->last_event_is_unexpected_end = EINA_TRUE;
438 } 579 }
@@ -441,9 +582,13 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
441 Event_Offsets event; 582 Event_Offsets event;
442 event.offset_finish = event_offset; 583 event.offset_finish = event_offset;
443 event.time_end = event_time; 584 event.time_end = event_time;
444 event.name = eventstr;
445 event.thread_slot = -1; 585 event.thread_slot = -1;
446 event.obj = item.obj; 586 event.obj = item.obj;
587
588 eina_rwlock_take_read(&thd->state_events.lock);
589 event.event_info = eina_hash_find(thd->state_events.hash, eventstr + 1);
590 eina_rwlock_release(&thd->state_events.lock);
591
447 if (!event_close(&event, &(ptt->active_events))) 592 if (!event_close(&event, &(ptt->active_events)))
448 thd->last_event_is_unexpected_end = EINA_TRUE; 593 thd->last_event_is_unexpected_end = EINA_TRUE;
449 } 594 }
@@ -453,9 +598,16 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
453 unsigned long long thcpu = atoll(eventstr + 9); 598 unsigned long long thcpu = atoll(eventstr + 9);
454 event->usage = atoi(detailstr); 599 event->usage = atoi(detailstr);
455 event->common.timestamp = event_time; 600 event->common.timestamp = event_time;
601
602 eina_rwlock_take_read(&thd->all_offs->threads.lock);
603 threads = thd->all_offs->threads.data;
456 i = log_thread_slot_find(threads, thcpu); 604 i = log_thread_slot_find(threads, thcpu);
457 Log_Thread *thr = eina_array_data_get(threads, i); 605 thr = eina_array_data_get(threads, i);
458 eina_array_push(thr->cpuused_events, event); 606 eina_rwlock_release(&thd->all_offs->threads.lock);
607
608 eina_rwlock_take_write(&thr->cpuused_events.lock);
609 eina_array_push(thr->cpuused_events.data, event);
610 eina_rwlock_release(&thr->cpuused_events.lock);
459 } 611 }
460 else if ((!strncmp(eventstr, "*CPUFREQ ", 9)) && (detailstr)) 612 else if ((!strncmp(eventstr, "*CPUFREQ ", 9)) && (detailstr))
461 { 613 {
@@ -463,7 +615,10 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
463 event->core = atoi(eventstr + 9); 615 event->core = atoi(eventstr + 9);
464 event->mhz = atoi(detailstr); 616 event->mhz = atoi(detailstr);
465 event->common.timestamp = event_time; 617 event->common.timestamp = event_time;
466 eina_array_push(thd->all_offs->cpufreqs, event); 618
619 eina_rwlock_take_write(&thd->all_offs->cpufreqs.lock);
620 eina_array_push(thd->all_offs->cpufreqs.data, event);
621 eina_rwlock_release(&thd->all_offs->cpufreqs.lock);
467 622
468 int cpu = atoi(eventstr + 9); 623 int cpu = atoi(eventstr + 9);
469 ptt->lastcpufreq_value[cpu] = atoi(detailstr); 624 ptt->lastcpufreq_value[cpu] = atoi(detailstr);
@@ -473,28 +628,32 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
473 Event_Offsets *event = calloc(1, sizeof(Event_Offsets)); 628 Event_Offsets *event = calloc(1, sizeof(Event_Offsets));
474 event->offset_start = event_offset; 629 event->offset_start = event_offset;
475 event->time_start = event_time; 630 event->time_start = event_time;
631 event->obj = item.obj;
632
633 eina_rwlock_take_read(&thd->all_offs->threads.lock);
634 threads = thd->all_offs->threads.data;
476 i = log_thread_slot_find(threads, item.thread); 635 i = log_thread_slot_find(threads, item.thread);
636 thr = eina_array_data_get(threads, i);
637 eina_rwlock_release(&thd->all_offs->threads.lock);
638
477 event->thread_slot = i; 639 event->thread_slot = i;
478 event->obj = item.obj;
479 Log_Thread *thr = eina_array_data_get(threads, i);
480 640
481 Event_Info_Single *ei; 641 Event_Info_Single *ei;
482 Thread_Events *te; 642 Thread_Events *te;
483 ei = eina_hash_find(thd->single_events, eventstr + 1); 643
484 for (i = 0; i < eina_array_count(ei->threads); i++) 644 eina_rwlock_take_read(&thd->single_events.lock);
485 { 645 ei = eina_hash_find(thd->single_events.hash, eventstr + 1);
486 te = eina_array_data_get(ei->threads, i); 646 eina_rwlock_release(&thd->single_events.lock);
487 if (thr == te->thread) break; 647
488 }
489 if (i == eina_array_count(ei->threads))
490 {
491 te = calloc(1, sizeof(Thread_Events));
492 te->thread = thr;
493 te->pointers = eina_array_new(ADD_PER_REALLOC);
494 eina_array_push(ei->threads, te);
495 }
496 eina_array_sort_insert(te->pointers, event);
497 event->event_info = (Event_Info *)ei; 648 event->event_info = (Event_Info *)ei;
649
650 eina_rwlock_take_write(&ei->threads.lock);
651 te = _thread_events_array_get(ei->threads.data, thr);
652 eina_rwlock_release(&ei->threads.lock);
653
654 eina_rwlock_take_write(&te->thread_events.lock);
655 eina_array_sort_insert(te->thread_events.data, event);
656 eina_rwlock_release(&te->thread_events.lock);
498 } 657 }
499 else 658 else
500 { 659 {
@@ -503,27 +662,32 @@ event_offsets_collect(In_Thread_Data *thd, Pointer_To_Time *ptt,
503} 662}
504 663
505static double 664static double
506max_cpu_freq_find(In_Thread_Data *thd) 665_cpu_freq_sum(In_Thread_Data *thd)
507{ 666{
508 double max_cpu = 0; 667 double sum = 0;
509 unsigned int i; 668 unsigned int i;
510 for (i = 0; i < thd->stored_data->cpucores; i++) 669 for (i = 0; i < thd->stored_data->cpucores; i++)
511 max_cpu += thd->stored_data->cpumhzlast[i]; 670 sum += thd->stored_data->cpumhzlast[i];
512 return max_cpu; 671 return sum;
513} 672}
514 673
515static double 674static double
516max_cpu_use_find(In_Thread_Data *thd) 675_cpu_use_sum(In_Thread_Data *thd)
517{ 676{
518 double max_cpu = 0; 677 double sum = 0;
519 unsigned int i; 678 unsigned int i;
520 Eina_Array *threads = thd->all_offs->threads; 679
680 Eina_Array *threads;
681 eina_rwlock_take_read(&thd->all_offs->threads.lock);
682 threads = thd->all_offs->threads.data;
521 for (i = 0; i < eina_array_count(threads); i++) 683 for (i = 0; i < eina_array_count(threads); i++)
522 { 684 {
523 Log_Thread *thr = (Log_Thread *)eina_array_data_get(threads, i); 685 Log_Thread *thr = (Log_Thread *)eina_array_data_get(threads, i);
524 max_cpu += thr->last_cpu; 686 sum += thr->last_cpu;
525 } 687 }
526 return max_cpu; 688 eina_rwlock_release(&thd->all_offs->threads.lock);
689
690 return sum;
527} 691}
528 692
529static void 693static void
@@ -531,9 +695,9 @@ graph_data_collect(In_Thread_Data *thd, Graph_Data *feedback, char *type)
531{ 695{
532 static Eina_Bool increased = EINA_FALSE; 696 static Eina_Bool increased = EINA_FALSE;
533 double time = thd->duration; 697 double time = thd->duration;
534 double max_cpu = 0; 698 double average_cpu = 0;
535 if (!strcmp(type, "used")) max_cpu = max_cpu_use_find(thd); 699 if (!strcmp(type, "used")) average_cpu = _cpu_use_sum(thd);
536 else if (!strcmp(type, "freq")) max_cpu = max_cpu_freq_find(thd); 700 else if (!strcmp(type, "freq")) average_cpu = _cpu_freq_sum(thd);
537 701
538 if (feedback->point_num % ADD_PER_REALLOC == 0) 702 if (feedback->point_num % ADD_PER_REALLOC == 0)
539 { 703 {
@@ -544,7 +708,7 @@ graph_data_collect(In_Thread_Data *thd, Graph_Data *feedback, char *type)
544 } 708 }
545 709
546 feedback->points[feedback->point_num] = time; 710 feedback->points[feedback->point_num] = time;
547 feedback->values[feedback->point_num] = max_cpu; 711 feedback->values[feedback->point_num] = average_cpu;
548 712
549 if (feedback->point_num) 713 if (feedback->point_num)
550 { 714 {
@@ -567,82 +731,29 @@ graph_data_collect(In_Thread_Data *thd, Graph_Data *feedback, char *type)
567 feedback->point_num++; 731 feedback->point_num++;
568} 732}
569 733
570static Eina_Bool
571log_block_info_first_read(In_Thread_Data *thd)
572{
573 if (ecore_thread_check(thd->thread)) return EINA_FALSE;
574 unsigned int header[3];
575
576 if (fread(header, 12, 1, thd->log_file) != 1) return EINA_FALSE;
577 if (header[0] != MAGIC_LOG_CHECK) return EINA_FALSE;
578 Navigation_Graphs *feedback = (Navigation_Graphs *) calloc(1, sizeof(Navigation_Graphs));
579 feedback->cpuuse = (Graph_Data *) calloc(1, sizeof(Graph_Data));
580 feedback->cpufreq = (Graph_Data *) calloc(1, sizeof(Graph_Data));
581
582 unsigned int blocksize = header[1];
583 Pointer_To_Time *ptt = (Pointer_To_Time*) calloc(1, sizeof(Pointer_To_Time));
584
585 if (thd->blocks)
586 {
587 Pointer_To_Time *last_ptt;
588 last_ptt = ((Pointer_To_Time *)eina_list_last_data_get(thd->blocks));
589 ptt->active_events = eina_list_clone(last_ptt->active_events);
590 memcpy(ptt->lastcpufreq_value, last_ptt->lastcpufreq_value, MAX_CPU_CORES * sizeof(int));
591
592 ptt->block_end += last_ptt->block_end;
593 ptt->block_start = last_ptt->block_end;
594 ptt->last_event_time = thd->duration;
595 }
596 ptt->block_end += sizeof(header) + blocksize;
597 ptt->block_start += sizeof(header);
598 thd->blocks = eina_list_append(thd->blocks, ptt);
599
600 void *buf = malloc(blocksize);
601 if (buf)
602 {
603 void *ptr, *end;
604
605 if (fread(buf, blocksize, 1, thd->log_file) != 1)
606 {
607 free(buf);
608 return EINA_FALSE;
609 }
610 ptr = buf;
611 long start_pointer = (long) ptr;
612 end = (char *)ptr + blocksize;
613 while ((ptr = log_block_event_read(thd, ptr, end, start_pointer,
614 feedback, EINA_FALSE)));
615 ptt->last_event_time = thd->duration;
616 free(buf);
617 }
618
619 if (ecore_thread_check(thd->thread)) return EINA_FALSE;
620 else ecore_thread_feedback(thd->thread, feedback);
621 return EINA_TRUE;
622}
623
624static void 734static void
625_log_file_first_read_cancel(void *data EINA_UNUSED, Ecore_Thread *thread) 735_log_file_first_read_cancel(void *data EINA_UNUSED, Ecore_Thread *thread)
626{ 736{
627 if (th == thread) th = NULL; 737 if (logload_data->log_read_thread == thread)
738 logload_data->log_read_thread = NULL;
739 eina_evlog("!Thread canceled", NULL, 0.0, NULL);
628} 740}
629 741
630static void 742static void
631_log_file_first_read_end(void *data, Ecore_Thread *thread) 743_log_file_first_read_end(void *data, Ecore_Thread *thread)
632{ 744{
633 if (th == thread) th = NULL; 745 if (logload_data->log_read_thread == thread)
634 In_Thread_Data *thd = (In_Thread_Data*) data; 746 logload_data->log_read_thread = NULL;
635 evas_object_smart_callback_call(thd->win, "logload,end", thd); 747 eina_evlog("!Thread ended successfully", NULL, 0.0, NULL);
636 if (thd->duration <= 0) return; 748 In_Thread_Data *thd = data;
749 evas_object_smart_callback_call(thd->win, "logload,file,read,end", thd);
637 evas_object_smart_callback_call(thd->win, "graph,draw", thd); 750 evas_object_smart_callback_call(thd->win, "graph,draw", thd);
638 evas_object_smart_callback_call(thd->win,
639 "display,interval",
640 &start_range);
641} 751}
642 752
643static void 753static void
644_log_file_first_read_feedback(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) 754_log_file_first_read_feedback(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
645{ 755{
756 eina_evlog("+feedback from thread", NULL, 0.0, NULL);
646 In_Thread_Data *thd = data; 757 In_Thread_Data *thd = data;
647 if (!thd->navi_area_displayed) 758 if (!thd->navi_area_displayed)
648 { 759 {
@@ -665,30 +776,32 @@ _log_file_first_read_feedback(void *data, Ecore_Thread *thread EINA_UNUSED, void
665 graph_data_free(feedback->cpufreq); 776 graph_data_free(feedback->cpufreq);
666 // It is unnecessary to free feedback->activity: it was merged to thd->navi; 777 // It is unnecessary to free feedback->activity: it was merged to thd->navi;
667 free(feedback); 778 free(feedback);
779 eina_evlog("-feedback from thread", NULL, 0.0, NULL);
668} 780}
669 781
670static void 782static void
671_log_file_first_read(void *data, Ecore_Thread *thread) 783_log_file_first_read(void *data, Ecore_Thread *thread EINA_UNUSED)
672{ 784{
673 eina_evlog("+first_read", NULL, 0.0, NULL); 785 eina_evlog("+first_read", NULL, 0.0, NULL);
674 In_Thread_Data *thd = (In_Thread_Data*) data; 786 In_Thread_Data *thd = (In_Thread_Data*) data;
675 thd->thread = thread; 787 while (_log_block_process(thd));
676 while (log_block_info_first_read(thd)); 788 /*NULL*/
677 eina_evlog("-first_read", NULL, 0.0, "Log file first read success"); 789 eina_evlog("-first_read", NULL, 0.0, "Log file first read success");
678} 790}
679 791
680/*
681 * Third parametr event_info must be not NULL.
682 * If you want use this callback, you must check it before.
683 * Now it was checked before call
684 */
685static void 792static void
686_log_file_load(void* data EINA_UNUSED, Evas_Object *obj, void *event_info) 793_log_file_load(void* data EINA_UNUSED, Evas_Object *obj, void *event_info)
687{ 794{
795 if (!event_info)
796 {
797 ERR("Empty path to log.");
798 return;
799 }
688 int header; 800 int header;
689 char *log_path = event_info; 801 char *log_path = event_info;
690 FILE *log_file = fopen(log_path, "rb"); 802 FILE *log_file = fopen(log_path, "rb");
691 DBG("firs read of %s", log_path); 803 In_Thread_Data *thd = NULL;
804 DBG("first read of %s", log_path);
692 if (!log_file) 805 if (!log_file)
693 { 806 {
694 ERR("Log file is not exist"); 807 ERR("Log file is not exist");
@@ -707,75 +820,55 @@ _log_file_load(void* data EINA_UNUSED, Evas_Object *obj, void *event_info)
707 return; 820 return;
708 } 821 }
709 822
710 if (th && !ecore_thread_check(th))
711 ecore_thread_cancel(th);
712 evas_object_smart_callback_call(obj, "log,close", NULL); 823 evas_object_smart_callback_call(obj, "log,close", NULL);
713 824 logload_data = calloc(1, sizeof(Logload_Data));
714 In_Thread_Data *thd = in_thread_data_init(); 825 logload_data->thd = in_thread_data_init();
715 evas_object_data_set(obj, "opened log", thd); 826 thd = logload_data->thd;
716 thd->log_path = strdup(log_path); 827 thd->log_path = strdup(log_path);
717 thd->log_file = log_file; 828 logload_data->file = log_file;
718 fseek (log_file, 0, SEEK_SET); 829 fseek(log_file, 0, SEEK_SET);
719 thd->win = obj; 830 thd->win = obj;
720 831
721 th = ecore_thread_feedback_run(_log_file_first_read, 832 logload_data->log_read_thread = ecore_thread_feedback_run(_log_file_first_read,
722 _log_file_first_read_feedback, 833 _log_file_first_read_feedback,
723 _log_file_first_read_end, 834 _log_file_first_read_end,
724 _log_file_first_read_cancel, 835 _log_file_first_read_cancel,
725 thd, EINA_FALSE); 836 thd, EINA_FALSE);
726 837
727 if (!th) CRITICAL("Failed create thread for processing log file"); 838 if (!logload_data->log_read_thread)
839 CRITICAL("Failed create thread for processing log file");
728} 840}
729 841
730static void 842static void
731_log_close_cb(void* data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) 843_log_close_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
732{ 844{
733 In_Thread_Data *thd; 845 _logload_data_free();
734 if (th && !ecore_thread_check(th))
735 ecore_thread_cancel(th);
736 if ((thd = evas_object_data_del(obj, "opened log")))
737 in_thread_data_free(thd);
738} 846}
739 847
740
741/* realtime functios */ 848/* realtime functios */
742static void 849static void
743realtime_data_free() 850_stream_processing_stop_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
744{
745 if (!rd) return;
746 if (rd->thd) in_thread_data_free(rd->thd);
747 if (rd->file) fclose(rd->file);
748 rd->file = NULL;
749 rd->first_block_drawed = EINA_FALSE;
750}
751
752static void
753_realtime_app_change(void* data EINA_UNUSED, Evas_Object *obj, void *event_info)
754{ 851{
755 evas_object_smart_callback_call(obj, "log,close", NULL); 852 evas_object_smart_callback_call(obj, "log,close", NULL);
756 int pid = *(int *)event_info; 853 int pid = *(int *)event_info;
757 if (!rd) 854 char path[STRING_LENGTH] = "";
758 {
759 ERR("Memory for Realtime_Data struct wasn`n allocated.");
760 return;
761 }
762 855
763 realtime_data_free(); 856 logload_data = calloc(1, sizeof(Logload_Data));
764 rd->thd = in_thread_data_init(); 857 logload_data->thd = in_thread_data_init();
765 rd->thd->win = obj; 858 logload_data->thd->win = obj;
766 snprintf(rd->path, sizeof(rd->path), "/tmp/efl_debug_evlog-%d.log", pid); 859 snprintf(path, STRING_LENGTH, "/tmp/efl_debug_evlog-%d.log", pid);
860 logload_data->thd->log_path = strdup(path);
767 graph_update_rate = 5; 861 graph_update_rate = 5;
768 rd->file = fopen(rd->path, "wb"); 862 logload_data->file = fopen(path, "wb");
769 evas_object_smart_callback_call(obj, "realtime,register", NULL);
770} 863}
771 864
772static void * 865static void *
773log_block_event_read(In_Thread_Data *thd, void *ptr, void *end, 866_log_block_event_read(In_Thread_Data *thd, void *ptr, void *end,
774 long start_pointer, Navigation_Graphs *feedback, 867 long start_pointer, Navigation_Graphs *feedback,
775 Eina_Bool realtime_status) 868 Log_Source_Type source_type)
776{ 869{
777 if (!realtime_status) 870 if (source_type == LOG_SOURCE_FILE)
778 if (ecore_thread_check(thd->thread)) return NULL; 871 if (ecore_thread_check(logload_data->log_read_thread)) return NULL;
779 char *data = ptr; 872 char *data = ptr;
780 char *dataend = end; 873 char *dataend = end;
781 Eina_Evlog_Item item; 874 Eina_Evlog_Item item;
@@ -803,9 +896,8 @@ log_block_event_read(In_Thread_Data *thd, void *ptr, void *end,
803 else 896 else
804 { 897 {
805 ERR("Maybe, your log is outdated and Eina_Evlog_Item was changed"); 898 ERR("Maybe, your log is outdated and Eina_Evlog_Item was changed");
806 if (!realtime_status) 899 if (source_type == LOG_SOURCE_FILE)
807 if (!ecore_thread_check(thd->thread)) 900 _log_read_thread_cancel();
808 ecore_thread_cancel(thd->thread);
809 return NULL; 901 return NULL;
810 } 902 }
811 if (item.detail_offset >= sizeof(Eina_Evlog_Item)) 903 if (item.detail_offset >= sizeof(Eina_Evlog_Item))
@@ -823,11 +915,16 @@ log_block_event_read(In_Thread_Data *thd, void *ptr, void *end,
823 */ 915 */
824 if (!thd->last_event_is_unexpected_end) 916 if (!thd->last_event_is_unexpected_end)
825 { 917 {
826 unsigned int i = log_thread_slot_find(thd->all_offs->threads, item.thread);
827 Log_Thread *thread; 918 Log_Thread *thread;
919 unsigned int i;
920
828 if (*eventstr == '+') 921 if (*eventstr == '+')
829 { 922 {
830 thread = eina_array_data_get(thd->all_offs->threads, i); 923 eina_rwlock_take_read(&thd->all_offs->threads.lock);
924 i = log_thread_slot_find(thd->all_offs->threads.data, item.thread);
925 thread = eina_array_data_get(thd->all_offs->threads.data, i);
926 eina_rwlock_release(&thd->all_offs->threads.lock);
927
831 thread->cur_events++; 928 thread->cur_events++;
832 if (thread->cur_events > thread->max_events) 929 if (thread->cur_events > thread->max_events)
833 thread->max_events = thread->cur_events; 930 thread->max_events = thread->cur_events;
@@ -842,7 +939,11 @@ log_block_event_read(In_Thread_Data *thd, void *ptr, void *end,
842 } 939 }
843 else if (*eventstr == '-') 940 else if (*eventstr == '-')
844 { 941 {
845 thread = eina_array_data_get(thd->all_offs->threads, i); 942 eina_rwlock_take_read(&thd->all_offs->threads.lock);
943 i = log_thread_slot_find(thd->all_offs->threads.data, item.thread);
944 thread = eina_array_data_get(thd->all_offs->threads.data, i);
945 eina_rwlock_release(&thd->all_offs->threads.lock);
946
846 thread->cur_events--; 947 thread->cur_events--;
847 if (thread->cur_events < 0) 948 if (thread->cur_events < 0)
848 { 949 {
@@ -880,14 +981,15 @@ log_block_event_read(In_Thread_Data *thd, void *ptr, void *end,
880} 981}
881 982
882static Eina_Bool 983static Eina_Bool
883log_block_info_realtime_read(Stream_Block_Data *block_data) 984_log_block_info_read(In_Thread_Data *thd, Stream_Block_Data *block_data,
985 Log_Source_Type source_type)
884{ 986{
885 In_Thread_Data *thd = rd->thd; 987 eina_evlog("+log_block_info", NULL, 0.0, NULL);
886 Navigation_Graphs *feedback = (Navigation_Graphs *) calloc(1, sizeof(Navigation_Graphs)); 988 Navigation_Graphs *feedback = (Navigation_Graphs *) calloc(1, sizeof(Navigation_Graphs));
887 feedback->cpuuse = (Graph_Data *) calloc(1, sizeof(Graph_Data)); 989 feedback->cpuuse = (Graph_Data *) calloc(1, sizeof(Graph_Data));
888 feedback->cpufreq = (Graph_Data *) calloc(1, sizeof(Graph_Data)); 990 feedback->cpufreq = (Graph_Data *) calloc(1, sizeof(Graph_Data));
889 991
890 unsigned int blocksize = block_data->size - 4; 992 unsigned int blocksize = block_data->size;
891 Pointer_To_Time *ptt = (Pointer_To_Time*) calloc(1, sizeof(Pointer_To_Time)); 993 Pointer_To_Time *ptt = (Pointer_To_Time*) calloc(1, sizeof(Pointer_To_Time));
892 994
893 if (thd->blocks) 995 if (thd->blocks)
@@ -899,6 +1001,7 @@ log_block_info_realtime_read(Stream_Block_Data *block_data)
899 1001
900 ptt->block_end += last_ptt->block_end; 1002 ptt->block_end += last_ptt->block_end;
901 ptt->block_start = last_ptt->block_end; 1003 ptt->block_start = last_ptt->block_end;
1004 ptt->last_event_time = thd->duration;
902 } 1005 }
903 ptt->block_end += 12 + blocksize; 1006 ptt->block_end += 12 + blocksize;
904 ptt->block_start += 12; 1007 ptt->block_start += 12;
@@ -909,15 +1012,60 @@ log_block_info_realtime_read(Stream_Block_Data *block_data)
909 { 1012 {
910 void *ptr, *end; 1013 void *ptr, *end;
911 1014
912 ptr = (char *)buf + 4; 1015 ptr = (char *)buf;
913 long start_pointer = (long) ptr; 1016 long start_pointer = (long) ptr;
914 end = (char *)ptr + blocksize; 1017 end = (char *)ptr + blocksize;
915 while ((ptr = log_block_event_read(thd, ptr, end, start_pointer, 1018 while ((ptr = _log_block_event_read(thd, ptr, end, start_pointer,
916 feedback, EINA_TRUE))); 1019 feedback, source_type)));
917 ptt->last_event_time = thd->duration; 1020 ptt->last_event_time = thd->duration;
1021 /*NULL*/
1022 }
1023
1024 if (source_type == LOG_SOURCE_STREAM)
1025 _log_file_first_read_feedback(thd, NULL, feedback);
1026 else
1027 ecore_thread_feedback(logload_data->log_read_thread, feedback);
1028 eina_evlog("-log_block_info", NULL, 0.0, NULL);
1029 return EINA_TRUE;
1030}
1031
1032static void
1033_first_block_display(void *data)
1034{
1035 eina_evlog("+first_block_display", NULL, 0.0, NULL);
1036 In_Thread_Data *thd = data;
1037 thd->stored_data->interval = start_range;
1038 evas_object_smart_callback_call(thd->win, "logload,end", thd);
1039 Time_Range test = DEFAULT_START_RANGE;
1040 evas_object_smart_callback_call(thd->win, "display,interval", &test);
1041 eina_evlog("-first_block_display", NULL, 0.0, NULL);
1042}
1043
1044static Eina_Bool
1045_log_block_process(In_Thread_Data *thd)
1046{
1047 if (ecore_thread_check(logload_data->log_read_thread)) return EINA_FALSE;
1048 unsigned int header[3];
1049
1050 if (fread(header, 12, 1, logload_data->file) != 1) return EINA_FALSE;
1051 if (header[0] != MAGIC_LOG_CHECK) return EINA_FALSE;
1052
1053 unsigned int blocksize = header[1];
1054 void *buf = malloc(blocksize);
1055 if (fread(buf, blocksize, 1, logload_data->file) != 1)
1056 {
1057 free(buf);
1058 return EINA_FALSE;
918 } 1059 }
919 1060
920 _log_file_first_read_feedback(rd->thd, NULL, feedback); 1061 Stream_Block_Data block_data = {blocksize, buf};
1062 _log_block_info_read(thd, &block_data, LOG_SOURCE_FILE);
1063 free(buf);
1064 if (!logload_data->first_block_drawed)
1065 {
1066 logload_data->first_block_drawed = EINA_TRUE;
1067 ecore_main_loop_thread_safe_call_async(_first_block_display, thd);
1068 }
921 return EINA_TRUE; 1069 return EINA_TRUE;
922} 1070}
923 1071
@@ -928,13 +1076,13 @@ _stream_block_process(void* data EINA_UNUSED,
928{ 1076{
929 Stream_Block_Data *block_data = event_info; 1077 Stream_Block_Data *block_data = event_info;
930 if (!block_data->size) return; 1078 if (!block_data->size) return;
931 if (!rd) 1079 if (!logload_data)
932 { 1080 {
933 ERR("Memory for Realtime_Data struct wasn`n allocated."); 1081 ERR("Memory for Logload_Data struct wasn`n allocated.");
934 return; 1082 return;
935 } 1083 }
936 1084
937 if (rd->status == DATA_STREAM_PAUSED) 1085 if (logload_data->status == DATA_STREAM_PAUSED)
938 { 1086 {
939 DBG("Stream processing paused"); 1087 DBG("Stream processing paused");
940 return; 1088 return;
@@ -944,26 +1092,22 @@ _stream_block_process(void* data EINA_UNUSED,
944 /* Log file is temporary, but it should be possible to open it from profiling tool */ 1092 /* Log file is temporary, but it should be possible to open it from profiling tool */
945 header[0] = MAGIC_LOG_CHECK; 1093 header[0] = MAGIC_LOG_CHECK;
946 header[1] = block_data->size - 4; 1094 header[1] = block_data->size - 4;
947 if ((fwrite(header, 1, 8, rd->file) < 8) || 1095 if ((fwrite(header, 1, 8, logload_data->file) < 8) ||
948 (fwrite(block_data->data, 1, block_data->size, rd->file) < block_data->size)) 1096 (fwrite(block_data->data, 1, block_data->size, logload_data->file) < block_data->size))
949 { 1097 {
950 ERR("Error writing bytes to temporary log-file"); 1098 ERR("Error writing bytes to temporary log-file");
951 return; 1099 return;
952 } 1100 }
953 if (!log_block_info_realtime_read(block_data)) return; 1101
954 if (!rd->first_block_drawed) 1102 /* Remove overflow from data block */
1103 block_data->data += sizeof(int);
1104 block_data->size -= sizeof(int);
1105 if (!_log_block_info_read(logload_data->thd, block_data, LOG_SOURCE_STREAM))
1106 return;
1107 if (!logload_data->first_block_drawed)
955 { 1108 {
956 In_Thread_Data *thd = rd->thd; 1109 logload_data->first_block_drawed = EINA_TRUE;
957 Time_Range time_range = {0, 0}; 1110 _first_block_display(logload_data->thd);
958 thd->log_path = strdup(rd->path);
959 thd->log_file = fopen(thd->log_path, "rb");
960 evas_object_smart_callback_call(thd->win, "logload,end", thd); //REPLACE
961 time_range.length = thd->duration;
962
963 evas_object_smart_callback_call(thd->win,
964 "display,interval",
965 &time_range);
966 rd->first_block_drawed = EINA_TRUE;
967 } 1111 }
968} 1112}
969/* realtime functios */ 1113/* realtime functios */
@@ -973,13 +1117,13 @@ _stream_processing_pause_cb(void *data EINA_UNUSED,
973 Evas_Object *obj EINA_UNUSED, 1117 Evas_Object *obj EINA_UNUSED,
974 void *event_info EINA_UNUSED) 1118 void *event_info EINA_UNUSED)
975{ 1119{
976 if (!rd) 1120 if (!logload_data)
977 { 1121 {
978 ERR("Memory for Realtime_Data struct wasn`n allocated."); 1122 ERR("Memory for Logload_Data struct wasn`n allocated.");
979 return; 1123 return;
980 } 1124 }
981 1125
982 rd->status = DATA_STREAM_PAUSED; 1126 logload_data->status = DATA_STREAM_PAUSED;
983} 1127}
984 1128
985static void 1129static void
@@ -987,23 +1131,21 @@ _stream_processing_resume_cb(void *data EINA_UNUSED,
987 Evas_Object *obj EINA_UNUSED, 1131 Evas_Object *obj EINA_UNUSED,
988 void *event_info EINA_UNUSED) 1132 void *event_info EINA_UNUSED)
989{ 1133{
990 if (!rd) 1134 if (!logload_data)
991 { 1135 {
992 ERR("Memory for Realtime_Data struct wasn`n allocated."); 1136 ERR("Memory for Logload_Data struct wasn`n allocated.");
993 return; 1137 return;
994 } 1138 }
995 1139
996 rd->status = DATA_STREAM_ACTIVE; 1140 logload_data->status = DATA_STREAM_ACTIVE;
997} 1141}
998 1142
999Eina_Bool 1143Eina_Bool
1000logload_init(Evas_Object* content) 1144logload_init(Evas_Object* content)
1001{ 1145{
1002 rd = (Realtime_Data *) calloc(1, sizeof(Realtime_Data));
1003 rd->status = DATA_STREAM_ACTIVE;
1004 evas_object_smart_callback_add(content, "first,read", _log_file_load, NULL); 1146 evas_object_smart_callback_add(content, "first,read", _log_file_load, NULL);
1005 evas_object_smart_callback_add(content, "log,close", _log_close_cb, NULL); 1147 evas_object_smart_callback_add(content, "log,close", _log_close_cb, NULL);
1006 evas_object_smart_callback_add(content, "stream,processing,stop", _realtime_app_change, NULL); 1148 evas_object_smart_callback_add(content, "stream,processing,stop", _stream_processing_stop_cb, NULL);
1007 evas_object_smart_callback_add(content, "stream,block,process", _stream_block_process, NULL); 1149 evas_object_smart_callback_add(content, "stream,block,process", _stream_block_process, NULL);
1008 evas_object_smart_callback_add(content, "start,range,change", _start_range_change, NULL); 1150 evas_object_smart_callback_add(content, "start,range,change", _start_range_change, NULL);
1009 evas_object_smart_callback_add(content, "stream,processing,pause", _stream_processing_pause_cb, NULL); 1151 evas_object_smart_callback_add(content, "stream,processing,pause", _stream_processing_pause_cb, NULL);
@@ -1016,18 +1158,12 @@ logload_init(Evas_Object* content)
1016Eina_Bool 1158Eina_Bool
1017logload_shutdown(Evas_Object* content) 1159logload_shutdown(Evas_Object* content)
1018{ 1160{
1019 realtime_data_free();
1020 free(rd);
1021 rd = NULL;
1022 evas_object_smart_callback_del(content, "first,read", _log_file_load); 1161 evas_object_smart_callback_del(content, "first,read", _log_file_load);
1023 evas_object_smart_callback_del(content, "log,close", _log_close_cb); 1162 evas_object_smart_callback_del(content, "log,close", _log_close_cb);
1024 evas_object_smart_callback_del(content, "stream,processing,stop", _realtime_app_change);
1025 evas_object_smart_callback_del(content, "stream,block,process", _stream_block_process); 1163 evas_object_smart_callback_del(content, "stream,block,process", _stream_block_process);
1026 evas_object_smart_callback_del(content, "start,range,change", _start_range_change); 1164 evas_object_smart_callback_del(content, "start,range,change", _start_range_change);
1027 evas_object_smart_callback_del(content, "stream,processing,stop", _realtime_app_change); 1165 evas_object_smart_callback_del(content, "stream,processing,stop", _stream_processing_stop_cb);
1028 evas_object_smart_callback_del(content, "stream,processing,pause", _stream_processing_pause_cb); 1166 evas_object_smart_callback_del(content, "stream,processing,pause", _stream_processing_pause_cb);
1029 evas_object_smart_callback_del(content, "stream,processing,resume", _stream_processing_resume_cb); 1167 evas_object_smart_callback_del(content, "stream,processing,resume", _stream_processing_resume_cb);
1030 if (th && !ecore_thread_check(th))
1031 ecore_thread_cancel(th);
1032 return EINA_TRUE; 1168 return EINA_TRUE;
1033} 1169}
diff --git a/src/lib/tasks/cpuuse.c b/src/lib/tasks/cpuuse.c
index 68002dd..e0f6cde 100644
--- a/src/lib/tasks/cpuuse.c
+++ b/src/lib/tasks/cpuuse.c
@@ -18,6 +18,7 @@ _task_cpuuse_layout_reuse(Task *data)
18 if (task->cpu_use == 0) 18 if (task->cpu_use == 0)
19 { 19 {
20 task_to_cache_queue_move((Task *)task); 20 task_to_cache_queue_move((Task *)task);
21 eina_evlog("-cpuuse_reuse", NULL, 0.0, NULL);
21 return; 22 return;
22 } 23 }
23 task_to_displayed_queue_move((Task *)task); 24 task_to_displayed_queue_move((Task *)task);
diff --git a/src/lib/ui.c b/src/lib/ui.c
index d193153..6397ef8 100644
--- a/src/lib/ui.c
+++ b/src/lib/ui.c
@@ -26,8 +26,7 @@
26 26
27static void timemarks_fill(Global_Data *gd); 27static void timemarks_fill(Global_Data *gd);
28static void _timemarks_range_labels_add(Global_Data *gd); 28static void _timemarks_range_labels_add(Global_Data *gd);
29static void _realtime_timemarks_update(void *data, Evas_Object *obj, void *event_info); 29/* events selecting */
30
31static void 30static void
32event_select_by_offsets(Global_Data *gd, char *offset_string) 31event_select_by_offsets(Global_Data *gd, char *offset_string)
33{ 32{
@@ -100,7 +99,6 @@ event_select_by_offsets(Global_Data *gd, char *offset_string)
100 log_event_strings_free(start); 99 log_event_strings_free(start);
101} 100}
102 101
103/* events selecting */
104static void 102static void
105_event_unselected_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 103_event_unselected_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
106{ 104{
@@ -238,37 +236,29 @@ _zoom_events_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, v
238} 236}
239 237
240/* background filling */ 238/* background filling */
241static Evas_Object * 239static void
242thread_background_create(Evas_Object *win, int max_events) 240_thread_grid_resize(Evas_Object *thread_grid, int max_events)
243{ 241{
244 Evas_Object *thread_grid;
245
246/* 242/*
247 * 1 for cpuuse, 2 for single events, 2 for each thread event. 243 * 1 for cpuuse, 2 for single events, 2 for each thread event.
248 */ 244 */
249 int grid_virtual_height = 1 + 2 + 2 * max_events; 245 int grid_virtual_height = 1 + 2 + 2 * max_events;
250 thread_grid = elm_grid_add(win);
251 elm_grid_size_set(thread_grid, GRID_SCALE, grid_virtual_height); 246 elm_grid_size_set(thread_grid, GRID_SCALE, grid_virtual_height);
252 evas_object_size_hint_min_set(thread_grid, 0, grid_virtual_height * 10); 247 evas_object_size_hint_min_set(thread_grid, 0, grid_virtual_height * 10);
253 return thread_grid;
254} 248}
255 249
256static Evas_Object * 250static void
257cpufreq_background_create(Evas_Object *win, int cpucores) 251_cpufreq_grid_resize(Evas_Object *freq_grid, int cpucores)
258{ 252{
259 Evas_Object *freq_grid = elm_grid_add(win);
260 elm_grid_size_set(freq_grid, GRID_SCALE, cpucores); 253 elm_grid_size_set(freq_grid, GRID_SCALE, cpucores);
261 evas_object_size_hint_min_set(freq_grid, 0, cpucores * 10); 254 evas_object_size_hint_min_set(freq_grid, 0, cpucores * 10);
262 return freq_grid;
263} 255}
264 256
265static Evas_Object * 257static void
266states_background_create(Evas_Object *win, int state_uniq) 258_states_grid_resize(Evas_Object *state_grid, int state_uniq)
267{ 259{
268 Evas_Object *state_grid = elm_grid_add(win);
269 elm_grid_size_set(state_grid, GRID_SCALE, state_uniq * 2); 260 elm_grid_size_set(state_grid, GRID_SCALE, state_uniq * 2);
270 evas_object_size_hint_min_set(state_grid, 0, state_uniq * 20); 261 evas_object_size_hint_min_set(state_grid, 0, state_uniq * 20);
271 return state_grid;
272} 262}
273 263
274static Evas_Object * 264static Evas_Object *
@@ -387,6 +377,7 @@ _event_area_select_end(void *data,
387 selected_interval.length = (end - 1.0) / (GRID_SCALE - 1.0) * 377 selected_interval.length = (end - 1.0) / (GRID_SCALE - 1.0) *
388 current_interval.length; 378 current_interval.length;
389 379
380 DBG("Here");
390 evas_object_smart_callback_call(ui->panes, 381 evas_object_smart_callback_call(ui->panes,
391 "display,interval", &selected_interval); 382 "display,interval", &selected_interval);
392 } 383 }
@@ -403,6 +394,44 @@ _event_area_select_end(void *data,
403 return; 394 return;
404} 395}
405 396
397/* navigation buttons */
398static Evas_Object *
399navigation_button_add(Global_Data *gd)
400{
401 Evas_Object *win = gd->ui->win;
402 Evas_Object *button;
403 button = elm_button_add(win);
404 evas_object_show(button);
405 evas_object_size_hint_weight_set(button, 0, EVAS_HINT_EXPAND);
406 evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
407 return button;
408}
409
410static void
411_prev_interval_display_cb(void *data,
412 Evas_Object *obj EINA_UNUSED,
413 void *event_info EINA_UNUSED)
414{
415 Global_Data *gd = data;
416 Time_Range time_range = {0, 0};
417 time_range = gd->thd->stored_data->interval;
418 time_range.start -= gd->thd->stored_data->interval.length;
419 evas_object_smart_callback_call(gd->ui->panes, "display,interval", &time_range);
420}
421
422static void
423_next_interval_display_cb(void *data,
424 Evas_Object *obj EINA_UNUSED,
425 void *event_info EINA_UNUSED)
426{
427 Global_Data *gd = data;
428 Time_Range time_range = {0, 0};
429 time_range = gd->thd->stored_data->interval;
430 time_range.start += gd->thd->stored_data->interval.length;
431 evas_object_smart_callback_call(gd->ui->panes, "display,interval", &time_range);
432}
433/* navigation buttons */
434
406static void 435static void
407_timemarks_grid_resize_cb(void *data, 436_timemarks_grid_resize_cb(void *data,
408 Evas *e EINA_UNUSED, 437 Evas *e EINA_UNUSED,
@@ -446,7 +475,8 @@ background_fill(Global_Data *gd)
446 label_size = object_width_calc(label); 475 label_size = object_width_calc(label);
447 if (label_size > biggest_label) biggest_label = label_size; 476 if (label_size > biggest_label) biggest_label = label_size;
448 bg_to_table_add(tb, 1, y, (Color){16, 16, 16, 255}); 477 bg_to_table_add(tb, 1, y, (Color){16, 16, 16, 255});
449 grids->cpufreq_grid = cpufreq_background_create(win, sd->cpucores); 478 grids->cpufreq_grid = elm_grid_add(win);
479 _cpufreq_grid_resize(grids->cpufreq_grid, sd->cpucores);
450 evas_object_size_hint_weight_set(grids->cpufreq_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 480 evas_object_size_hint_weight_set(grids->cpufreq_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
451 evas_object_size_hint_align_set(grids->cpufreq_grid, EVAS_HINT_FILL, EVAS_HINT_FILL); 481 evas_object_size_hint_align_set(grids->cpufreq_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
452 elm_table_pack(tb, grids->cpufreq_grid, 1, y++, 1, 1); 482 elm_table_pack(tb, grids->cpufreq_grid, 1, y++, 1, 1);
@@ -456,8 +486,13 @@ background_fill(Global_Data *gd)
456 label_size = object_width_calc(label); 486 label_size = object_width_calc(label);
457 if (label_size > biggest_label) biggest_label = label_size; 487 if (label_size > biggest_label) biggest_label = label_size;
458 bg_to_table_add(tb, 1, y, (Color){24, 24, 24, 255}); 488 bg_to_table_add(tb, 1, y, (Color){24, 24, 24, 255});
459 unsigned int state_num = eina_hash_population(gd->thd->states); 489
460 grids->states_grid = states_background_create(win, state_num); 490 eina_rwlock_take_read(&gd->thd->state_events.lock);
491 unsigned int state_num = eina_hash_population(gd->thd->state_events.hash);
492 eina_rwlock_release(&gd->thd->state_events.lock);
493
494 grids->states_grid = elm_grid_add(win);
495 _states_grid_resize(grids->states_grid, state_num);
461 evas_object_size_hint_weight_set(grids->states_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 496 evas_object_size_hint_weight_set(grids->states_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
462 evas_object_size_hint_align_set(grids->states_grid, EVAS_HINT_FILL, EVAS_HINT_FILL); 497 evas_object_size_hint_align_set(grids->states_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
463 elm_table_pack(tb, grids->states_grid, 1, y++, 1, 1); 498 elm_table_pack(tb, grids->states_grid, 1, y++, 1, 1);
@@ -465,9 +500,13 @@ background_fill(Global_Data *gd)
465 500
466 char buf[STRING_LENGTH]; 501 char buf[STRING_LENGTH];
467 unsigned int i; 502 unsigned int i;
468 Eina_Array *threads = gd->thd->all_offs->threads; 503 Log_Thread *thread;
469 grids->thread_grid = calloc(eina_array_count(threads), sizeof(Evas_Object *)); 504
470 for (i = 0; i < eina_array_count(threads); i++) 505 eina_rwlock_take_read(&gd->thd->all_offs->threads.lock);
506 Eina_Array *threads = gd->thd->all_offs->threads.data;
507 grids->thread_grid_arrays_size = eina_array_count(threads);
508 grids->thread_grid = calloc(grids->thread_grid_arrays_size, sizeof(Evas_Object *));
509 for (i = 0; i < grids->thread_grid_arrays_size; i++)
471 { 510 {
472 snprintf(buf, STRING_LENGTH, "<b>%i</b>", i + 1); 511 snprintf(buf, STRING_LENGTH, "<b>%i</b>", i + 1);
473 label = label_to_table_add(tb, 0, y, buf); 512 label = label_to_table_add(tb, 0, y, buf);
@@ -478,13 +517,15 @@ background_fill(Global_Data *gd)
478 bg_to_table_add(tb, 1, y, (Color){thread_grid_color, thread_grid_color, 517 bg_to_table_add(tb, 1, y, (Color){thread_grid_color, thread_grid_color,
479 thread_grid_color, 255}); 518 thread_grid_color, 255});
480 519
481 Log_Thread *thread = eina_array_data_get(threads, i); 520 thread = eina_array_data_get(threads, i);
482 grids->thread_grid[i] = thread_background_create(win, thread->max_events); 521 grids->thread_grid[i] = elm_grid_add(win);
522 _thread_grid_resize(grids->thread_grid[i], thread->max_events);
483 evas_object_size_hint_weight_set(grids->thread_grid[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 523 evas_object_size_hint_weight_set(grids->thread_grid[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
484 evas_object_size_hint_align_set(grids->thread_grid[i], EVAS_HINT_FILL, EVAS_HINT_FILL); 524 evas_object_size_hint_align_set(grids->thread_grid[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
485 elm_table_pack(tb, grids->thread_grid[i], 1, y++, 1, 1); 525 elm_table_pack(tb, grids->thread_grid[i], 1, y++, 1, 1);
486 evas_object_show(grids->thread_grid[i]); 526 evas_object_show(grids->thread_grid[i]);
487 } 527 }
528 eina_rwlock_release(&gd->thd->all_offs->threads.lock);
488 529
489 grids->over_grid = elm_grid_add(win); 530 grids->over_grid = elm_grid_add(win);
490 evas_object_size_hint_weight_set(grids->over_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 531 evas_object_size_hint_weight_set(grids->over_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -517,45 +558,157 @@ background_fill(Global_Data *gd)
517 _zoom_events_cb, gd); 558 _zoom_events_cb, gd);
518 eina_evlog("-background_fill", NULL, 0.0, NULL); 559 eina_evlog("-background_fill", NULL, 0.0, NULL);
519} 560}
520/* background filling */
521 561
522/* navigation buttons */ 562static void EINA_UNUSED
523static Evas_Object * 563_event_area_init(Global_Data *gd, In_Thread_Data *thd)
524navigation_button_add(Global_Data *gd)
525{ 564{
526 Evas_Object *win = gd->ui->win; 565 if (!thd) return;
527 Evas_Object *button; 566 Evas_Object *panes = gd->ui->panes;
528 button = elm_button_add(win); 567 if (!thd->duration)
529 evas_object_show(button); 568 {
530 evas_object_size_hint_weight_set(button, 0, EVAS_HINT_EXPAND); 569 ERR("Maybe it is not required logfile.");
531 evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); 570 thd->duration = -1;
532 return button; 571 return;
572 }
573 gd->thd = thd;
574 EVLOG_START;
575
576 evas_object_smart_callback_call(gd->ui->win, "menu,filters,enable", NULL);
577
578 Evas_Object *scroll = elm_scroller_add(gd->ui->win);
579 Evas_Object *table = elm_table_add(gd->ui->win);
580
581 evas_object_show(table);
582 elm_object_content_set(scroll, table);
583 evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
584 evas_object_size_hint_expand_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
585 elm_table_align_set(table, 0, 0);
586 gd->ui->table = table;
587
588 Evas_Object *timemark_scroll = elm_scroller_add(gd->ui->win);
589 elm_scroller_policy_set(timemark_scroll, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
590 evas_object_show(timemark_scroll);
591 Evas_Object *timemark_table = elm_table_add(gd->ui->win);
592 evas_object_size_hint_weight_set(timemark_table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
593 evas_object_size_hint_align_set(timemark_table, EVAS_HINT_FILL, EVAS_HINT_FILL);
594 elm_table_align_set(timemark_table, 0, 0);
595 evas_object_show(timemark_table);
596 elm_object_content_set(timemark_scroll, timemark_table);
597 gd->ui->timemark_table = timemark_table;
598
599 Evas_Object *layout = layout_create(gd->ui->win, PROJECT_NAME, "top_panes");
600 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
601 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
602 gd->ui->top_panes_layout = layout;
603
604 gd->ui->grids = (Grids*) calloc(1, sizeof(Grids));
605 background_fill(gd);
606
607 Evas_Object *left_button, *right_button, *left_icon, *right_icon;
608 left_button = navigation_button_add(gd);
609 right_button = navigation_button_add(gd);
610 left_icon = elm_icon_add(gd->ui->win);
611 elm_icon_standard_set(left_icon, "arrow_left");
612 right_icon = elm_icon_add(gd->ui->win);
613 elm_icon_standard_set(right_icon, "arrow_right");
614 elm_object_part_content_set(right_button, "icon", right_icon);
615 elm_object_part_content_set(left_button, "icon", left_icon);
616
617 elm_table_padding_set(table, 1, 6);
618
619 evas_object_smart_callback_add(left_button, "clicked", _prev_interval_display_cb, gd);
620 evas_object_smart_callback_add(right_button, "clicked", _next_interval_display_cb, gd);
621 elm_table_pack(timemark_table, left_button, 1, 0, 1, 1);
622 elm_table_pack(timemark_table, right_button, 3, 0, 1, 1);
623
624 evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
625 evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL);
626 evas_object_show(scroll);
627 elm_layout_content_set(layout, "scroll", scroll);
628 elm_layout_content_set(layout, "timemarks", timemark_scroll);
629 elm_object_part_content_set(panes, "top", layout);
630
631 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_DOWN,
632 _event_area_select_begin, gd->ui);
633 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_MOVE,
634 _event_area_select_move, gd->ui);
635 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_UP,
636 _event_area_select_end, gd->ui);
637
638 EVLOG_END;
533} 639}
534 640
535static void 641static void
536_prev_interval_display_cb(void *data, 642_event_area_init_cb(void *data,
537 Evas_Object *obj EINA_UNUSED, 643 Evas_Object *obj EINA_UNUSED,
538 void *event_info EINA_UNUSED) 644 void *event_info)
539{ 645{
540 Global_Data *gd = data; 646 Global_Data *gd = data;
541 Time_Range time_range = {0, 0}; 647 In_Thread_Data *thd = event_info;
542 time_range = gd->thd->stored_data->interval; 648 _event_area_init(gd, thd);
543 time_range.start -= gd->thd->stored_data->interval.length;
544 evas_object_smart_callback_call(gd->ui->panes, "display,interval", &time_range);
545} 649}
546 650
547static void 651static void
548_next_interval_display_cb(void *data, 652_background_update_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) //MERGE: Delete useless grids. Check if eventarea inited.
549 Evas_Object *obj EINA_UNUSED,
550 void *event_info EINA_UNUSED)
551{ 653{
552 Global_Data *gd = data; 654 Global_Data *gd = data;
553 Time_Range time_range = {0, 0}; 655 In_Thread_Data *thd = gd->thd;
554 time_range = gd->thd->stored_data->interval; 656 Grids *grids = gd->ui->grids;
555 time_range.start += gd->thd->stored_data->interval.length; 657 int cpucores;
556 evas_object_smart_callback_call(gd->ui->panes, "display,interval", &time_range); 658 unsigned int i, threads_count;
659 char buf_a[STRING_LENGTH];
660 Evas_Object *tb = gd->ui->table;
661 Color rgba;
662 Log_Thread *thread;
663
664 if (!grids)
665 {
666 ERR("Grids are not ready for creating background");
667 return;
668 }
669
670 cpucores = thd->stored_data->cpucores;
671 _cpufreq_grid_resize(grids->cpufreq_grid, cpucores);
672
673 eina_rwlock_take_read(&gd->thd->state_events.lock);
674 unsigned int state_num = eina_hash_population(gd->thd->state_events.hash);
675 eina_rwlock_release(&gd->thd->state_events.lock);
676 _states_grid_resize(grids->states_grid, state_num);
677
678 eina_rwlock_take_read(&gd->thd->all_offs->threads.lock);
679 threads_count = eina_array_count(thd->all_offs->threads.data);
680 grids->thread_grid = realloc(grids->thread_grid, threads_count * sizeof(Evas_Object *));
681 for (i = 0; i < grids->thread_grid_arrays_size; i++)
682 {
683 thread = eina_array_data_get(thd->all_offs->threads.data, i);
684 _thread_grid_resize(grids->thread_grid[i], thread->max_events);
685 }
686
687 for (i = grids->thread_grid_arrays_size; i < threads_count; i++)
688 {
689 snprintf(buf_a, STRING_LENGTH, "<b>%i</b>", i + 1);
690 label_to_table_add(tb, 0, i + 2, buf_a);
691
692 /* Make neighboring threads color different */
693 int thread_grid_color = 32 + ((i % 2) * 16);
694 rgba = (Color){thread_grid_color, thread_grid_color, thread_grid_color, 255};
695 bg_to_table_add(tb, 1, i + 2, rgba);
696
697 thread = eina_array_data_get(thd->all_offs->threads.data, i);
698 grids->thread_grid[i] = elm_grid_add(obj);
699 _thread_grid_resize(grids->thread_grid[i], thread->max_events);
700 evas_object_size_hint_weight_set(grids->thread_grid[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
701 evas_object_size_hint_align_set(grids->thread_grid[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
702 elm_table_pack(tb, grids->thread_grid[i], 1, i + 2, 1, 1);
703 evas_object_show(grids->thread_grid[i]);
704 }
705 grids->thread_grid_arrays_size = threads_count;
706 eina_rwlock_release(&gd->thd->all_offs->threads.lock);
707
708 elm_table_pack(tb, grids->over_grid, 1, 0, 1, grids->thread_grid_arrays_size + 2);
709 evas_object_raise(grids->over_grid);
557} 710}
558/* navigation buttons */ 711/* background filling */
559 712
560inline int 713inline int
561time_to_grid_interval_convert(double time, Time_Range interval) 714time_to_grid_interval_convert(double time, Time_Range interval)
@@ -717,94 +870,6 @@ timemarks_fill(Global_Data *gd)
717 timelines_navi_add(gd); 870 timelines_navi_add(gd);
718} 871}
719 872
720/* timemarks */
721static void
722_event_area_init_cb(void *data, Evas_Object *obj, void *event_info)
723{
724 In_Thread_Data *thd = event_info;
725 if (!thd) return;
726 Global_Data *gd = data;
727 Evas_Object *win = obj;
728 Evas_Object *panes = gd->ui->panes;
729 if (!thd->duration)
730 {
731 ERR("Maybe it is not required logfile.");
732 thd->duration = -1;
733 return;
734 }
735 gd->thd = thd;
736 EVLOG_START;
737
738 evas_object_smart_callback_call(gd->ui->win, "menu,filters,enable", NULL);
739
740 Evas_Object *scroll = elm_scroller_add(win);
741 Evas_Object *table = elm_table_add(win);
742
743 evas_object_show(table);
744 elm_object_content_set(scroll, table);
745 evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
746 evas_object_size_hint_expand_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
747 elm_table_align_set(table, 0, 0);
748 gd->ui->table = table;
749
750 Evas_Object *timemark_scroll = elm_scroller_add(win);
751 elm_scroller_policy_set(timemark_scroll, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
752 evas_object_show(timemark_scroll);
753 Evas_Object *timemark_table = elm_table_add(win);
754 evas_object_size_hint_weight_set(timemark_table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
755 evas_object_size_hint_align_set(timemark_table, EVAS_HINT_FILL, EVAS_HINT_FILL);
756 elm_table_align_set(timemark_table, 0, 0);
757 evas_object_show(timemark_table);
758 elm_object_content_set(timemark_scroll, timemark_table);
759 gd->ui->timemark_table = timemark_table;
760
761 Evas_Object *layout = layout_create(win, PROJECT_NAME, "top_panes");
762 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
763 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
764 gd->ui->top_panes_layout = layout;
765
766 gd->ui->knob = elm_progressbar_add(gd->ui->panes);
767 elm_object_style_set(gd->ui->knob, "wheel");
768 elm_progressbar_pulse_set(gd->ui->knob, EINA_TRUE);
769 elm_layout_content_set(gd->ui->top_panes_layout, "knob", gd->ui->knob);
770
771 gd->ui->grids = (Grids*) calloc(1, sizeof(Grids));
772 background_fill(gd);
773
774 Evas_Object *left_button, *right_button, *left_icon, *right_icon;
775 left_button = navigation_button_add(gd);
776 right_button = navigation_button_add(gd);
777 left_icon = elm_icon_add(win);
778 elm_icon_standard_set(left_icon, "arrow_left");
779 right_icon = elm_icon_add(win);
780 elm_icon_standard_set(right_icon, "arrow_right");
781 elm_object_part_content_set(right_button, "icon", right_icon);
782 elm_object_part_content_set(left_button, "icon", left_icon);
783
784 elm_table_padding_set(table, 1, 6);
785
786 evas_object_smart_callback_add(left_button, "clicked", _prev_interval_display_cb, gd);
787 evas_object_smart_callback_add(right_button, "clicked", _next_interval_display_cb, gd);
788 elm_table_pack(timemark_table, left_button, 1, 0, 1, 1);
789 elm_table_pack(timemark_table, right_button, 3, 0, 1, 1);
790
791 evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
792 evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL);
793 evas_object_show(scroll);
794 elm_layout_content_set(layout, "scroll", scroll);
795 elm_layout_content_set(layout, "timemarks", timemark_scroll);
796 elm_object_part_content_set(panes, "top", layout);
797
798 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_DOWN,
799 _event_area_select_begin, gd->ui);
800 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_MOVE,
801 _event_area_select_move, gd->ui);
802 evas_object_event_callback_add(table, EVAS_CALLBACK_MOUSE_UP,
803 _event_area_select_end, gd->ui);
804
805 EVLOG_END;
806}
807
808static void 873static void
809grids_clear(Global_Data *gd) 874grids_clear(Global_Data *gd)
810{ 875{
@@ -816,7 +881,7 @@ grids_clear(Global_Data *gd)
816 list_to_hide = elm_grid_children_get(grids->thread_grid[0]); 881 list_to_hide = elm_grid_children_get(grids->thread_grid[0]);
817 tasks_list_to_hide_queue_move(&gd->tasks, list_to_hide); 882 tasks_list_to_hide_queue_move(&gd->tasks, list_to_hide);
818 883
819 for (i = 1; i < eina_array_count(gd->thd->all_offs->threads); i++) 884 for (i = 1; i < eina_array_count(gd->thd->all_offs->threads.data); i++)
820 { 885 {
821 list_to_hide = elm_grid_children_get(grids->thread_grid[i]); 886 list_to_hide = elm_grid_children_get(grids->thread_grid[i]);
822 tasks_list_to_hide_queue_move(&gd->tasks, list_to_hide); 887 tasks_list_to_hide_queue_move(&gd->tasks, list_to_hide);
@@ -893,8 +958,8 @@ _interval_display_cb(void *data,
893 return; 958 return;
894 } 959 }
895 960
896 if ((cur_time_range.start == time_range->start) && 961 if ((cur_time_range.start == ret.start) &&
897 (cur_time_range.length == time_range->length)) 962 (cur_time_range.length == ret.length))
898 { 963 {
899 DBG("The same interval already displayed: [%f, %f]", time_range->start, 964 DBG("The same interval already displayed: [%f, %f]", time_range->start,
900 time_range->length); 965 time_range->length);
@@ -902,7 +967,7 @@ _interval_display_cb(void *data,
902 } 967 }
903 tasks_idler_exiter(gd); 968 tasks_idler_exiter(gd);
904 969
905 gd->thd->stored_data->interval = *time_range; 970 gd->thd->stored_data->interval = ret;
906 gd->thd->need_to_unselect = EINA_TRUE; 971 gd->thd->need_to_unselect = EINA_TRUE;
907 972
908 tasks_inlist_to_cache_move(gd->tasks.events.show); 973 tasks_inlist_to_cache_move(gd->tasks.events.show);
@@ -1379,28 +1444,17 @@ _navigation_area_change_cb(void *data,
1379/* navigation functions */ 1444/* navigation functions */
1380 1445
1381static void 1446static void
1382_realtime_timemarks_update(void *data, Evas_Object *obj, void *event_info) 1447_navi_timemarks_update(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
1383{ 1448{
1384 Global_Data *gd = data; 1449 Global_Data *gd = data;
1385 UI_Elements *ui = gd->ui; 1450 UI_Elements *ui = gd->ui;
1451 if (!gd->thd) return;
1386 if (ui->grids) 1452 if (ui->grids)
1387 { 1453 {
1388 int length;
1389 evas_object_geometry_get(ui->navi.timelines, NULL, NULL, &length, NULL);
1390 timelines_navi_add(gd); 1454 timelines_navi_add(gd);
1391 } 1455 }
1392 1456
1393 _navigation_area_change_cb(gd, obj, event_info); 1457 _navigation_area_change_cb(gd, obj, (void *)(&gd->thd->stored_data->interval));
1394}
1395
1396static void
1397_realtime_callbacks_register(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
1398{
1399 evas_object_smart_callback_priority_add(obj, "display,interval",
1400 EVAS_CALLBACK_PRIORITY_BEFORE,
1401 _event_area_init_cb, data);
1402 //evas_object_smart_callback_add(obj, "graph,draw", _navigation_area_change_cb, data);
1403 evas_object_smart_callback_add(obj, "graph,draw", _realtime_timemarks_update, data);
1404} 1458}
1405 1459
1406static void 1460static void
@@ -1627,7 +1681,10 @@ ui_init(Evas_Object *parent)
1627 evas_object_smart_callback_add(panes, "task,freq,register", _task_freq_register_cb, gd); 1681 evas_object_smart_callback_add(panes, "task,freq,register", _task_freq_register_cb, gd);
1628 evas_object_smart_callback_add(panes, "task,use,register", _task_use_register_cb, gd); 1682 evas_object_smart_callback_add(panes, "task,use,register", _task_use_register_cb, gd);
1629 1683
1630 evas_object_smart_callback_add(panes, "realtime,register", _realtime_callbacks_register, gd); 1684 evas_object_smart_callback_priority_add(panes, "display,interval",
1685 EVAS_CALLBACK_PRIORITY_BEFORE,
1686 _background_update_cb, gd);
1687 evas_object_smart_callback_add(panes, "graph,draw", _navi_timemarks_update, gd);
1631 evas_object_smart_callback_add(panes, "logload,end", _event_area_init_cb, gd); 1688 evas_object_smart_callback_add(panes, "logload,end", _event_area_init_cb, gd);
1632 evas_object_smart_callback_add(panes, "display,interval", _interval_display_cb, gd); 1689 evas_object_smart_callback_add(panes, "display,interval", _interval_display_cb, gd);
1633 evas_object_smart_callback_add(panes, "redraw,interval", _event_area_redraw_cb, gd); 1690 evas_object_smart_callback_add(panes, "redraw,interval", _event_area_redraw_cb, gd);
@@ -1643,8 +1700,6 @@ ui_init(Evas_Object *parent)
1643Eina_Bool 1700Eina_Bool
1644ui_shutdown(Evas_Object* content) 1701ui_shutdown(Evas_Object* content)
1645{ 1702{
1646 /*evas_object_smart_callback_del(content, "display,interval", _event_area_init_cb);
1647 evas_object_smart_callback_del(content, "graph,draw", _navigation_area_change_cb);*/
1648 Global_Data *gd; 1703 Global_Data *gd;
1649 if ((gd = evas_object_data_del(content, "GLOBAL_DATA"))) 1704 if ((gd = evas_object_data_del(content, "GLOBAL_DATA")))
1650 { 1705 {
@@ -1659,6 +1714,9 @@ ui_shutdown(Evas_Object* content)
1659 evas_object_smart_callback_del(content, "task,freq,register", _task_freq_register_cb); 1714 evas_object_smart_callback_del(content, "task,freq,register", _task_freq_register_cb);
1660 evas_object_smart_callback_del(content, "task,use,register", _task_use_register_cb); 1715 evas_object_smart_callback_del(content, "task,use,register", _task_use_register_cb);
1661 1716
1717 evas_object_smart_callback_del(content, "display,interval", _background_update_cb);
1718 evas_object_smart_callback_del(content, "graph,draw", _navi_timemarks_update);
1719
1662 evas_object_smart_callback_del(content, "in,thread,data,request", _get_thd); 1720 evas_object_smart_callback_del(content, "in,thread,data,request", _get_thd);
1663 evas_object_smart_callback_del(content, "display,interval", _interval_display_cb); 1721 evas_object_smart_callback_del(content, "display,interval", _interval_display_cb);
1664 evas_object_smart_callback_del(content, "redraw,interval", _event_area_redraw_cb); 1722 evas_object_smart_callback_del(content, "redraw,interval", _event_area_redraw_cb);
diff --git a/src/lib/ui_private.h b/src/lib/ui_private.h
index 5a2fdf1..f4cc170 100644
--- a/src/lib/ui_private.h
+++ b/src/lib/ui_private.h
@@ -34,6 +34,7 @@ typedef struct _Grids
34 Evas_Object *states_grid; 34 Evas_Object *states_grid;
35 Evas_Object *cpufreq_grid; 35 Evas_Object *cpufreq_grid;
36 Evas_Object **thread_grid; 36 Evas_Object **thread_grid;
37 unsigned int thread_grid_arrays_size;
37 Evas_Object *over_grid; 38 Evas_Object *over_grid;
38 Evas_Object *timemarks_grid; 39 Evas_Object *timemarks_grid;
39 int over_grid_size; 40 int over_grid_size;
diff --git a/tool/efl_event_log_parse.py b/tool/efl_event_log_parse.py
new file mode 100644
index 0000000..284effe
--- /dev/null
+++ b/tool/efl_event_log_parse.py
@@ -0,0 +1,54 @@
1# RUN 'python efl_event_log_parse.sh "my path"'
2import sys
3import struct
4import os
5def parse_log(log_path):
6 if (not os.path.isfile(log_path)):
7 print('Error: log_path - not file')
8 return
9 fd = open(log_path, 'rb')
10 event_info_size=struct.calcsize('=ddQQHHH')
11 c=0
12 while (True):
13
14 data = fd.read(12)
15 if (len(data) <= 0):
16 break
17 header = struct.unpack('=iii', data)
18
19 if (hex(header[0]) != '0xffee211'):
20 print('Error: log_path - not log')
21 break
22
23 block_data=fd.read(header[1])
24 print("block={0}".format(c))
25 c=c+1
26 while(block_data):
27 event_info=struct.unpack('=ddQQHHH', block_data[0:event_info_size])
28 tim = event_info[0]
29 srctim = event_info[1]
30 thread = event_info[2]
31 obj = event_info[3]
32 event_offset = event_info[4]
33 detail_offset = event_info[5]
34 event_next = event_info[6]
35 if (event_next == 0):
36 break
37
38 eventstr = str(block_data[event_offset:event_offset + block_data[event_offset:].index(b"\0")])
39 detailstr = ""
40 if (detail_offset):
41 detailstr = str(block_data[detail_offset:detail_offset + block_data[detail_offset:].index(b"\0")])
42
43 if (len(detailstr)>60):
44 break
45
46 print(" {0}, {1}, {2}, {3}, {4}, {5}".format(tim, srctim, thread, obj, eventstr, detailstr))
47 block_data=block_data[event_next:]
48
49if __name__ == "__main__":
50 if (len(sys.argv) == 2):
51 parse_log(sys.argv[1])
52 else:
53 print('Error: more arguments')
54