1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.evProcessor
;
14 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
15 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.Events
;
16 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.Fields
;
17 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.IEventProcessing
;
18 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngProcessState
;
19 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
20 import org
.eclipse
.linuxtools
.lttng
.ui
.TraceDebug
;
21 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeEventProcess
;
22 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
25 * Creates instances of specific after state update handlers, per corresponding
31 class FlowTRangeAfterUpdateHandlers
{
34 * Handles: LTT_EVENT_SCHED_SCHEDULE
36 * Replace C function "after_schedchange_hook" in eventhooks.c
38 * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID
43 final IEventProcessing
getSchedChangeHandler() {
44 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
46 private Events eventType
= Events
.LTT_EVENT_SCHED_SCHEDULE
;
49 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
51 // get event time, cpu, trace_number, process, pid
52 LttngProcessState process_in
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
54 // pid_out is never used, even in LTTv!
55 //Long pid_out = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PREV_PID);
56 Long pid_in
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_NEXT_PID
);
58 if ( !(pid_in
.equals(process_in
.getPid())) ) {
59 TraceDebug
.debug("pid_in != PID! (getSchedChangeHandler)");
62 //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
63 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(),process_in
.getCreation_time() );
65 if ( localProcess
== null ) {
66 if ( (pid_in
== 0) || (pid_in
!= process_in
.getPpid()) ) {
67 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
68 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
72 .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)");
76 // There is no drawing done by the C code below, only refreshing
77 // the references to the current hash data to make it ready for
80 // This current implementation does not support the use of
81 // current hashed data
82 // although an equivalent would be good in order to improve the
83 // time to find the currently running process per cpu.
85 if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0)
87 TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab);
90 if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1)
94 Drawing_t *drawing = control_flow_data->drawing;
95 guint width = drawing->width;
98 convert_time_to_pixels(time_window,evtime,width,&new_x);
100 if(hashed_process_data_in->x.middle != new_x) {
101 hashed_process_data_in->x.middle = new_x;
102 hashed_process_data_in->x.middle_used = FALSE;
103 hashed_process_data_in->x.middle_marked = FALSE;
112 public Events
getEventHandleType() {
121 * Handles: LTT_EVENT_PROCESS_FORK
123 * Replace C function "after_process_fork_hook" in eventhooks.c
125 * Fields: LTT_FIELD_CHILD_PID
130 final IEventProcessing
getProcessForkHandler() {
131 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
133 private Events eventType
= Events
.LTT_EVENT_PROCESS_FORK
;
136 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
138 Long child_pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_CHILD_PID
);
139 LttngProcessState process_child
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), child_pid
);
141 if ( process_child
!= null ) {
142 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_child
.getPid(), process_child
.getCpu(), traceSt
.getTraceId(), process_child
.getCreation_time() );
144 if ( localProcess
== null ) {
145 if ( (child_pid
== 0) || (child_pid
!= process_child
.getPpid()) ) {
146 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
147 localProcess
= addLocalProcess(process_child
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
150 TraceDebug
.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)");
153 // If we found the process, the Ppid and the Tgid might
154 // be missing, let's add them
155 localProcess
.setPpid(process_child
.getPpid());
156 localProcess
.setTgid(process_child
.getTgid());
160 TraceDebug
.debug("process_child is null! (getProcessForkHandler)");
167 public Events
getEventHandleType() {
176 * Handles: LTT_EVENT_PROCESS_EXIT
178 * Replace C function "after_process_exit_hook" in eventhooks.c
182 final IEventProcessing
getProcessExitHandler() {
183 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
185 private Events eventType
= Events
.LTT_EVENT_PROCESS_EXIT
;
188 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
190 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
192 if ( process
!= null ) {
195 // We shall look into a way to find the current process
196 // faster, see the c library
197 // (current_hash) in order to speed up the find. see c-code
198 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
199 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
201 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
203 if ( localProcess
== null ) {
204 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
205 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
206 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
209 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)");
214 TraceDebug
.debug("process is null! (getProcessExitHandler)");
221 public Events
getEventHandleType() {
231 * Handles: LTT_EVENT_EXEC
233 * Replace C function "after_fs_exec_hook" in eventhooks.c
237 final IEventProcessing
getProcessExecHandler() {
238 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
240 private Events eventType
= Events
.LTT_EVENT_EXEC
;
243 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
245 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
247 if ( process
!= null ) {
249 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
251 if ( localProcess
== null ) {
252 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
253 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
254 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
257 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)");
261 // If we found the process, the name might be missing. Let's add it here.
262 localProcess
.setName(process
.getName());
266 TraceDebug
.debug("process is null! (getProcessExecHandler)");
273 public Events
getEventHandleType() {
282 * LTT_EVENT_THREAD_BRAND
284 * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
288 final IEventProcessing
GetThreadBrandHandler() {
289 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
291 private Events eventType
= Events
.LTT_EVENT_THREAD_BRAND
;
294 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
296 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
298 if ( process
!= null ) {
300 // Similar to above comments, implement a faster way to find
302 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
303 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
305 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
307 if ( localProcess
== null ) {
308 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
309 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
310 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
313 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)");
317 // If we found the process, the brand might be missing
319 localProcess
.setBrand(process
.getBrand());
323 TraceDebug
.debug("process is null! (GetThreadBrandHandler)");
331 public Events
getEventHandleType() {
340 * LTT_EVENT_PROCESS_STATE
342 * Replace C function "after_event_enum_process_hook" in eventhooks.c
345 * Creates the processlist entry for the child process. Put the last
346 * position in x at the current time value.
350 * Fields: LTT_FIELD_PID
355 final IEventProcessing
getEnumProcessStateHandler() {
356 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
358 private Events eventType
= Events
.LTT_EVENT_PROCESS_STATE
;
361 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
366 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
367 Fields
.LTT_FIELD_PID
);
369 // Lttv assume that pid_in will NEVER be null or incoherent
370 // What if ... ? (let's add some debug)
371 if ( pid_in
!= null ) {
374 nb_cpus
= traceSt
.getNumberOfCPUs();
377 first_cpu
= ANY_CPU
.intValue();
378 nb_cpus
= ANY_CPU
.intValue() + 1;
381 for (int cpu
= first_cpu
; cpu
< nb_cpus
; cpu
++) {
382 LttngProcessState process_in
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), pid_in
);
384 if ( process_in
!= null ) {
385 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(), process_in
.getCreation_time());
387 if (localProcess
== null) {
388 if ( (process_in
.getPid() == 0) || (process_in
.getPid() != process_in
.getPpid()) ) {
389 TmfTimeRange timeRange
= traceSt
.getInputDataRef().getTraceTimeWindow();
390 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
393 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)");
397 // If the process was found, it might be missing informations, add it here
398 localProcess
.setName(process_in
.getName());
399 localProcess
.setPpid(process_in
.getPpid());
400 localProcess
.setTgid(process_in
.getTgid());
404 TraceDebug
.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)");
409 TraceDebug
.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)");
416 public Events
getEventHandleType() {