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 * Michel Dagenais (michel.dagenais@polymtl.ca) - Reference C implementation, used with permission
12 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.evProcessor
;
15 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.event
.LttngEvent
;
16 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.StateStrings
.Fields
;
17 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.evProcessor
.ILttngEventProcessor
;
18 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.model
.LttngProcessState
;
19 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.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
.core
.event
.TmfTimeRange
;
25 * Creates instances of specific after state update handlers, per corresponding
31 class FlowAfterUpdateHandlers
{
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 ILttngEventProcessor
getSchedChangeHandler() {
44 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
48 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
50 // get event time, cpu, trace_number, process, pid
51 LttngProcessState process_in
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
53 // pid_out is never used, even in LTTv!
54 //Long pid_out = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PREV_PID);
55 Long pid_in
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_NEXT_PID
);
57 if ( !(pid_in
.equals(process_in
.getPid())) ) {
58 TraceDebug
.debug("pid_in != PID! (getSchedChangeHandler)"); //$NON-NLS-1$
61 //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
62 TimeRangeEventProcess localProcess
= procContainer
.findProcess(pid_in
, process_in
.getCpu(), traceSt
63 .getTraceId(), process_in
.getCreation_time());
65 if (localProcess
== null) {
66 if ((pid_in
== 0) || !pid_in
.equals(process_in
.getPpid())) {
67 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
68 addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
72 .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)"); //$NON-NLS-1$
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;
116 * Handles: LTT_EVENT_PROCESS_FORK
118 * Replace C function "after_process_fork_hook" in eventhooks.c
120 * Fields: LTT_FIELD_CHILD_PID
125 final ILttngEventProcessor
getProcessForkHandler() {
126 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
130 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
132 Long child_pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_CHILD_PID
);
133 LttngProcessState process_child
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), child_pid
);
135 if (process_child
!= null) {
136 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_child
.getPid(), process_child
.getCpu(), traceSt
.getTraceId(), process_child
.getCreation_time() );
138 if (localProcess
== null) {
139 if (child_pid
== 0 || !child_pid
.equals(process_child
.getPpid())) {
140 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
141 addLocalProcess(process_child
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
144 TraceDebug
.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)"); //$NON-NLS-1$
147 // If we found the process, the Ppid and the Tgid might
148 // be missing, let's add them
149 localProcess
.setPpid(process_child
.getPpid());
150 localProcess
.setTgid(process_child
.getTgid());
154 TraceDebug
.debug("process_child is null! (getProcessForkHandler)"); //$NON-NLS-1$
165 * Handles: LTT_EVENT_PROCESS_EXIT
167 * Replace C function "after_process_exit_hook" in eventhooks.c
171 final ILttngEventProcessor
getProcessExitHandler() {
172 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
176 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
178 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
180 if (process
!= null) {
183 // We shall look into a way to find the current process
184 // faster, see the c library
185 // (current_hash) in order to speed up the find. see c-code
186 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
187 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
189 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
191 if (localProcess
== null) {
192 if (process
.getPid() == 0 || !process
.getPid().equals(process
.getPpid())) {
193 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
194 addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
197 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)"); //$NON-NLS-1$
202 TraceDebug
.debug("process is null! (getProcessExitHandler)"); //$NON-NLS-1$
214 * Handles: LTT_EVENT_EXEC
216 * Replace C function "after_fs_exec_hook" in eventhooks.c
220 final ILttngEventProcessor
getProcessExecHandler() {
221 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
225 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
227 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
229 if (process
!= null) {
231 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
233 if (localProcess
== null) {
234 if (process
.getPid() == 0 || !process
.getPid().equals(process
.getPpid())) {
235 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
236 addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
239 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)"); //$NON-NLS-1$
243 // If we found the process, the name might be missing. Let's add it here.
244 localProcess
.setName(process
.getName());
248 TraceDebug
.debug("process is null! (getProcessExecHandler)"); //$NON-NLS-1$
259 * LTT_EVENT_THREAD_BRAND
261 * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
265 final ILttngEventProcessor
GetThreadBrandHandler() {
266 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
270 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
272 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
274 if (process
!= null) {
276 // Similar to above comments, implement a faster way to find
278 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
279 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
281 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
283 if (localProcess
== null) {
284 if (process
.getPid() == 0 || !process
.getPid().equals(process
.getPpid())) {
285 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
286 addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
289 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)"); //$NON-NLS-1$
293 // If we found the process, the brand might be missing
295 localProcess
.setBrand(process
.getBrand());
299 TraceDebug
.debug("process is null! (GetThreadBrandHandler)"); //$NON-NLS-1$
311 * LTT_EVENT_PROCESS_STATE
313 * Replace C function "after_event_enum_process_hook" in eventhooks.c
316 * Creates the processlist entry for the child process. Put the last
317 * position in x at the current time value.
321 * Fields: LTT_FIELD_PID
326 final ILttngEventProcessor
getEnumProcessStateHandler() {
327 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
331 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
336 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
337 Fields
.LTT_FIELD_PID
);
339 if ( pid_in
!= null ) {
342 nb_cpus
= traceSt
.getNumberOfCPUs();
345 first_cpu
= ANY_CPU
.intValue();
346 nb_cpus
= ANY_CPU
.intValue() + 1;
349 for (int cpu
= first_cpu
; cpu
< nb_cpus
; cpu
++) {
350 LttngProcessState process_in
= lttv_state_find_process(traceSt
, Long
.valueOf(cpu
), pid_in
);
352 if ( process_in
!= null ) {
353 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(), process_in
.getCreation_time());
355 if (localProcess
== null) {
356 if (process_in
.getPid() == 0 || !process_in
.getPid().equals(process_in
.getPpid())) {
357 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
358 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
361 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)"); //$NON-NLS-1$
366 // If the process was found, it might be missing
367 // informations, add it here
368 localProcess
.setName(process_in
.getName());
369 localProcess
.setPpid(process_in
.getPpid());
370 localProcess
.setTgid(process_in
.getTgid());
373 TraceDebug
.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)"); //$NON-NLS-1$
378 TraceDebug
.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)"); //$NON-NLS-1$