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() {
46 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
48 // get event time, cpu, trace_number, process, pid
49 LttngProcessState process_in
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
51 // pid_out is never used, even in LTTv!
52 //Long pid_out = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PREV_PID);
53 Long pid_in
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_NEXT_PID
);
55 if ( !(pid_in
.equals(process_in
.getPid())) ) {
56 TraceDebug
.debug("pid_in != PID! (getSchedChangeHandler)");
59 //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
60 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(),process_in
.getCreation_time() );
62 if ( localProcess
== null ) {
63 if ( (pid_in
== 0) || (pid_in
!= process_in
.getPpid()) ) {
64 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
65 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
69 .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)");
73 // There is no drawing done by the C code below, only refreshing
74 // the references to the current hash data to make it ready for
77 // This current implementation does not support the use of
78 // current hashed data
79 // although an equivalent would be good in order to improve the
80 // time to find the currently running process per cpu.
82 if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0)
84 TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab);
87 if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1)
91 Drawing_t *drawing = control_flow_data->drawing;
92 guint width = drawing->width;
95 convert_time_to_pixels(time_window,evtime,width,&new_x);
97 if(hashed_process_data_in->x.middle != new_x) {
98 hashed_process_data_in->x.middle = new_x;
99 hashed_process_data_in->x.middle_used = FALSE;
100 hashed_process_data_in->x.middle_marked = FALSE;
113 * Handles: LTT_EVENT_PROCESS_FORK
115 * Replace C function "after_process_fork_hook" in eventhooks.c
117 * Fields: LTT_FIELD_CHILD_PID
122 final ILttngEventProcessor
getProcessForkHandler() {
123 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
126 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
128 Long child_pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_CHILD_PID
);
129 LttngProcessState process_child
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), child_pid
);
131 if ( process_child
!= null ) {
132 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_child
.getPid(), process_child
.getCpu(), traceSt
.getTraceId(), process_child
.getCreation_time() );
134 if ( localProcess
== null ) {
135 if ( (child_pid
== 0) || (child_pid
!= process_child
.getPpid()) ) {
136 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
137 localProcess
= addLocalProcess(process_child
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
140 TraceDebug
.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)");
143 // If we found the process, the Ppid and the Tgid might
144 // be missing, let's add them
145 localProcess
.setPpid(process_child
.getPpid());
146 localProcess
.setTgid(process_child
.getTgid());
150 TraceDebug
.debug("process_child is null! (getProcessForkHandler)");
161 * Handles: LTT_EVENT_PROCESS_EXIT
163 * Replace C function "after_process_exit_hook" in eventhooks.c
167 final ILttngEventProcessor
getProcessExitHandler() {
168 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
171 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
173 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
175 if ( process
!= null ) {
178 // We shall look into a way to find the current process
179 // faster, see the c library
180 // (current_hash) in order to speed up the find. see c-code
181 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
182 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
184 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
186 if ( localProcess
== null ) {
187 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
188 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
189 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
192 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)");
197 TraceDebug
.debug("process is null! (getProcessExitHandler)");
209 * Handles: LTT_EVENT_EXEC
211 * Replace C function "after_fs_exec_hook" in eventhooks.c
215 final ILttngEventProcessor
getProcessExecHandler() {
216 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
219 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
221 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
223 if ( process
!= null ) {
225 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
227 if ( localProcess
== null ) {
228 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
229 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
230 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
233 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)");
237 // If we found the process, the name might be missing. Let's add it here.
238 localProcess
.setName(process
.getName());
242 TraceDebug
.debug("process is null! (getProcessExecHandler)");
253 * LTT_EVENT_THREAD_BRAND
255 * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
259 final ILttngEventProcessor
GetThreadBrandHandler() {
260 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
263 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
265 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
267 if ( process
!= null ) {
269 // Similar to above comments, implement a faster way to find
271 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
272 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
274 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
276 if ( localProcess
== null ) {
277 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
278 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
279 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
282 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)");
286 // If we found the process, the brand might be missing
288 localProcess
.setBrand(process
.getBrand());
292 TraceDebug
.debug("process is null! (GetThreadBrandHandler)");
304 * LTT_EVENT_PROCESS_STATE
306 * Replace C function "after_event_enum_process_hook" in eventhooks.c
309 * Creates the processlist entry for the child process. Put the last
310 * position in x at the current time value.
314 * Fields: LTT_FIELD_PID
319 final ILttngEventProcessor
getEnumProcessStateHandler() {
320 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
323 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
328 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
329 Fields
.LTT_FIELD_PID
);
331 // Lttv assume that pid_in will NEVER be null or incoherent
332 // What if ... ? (let's add some debug)
333 if ( pid_in
!= null ) {
336 nb_cpus
= traceSt
.getNumberOfCPUs();
339 first_cpu
= ANY_CPU
.intValue();
340 nb_cpus
= ANY_CPU
.intValue() + 1;
343 for (int cpu
= first_cpu
; cpu
< nb_cpus
; cpu
++) {
344 LttngProcessState process_in
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), pid_in
);
346 if ( process_in
!= null ) {
347 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(), process_in
.getCreation_time());
349 if (localProcess
== null) {
350 if ( (process_in
.getPid() == 0) || (process_in
.getPid() != process_in
.getPpid()) ) {
351 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
352 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
355 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)");
359 // If the process was found, it might be missing informations, add it here
360 localProcess
.setName(process_in
.getName());
361 localProcess
.setPpid(process_in
.getPpid());
362 localProcess
.setTgid(process_in
.getTgid());
366 TraceDebug
.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)");
371 TraceDebug
.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)");