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(pid_in
, process_in
.getCpu(), traceSt
61 .getTraceId(), process_in
.getCreation_time());
63 if ( localProcess
== null ) {
64 if ( (pid_in
== 0) || (pid_in
!= process_in
.getPpid()) ) {
65 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
66 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
70 .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)");
74 // There is no drawing done by the C code below, only refreshing
75 // the references to the current hash data to make it ready for
78 // This current implementation does not support the use of
79 // current hashed data
80 // although an equivalent would be good in order to improve the
81 // time to find the currently running process per cpu.
83 if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0)
85 TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab);
88 if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1)
92 Drawing_t *drawing = control_flow_data->drawing;
93 guint width = drawing->width;
96 convert_time_to_pixels(time_window,evtime,width,&new_x);
98 if(hashed_process_data_in->x.middle != new_x) {
99 hashed_process_data_in->x.middle = new_x;
100 hashed_process_data_in->x.middle_used = FALSE;
101 hashed_process_data_in->x.middle_marked = FALSE;
114 * Handles: LTT_EVENT_PROCESS_FORK
116 * Replace C function "after_process_fork_hook" in eventhooks.c
118 * Fields: LTT_FIELD_CHILD_PID
123 final ILttngEventProcessor
getProcessForkHandler() {
124 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
127 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
129 Long child_pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_CHILD_PID
);
130 LttngProcessState process_child
= lttv_state_find_process(traceSt
, trcEvent
.getCpuId(), child_pid
);
132 if ( process_child
!= null ) {
133 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_child
.getPid(), process_child
.getCpu(), traceSt
.getTraceId(), process_child
.getCreation_time() );
135 if ( localProcess
== null ) {
136 if ( (child_pid
== 0) || (child_pid
!= process_child
.getPpid()) ) {
137 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
138 localProcess
= addLocalProcess(process_child
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
141 TraceDebug
.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)");
144 // If we found the process, the Ppid and the Tgid might
145 // be missing, let's add them
146 localProcess
.setPpid(process_child
.getPpid());
147 localProcess
.setTgid(process_child
.getTgid());
151 TraceDebug
.debug("process_child is null! (getProcessForkHandler)");
162 * Handles: LTT_EVENT_PROCESS_EXIT
164 * Replace C function "after_process_exit_hook" in eventhooks.c
168 final ILttngEventProcessor
getProcessExitHandler() {
169 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
172 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
174 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
176 if ( process
!= null ) {
179 // We shall look into a way to find the current process
180 // faster, see the c library
181 // (current_hash) in order to speed up the find. see c-code
182 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
183 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
185 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
187 if ( localProcess
== null ) {
188 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
189 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
190 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
193 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)");
198 TraceDebug
.debug("process is null! (getProcessExitHandler)");
210 * Handles: LTT_EVENT_EXEC
212 * Replace C function "after_fs_exec_hook" in eventhooks.c
216 final ILttngEventProcessor
getProcessExecHandler() {
217 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
220 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
222 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
224 if ( process
!= null ) {
226 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
228 if ( localProcess
== null ) {
229 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
230 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
231 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
234 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)");
238 // If we found the process, the name might be missing. Let's add it here.
239 localProcess
.setName(process
.getName());
243 TraceDebug
.debug("process is null! (getProcessExecHandler)");
254 * LTT_EVENT_THREAD_BRAND
256 * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
260 final ILttngEventProcessor
GetThreadBrandHandler() {
261 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
264 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
266 LttngProcessState process
= traceSt
.getRunning_process().get(trcEvent
.getCpuId());
268 if ( process
!= null ) {
270 // Similar to above comments, implement a faster way to find
272 // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
273 // hashed_process_data = process_list->current_hash_data[trace_num][cpu];
275 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process
.getPid(), process
.getCpu(), traceSt
.getTraceId(), process
.getCreation_time());
277 if ( localProcess
== null ) {
278 if ( (process
.getPid() == 0) || (process
.getPid() != process
.getPpid()) ) {
279 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
280 localProcess
= addLocalProcess(process
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
283 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)");
287 // If we found the process, the brand might be missing
289 localProcess
.setBrand(process
.getBrand());
293 TraceDebug
.debug("process is null! (GetThreadBrandHandler)");
305 * LTT_EVENT_PROCESS_STATE
307 * Replace C function "after_event_enum_process_hook" in eventhooks.c
310 * Creates the processlist entry for the child process. Put the last
311 * position in x at the current time value.
315 * Fields: LTT_FIELD_PID
320 final ILttngEventProcessor
getEnumProcessStateHandler() {
321 AbsFlowTRangeUpdate handler
= new AbsFlowTRangeUpdate() {
324 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
329 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
330 Fields
.LTT_FIELD_PID
);
332 if ( pid_in
!= null ) {
335 nb_cpus
= traceSt
.getNumberOfCPUs();
338 first_cpu
= ANY_CPU
.intValue();
339 nb_cpus
= ANY_CPU
.intValue() + 1;
342 for (int cpu
= first_cpu
; cpu
< nb_cpus
; cpu
++) {
343 LttngProcessState process_in
= lttv_state_find_process(traceSt
, Long
.valueOf(cpu
), pid_in
);
345 if ( process_in
!= null ) {
346 TimeRangeEventProcess localProcess
= procContainer
.findProcess(process_in
.getPid(), process_in
.getCpu(), traceSt
.getTraceId(), process_in
.getCreation_time());
348 if (localProcess
== null) {
349 if ( (process_in
.getPid() == 0) || (process_in
.getPid() != process_in
.getPpid()) ) {
350 TmfTimeRange timeRange
= traceSt
.getContext().getTraceTimeWindow();
351 localProcess
= addLocalProcess(process_in
, timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue(), traceSt
.getTraceId());
354 TraceDebug
.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)");
358 // If the process was found, it might be missing
359 // informations, add it here
360 localProcess
.setName(process_in
.getName());
361 localProcess
.setPpid(process_in
.getPpid());
362 localProcess
.setTgid(process_in
.getTgid());
365 TraceDebug
.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)");
370 TraceDebug
.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)");