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
.Fields
;
16 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.ILttngEventProcessor
;
17 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngProcessState
;
18 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
19 import org
.eclipse
.linuxtools
.lttng
.ui
.TraceDebug
;
20 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeEventProcess
;
21 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
24 * Creates instances of specific after state update handlers, per corresponding
30 class FlowAfterUpdateHandlers
{
33 * Handles: LTT_EVENT_SCHED_SCHEDULE
35 * Replace C function "after_schedchange_hook" in eventhooks.c
37 * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID
42 final ILttngEventProcessor
getSchedChangeHandler() {
43 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
47 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
49 // get event time, cpu, trace_number, process, pid
50 LttngProcessState process_in
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
52 // pid_out is never used, even in LTTv!
53 //Long pid_out = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PREV_PID);
54 Long pid_in
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_NEXT_PID
);
56 if ( !(pid_in
.equals(process_in
.getPid())) ) {
57 TraceDebug
.debug("pid_in != PID! (getSchedChangeHandler)");
60 //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
61 TimeRangeEventProcess localProcess
= procContainer
.findProcess(pid_in
, process_in
.getCpu(), traceSt
62 .getTraceId(), process_in
.getCreation_time());
64 if ( localProcess
== null ) {
65 if ( (pid_in
== 0) || (pid_in
!= process_in
.getPpid()) ) {
66 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
67 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
71 .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)");
75 // There is no drawing done by the C code below, only refreshing
76 // the references to the current hash data to make it ready for
79 // This current implementation does not support the use of
80 // current hashed data
81 // although an equivalent would be good in order to improve the
82 // time to find the currently running process per cpu.
84 if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0)
86 TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab);
89 if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1)
93 Drawing_t *drawing = control_flow_data->drawing;
94 guint width = drawing->width;
97 convert_time_to_pixels(time_window,evtime,width,&new_x);
99 if(hashed_process_data_in->x.middle != new_x) {
100 hashed_process_data_in->x.middle = new_x;
101 hashed_process_data_in->x.middle_used = FALSE;
102 hashed_process_data_in->x.middle_marked = FALSE;
115 * Handles: LTT_EVENT_PROCESS_FORK
117 * Replace C function "after_process_fork_hook" in eventhooks.c
119 * Fields: LTT_FIELD_CHILD_PID
124 final ILttngEventProcessor
getProcessForkHandler() {
125 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
129 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
131 Long child_pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_CHILD_PID
);
132 LttngProcessState process_child
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), child_pid
);
134 if ( process_child
!= null ) {
135 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_child
.getPid(), process_child
.getCpu(), traceSt
.getTraceId(), process_child
.getCreation_time() );
137 if ( localProcess
== null ) {
138 if ( (child_pid
== 0) || (child_pid
!= process_child
.getPpid()) ) {
139 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
140 localProcess
= addLocalProcess(process_child
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
143 TraceDebug
.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)");
146 // If we found the process, the Ppid and the Tgid might
147 // be missing, let's add them
148 localProcess
.setPpid(process_child
.getPpid());
149 localProcess
.setTgid(process_child
.getTgid());
153 TraceDebug
.debug("process_child is null! (getProcessForkHandler)");
164 * Handles: LTT_EVENT_PROCESS_EXIT
166 * Replace C function "after_process_exit_hook" in eventhooks.c
170 final ILttngEventProcessor
getProcessExitHandler() {
171 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
175 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
177 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
179 if ( process
!= null ) {
182 // We shall look into a way to find the current process
183 // faster, see the c library
184 // (current_hash) in order to speed up the find. see c-code
185 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
186 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
188 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
190 if ( localProcess
== null ) {
191 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
192 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
193 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
196 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)");
201 TraceDebug
.debug("process is null! (getProcessExitHandler)");
213 * Handles: LTT_EVENT_EXEC
215 * Replace C function "after_fs_exec_hook" in eventhooks.c
219 final ILttngEventProcessor
getProcessExecHandler() {
220 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
224 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
226 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
228 if ( process
!= null ) {
230 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
232 if ( localProcess
== null ) {
233 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
234 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
235 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
238 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)");
242 // If we found the process, the name might be missing. Let's add it here.
243 localProcess
.setName(process
.getName());
247 TraceDebug
.debug("process is null! (getProcessExecHandler)");
258 * LTT_EVENT_THREAD_BRAND
260 * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
264 final ILttngEventProcessor
GetThreadBrandHandler() {
265 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
269 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
271 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
273 if ( process
!= null ) {
275 // Similar to above comments, implement a faster way to find
277 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
278 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
280 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
282 if ( localProcess
== null ) {
283 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
284 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
285 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
288 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)");
292 // If we found the process, the brand might be missing
294 localProcess
.setBrand(process
.getBrand());
298 TraceDebug
.debug("process is null! (GetThreadBrandHandler)");
310 * LTT_EVENT_PROCESS_STATE
312 * Replace C function "after_event_enum_process_hook" in eventhooks.c
315 * Creates the processlist entry for the child process. Put the last
316 * position in x at the current time value.
320 * Fields: LTT_FIELD_PID
325 final ILttngEventProcessor
getEnumProcessStateHandler() {
326 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
330 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
335 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
336 Fields
.LTT_FIELD_PID
);
338 if ( pid_in
!= null ) {
341 nb_cpus
= traceSt
.getNumberOfCPUs();
344 first_cpu
= ANY_CPU
.intValue();
345 nb_cpus
= ANY_CPU
.intValue() + 1;
348 for (int cpu
= first_cpu
; cpu
< nb_cpus
; cpu
++) {
349 LttngProcessState process_in
= lttv_state_find_process(traceSt
, Long
.valueOf(cpu
), pid_in
);
351 if ( process_in
!= null ) {
352 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(), process_in
.getCreation_time());
354 if (localProcess
== null) {
355 if ( (process_in
.getPid() == 0) || (process_in
.getPid() != process_in
.getPpid()) ) {
356 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
357 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
360 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)");
364 // If the process was found, it might be missing
365 // informations, add it here
366 localProcess
.setName(process_in
.getName());
367 localProcess
.setPpid(process_in
.getPpid());
368 localProcess
.setTgid(process_in
.getTgid());
371 TraceDebug
.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)");
376 TraceDebug
.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)");