Commit | Line | Data |
---|---|---|
6e512b93 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
3 | * | |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation | |
860cadcf | 11 | * Michel Dagenais (michel.dagenais@polymtl.ca) - Reference C implementation, used with permission |
6e512b93 ASL |
12 | *******************************************************************************/ |
13 | package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor; | |
14 | ||
5945cec9 FC |
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; | |
6e512b93 ASL |
20 | import org.eclipse.linuxtools.lttng.ui.TraceDebug; |
21 | import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess; | |
6c13869b | 22 | import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; |
6e512b93 ASL |
23 | |
24 | /** | |
25 | * Creates instances of specific after state update handlers, per corresponding | |
26 | * event. | |
27 | * | |
28 | * @author alvaro | |
29 | * | |
30 | */ | |
31 | class FlowAfterUpdateHandlers { | |
32 | /** | |
33 | * <p> | |
34 | * Handles: LTT_EVENT_SCHED_SCHEDULE | |
35 | * </p> | |
36 | * Replace C function "after_schedchange_hook" in eventhooks.c | |
37 | * <p> | |
38 | * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID | |
39 | * </p> | |
40 | * | |
41 | * @return | |
42 | */ | |
43 | final ILttngEventProcessor getSchedChangeHandler() { | |
44 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
45 | ||
46 | // @Override | |
d4011df2 | 47 | @Override |
6e512b93 ASL |
48 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
49 | ||
50 | // get event time, cpu, trace_number, process, pid | |
51 | LttngProcessState process_in = traceSt.getRunning_process().get(trcEvent.getCpuId()); | |
52 | ||
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); | |
56 | ||
57 | if ( !(pid_in.equals(process_in.getPid())) ) { | |
9c4eb5f7 | 58 | TraceDebug.debug("pid_in != PID! (getSchedChangeHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
59 | } |
60 | ||
61 | //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num); | |
ba1bc132 ASL |
62 | TimeRangeEventProcess localProcess = procContainer.findProcess(pid_in, process_in.getCpu(), traceSt |
63 | .getTraceId(), process_in.getCreation_time()); | |
6e512b93 | 64 | |
f9a8715c FC |
65 | if (localProcess == null) { |
66 | if ((pid_in == 0) || !pid_in.equals(process_in.getPpid())) { | |
6e512b93 | 67 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
c6f55e56 | 68 | addLocalProcess(process_in, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); |
6e512b93 ASL |
69 | } |
70 | else { | |
71 | TraceDebug | |
9c4eb5f7 | 72 | .debug("pid_in is not 0 or pid_in == PPID! (getSchedChangeHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
73 | } |
74 | } | |
75 | ||
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 | |
78 | // next event | |
79 | ||
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. | |
84 | /* | |
85 | if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0) | |
86 | { | |
87 | TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab); | |
88 | ||
89 | #ifdef EXTRA_CHECK | |
90 | if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1) | |
91 | return FALSE; | |
92 | #endif //EXTRA_CHECK | |
93 | ||
94 | Drawing_t *drawing = control_flow_data->drawing; | |
95 | guint width = drawing->width; | |
96 | guint new_x; | |
97 | ||
98 | convert_time_to_pixels(time_window,evtime,width,&new_x); | |
99 | ||
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; | |
104 | } | |
105 | }*/ | |
106 | ||
107 | return false; | |
108 | ||
109 | } | |
110 | }; | |
111 | return handler; | |
112 | } | |
113 | ||
114 | /** | |
115 | * <p> | |
116 | * Handles: LTT_EVENT_PROCESS_FORK | |
117 | * </p> | |
118 | * Replace C function "after_process_fork_hook" in eventhooks.c | |
119 | * <p> | |
120 | * Fields: LTT_FIELD_CHILD_PID | |
121 | * </p> | |
122 | * | |
123 | * @return | |
124 | */ | |
125 | final ILttngEventProcessor getProcessForkHandler() { | |
126 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
127 | ||
128 | // @Override | |
d4011df2 | 129 | @Override |
6e512b93 ASL |
130 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
131 | ||
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 ); | |
134 | ||
1cceddbe | 135 | if (process_child != null) { |
6e512b93 ASL |
136 | TimeRangeEventProcess localProcess = procContainer.findProcess(process_child.getPid(), process_child.getCpu(), traceSt.getTraceId(), process_child.getCreation_time() ); |
137 | ||
1cceddbe | 138 | if (localProcess == null) { |
f4c52cea | 139 | if (child_pid == 0 || !child_pid.equals(process_child.getPpid())) { |
6e512b93 | 140 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
c6f55e56 | 141 | addLocalProcess(process_child, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); |
6e512b93 ASL |
142 | } |
143 | else { | |
9c4eb5f7 | 144 | TraceDebug.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
145 | } |
146 | } else { | |
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()); | |
151 | } | |
152 | } | |
153 | else { | |
9c4eb5f7 | 154 | TraceDebug.debug("process_child is null! (getProcessForkHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
155 | } |
156 | ||
157 | return false; | |
158 | } | |
159 | }; | |
160 | return handler; | |
161 | } | |
162 | ||
163 | /** | |
164 | * <p> | |
165 | * Handles: LTT_EVENT_PROCESS_EXIT | |
166 | * </p> | |
167 | * Replace C function "after_process_exit_hook" in eventhooks.c | |
168 | * | |
169 | * @return | |
170 | */ | |
171 | final ILttngEventProcessor getProcessExitHandler() { | |
172 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
173 | ||
174 | // @Override | |
d4011df2 | 175 | @Override |
6e512b93 ASL |
176 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
177 | ||
178 | LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId()); | |
179 | ||
1cceddbe | 180 | if (process != null) { |
6e512b93 ASL |
181 | |
182 | // *** TODO: *** | |
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]; | |
188 | // } | |
189 | TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(), process.getCpu(), traceSt.getTraceId(), process.getCreation_time()); | |
190 | ||
1cceddbe | 191 | if (localProcess == null) { |
f4c52cea | 192 | if (process.getPid() == 0 || !process.getPid().equals(process.getPpid())) { |
6e512b93 | 193 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
c6f55e56 | 194 | addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); |
6e512b93 ASL |
195 | } |
196 | else { | |
9c4eb5f7 | 197 | TraceDebug.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
198 | } |
199 | } | |
200 | } | |
201 | else { | |
9c4eb5f7 | 202 | TraceDebug.debug("process is null! (getProcessExitHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
203 | } |
204 | ||
205 | return false; | |
206 | } | |
207 | }; | |
208 | return handler; | |
209 | } | |
210 | ||
211 | ||
212 | /** | |
213 | * <p> | |
214 | * Handles: LTT_EVENT_EXEC | |
215 | * </p> | |
216 | * Replace C function "after_fs_exec_hook" in eventhooks.c | |
217 | * | |
218 | * @return | |
219 | */ | |
220 | final ILttngEventProcessor getProcessExecHandler() { | |
221 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
222 | ||
223 | // @Override | |
d4011df2 | 224 | @Override |
6e512b93 ASL |
225 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
226 | ||
227 | LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId()); | |
228 | ||
1cceddbe | 229 | if (process != null) { |
6e512b93 ASL |
230 | |
231 | TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(), process.getCpu(), traceSt.getTraceId(), process.getCreation_time()); | |
232 | ||
1cceddbe | 233 | if (localProcess == null) { |
f4c52cea | 234 | if (process.getPid() == 0 || !process.getPid().equals(process.getPpid())) { |
6e512b93 | 235 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
c6f55e56 | 236 | addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); |
6e512b93 ASL |
237 | } |
238 | else { | |
9c4eb5f7 | 239 | TraceDebug.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
240 | } |
241 | } | |
242 | else { | |
243 | // If we found the process, the name might be missing. Let's add it here. | |
244 | localProcess.setName(process.getName()); | |
245 | } | |
246 | } | |
247 | else { | |
9c4eb5f7 | 248 | TraceDebug.debug("process is null! (getProcessExecHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
249 | } |
250 | ||
251 | return false; | |
252 | } | |
253 | }; | |
254 | return handler; | |
255 | } | |
256 | ||
257 | /** | |
258 | * <p> | |
259 | * LTT_EVENT_THREAD_BRAND | |
260 | * </p> | |
261 | * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c | |
262 | * | |
263 | * @return | |
264 | */ | |
265 | final ILttngEventProcessor GetThreadBrandHandler() { | |
266 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
267 | ||
268 | // @Override | |
d4011df2 | 269 | @Override |
6e512b93 ASL |
270 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
271 | ||
272 | LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId()); | |
273 | ||
1cceddbe | 274 | if (process != null) { |
6e512b93 ASL |
275 | |
276 | // Similar to above comments, implement a faster way to find | |
277 | // the local process | |
278 | // if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){ | |
279 | // hashed_process_data = process_list->current_hash_data[trace_num][cpu]; | |
280 | // } | |
281 | TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(), process.getCpu(), traceSt.getTraceId(), process.getCreation_time()); | |
282 | ||
1cceddbe | 283 | if (localProcess == null) { |
f4c52cea | 284 | if (process.getPid() == 0 || !process.getPid().equals(process.getPpid())) { |
6e512b93 | 285 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
c6f55e56 | 286 | addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); |
6e512b93 ASL |
287 | } |
288 | else { | |
9c4eb5f7 | 289 | TraceDebug.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
290 | } |
291 | } | |
292 | else { | |
293 | // If we found the process, the brand might be missing | |
294 | // on it, add it. | |
295 | localProcess.setBrand(process.getBrand()); | |
296 | } | |
297 | } | |
298 | else { | |
9c4eb5f7 | 299 | TraceDebug.debug("process is null! (GetThreadBrandHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
300 | } |
301 | ||
302 | return false; | |
303 | ||
304 | } | |
305 | }; | |
306 | return handler; | |
307 | } | |
308 | ||
309 | /** | |
310 | * <p> | |
311 | * LTT_EVENT_PROCESS_STATE | |
312 | * </p> | |
313 | * Replace C function "after_event_enum_process_hook" in eventhooks.c | |
314 | * <p> | |
315 | * <p> | |
316 | * Creates the processlist entry for the child process. Put the last | |
317 | * position in x at the current time value. | |
318 | * </p> | |
319 | * | |
320 | * <p> | |
321 | * Fields: LTT_FIELD_PID | |
322 | * </p> | |
323 | * | |
324 | * @return | |
325 | */ | |
326 | final ILttngEventProcessor getEnumProcessStateHandler() { | |
327 | AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() { | |
328 | ||
329 | // @Override | |
d4011df2 | 330 | @Override |
6e512b93 ASL |
331 | public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { |
332 | ||
333 | int first_cpu; | |
334 | int nb_cpus; | |
335 | ||
336 | Long pid_in = getAFieldLong(trcEvent, traceSt, | |
337 | Fields.LTT_FIELD_PID); | |
338 | ||
6e512b93 ASL |
339 | if ( pid_in != null ) { |
340 | if(pid_in == 0L) { | |
341 | first_cpu = 0; | |
342 | nb_cpus = traceSt.getNumberOfCPUs(); | |
343 | } | |
344 | else { | |
345 | first_cpu = ANY_CPU.intValue(); | |
346 | nb_cpus = ANY_CPU.intValue() + 1; | |
347 | } | |
348 | ||
349 | for (int cpu = first_cpu; cpu < nb_cpus; cpu++) { | |
ba1bc132 | 350 | LttngProcessState process_in = lttv_state_find_process(traceSt, Long.valueOf(cpu), pid_in); |
6e512b93 ASL |
351 | |
352 | if ( process_in != null ) { | |
353 | TimeRangeEventProcess localProcess = procContainer.findProcess(process_in.getPid(), process_in.getCpu(), traceSt.getTraceId(), process_in.getCreation_time()); | |
354 | ||
355 | if (localProcess == null) { | |
f4c52cea | 356 | if (process_in.getPid() == 0 || !process_in.getPid().equals(process_in.getPpid())) { |
6e512b93 ASL |
357 | TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow(); |
358 | localProcess = addLocalProcess(process_in, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId()); | |
359 | } | |
360 | else { | |
9c4eb5f7 | 361 | TraceDebug.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)"); //$NON-NLS-1$ |
1cceddbe | 362 | return false; |
6e512b93 ASL |
363 | } |
364 | } | |
ba1bc132 ASL |
365 | |
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()); | |
6e512b93 ASL |
371 | } |
372 | else { | |
9c4eb5f7 | 373 | TraceDebug.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
374 | } |
375 | } | |
376 | } | |
377 | else { | |
9c4eb5f7 | 378 | TraceDebug.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)"); //$NON-NLS-1$ |
6e512b93 ASL |
379 | } |
380 | ||
381 | return false; | |
382 | } | |
383 | }; | |
384 | return handler; | |
385 | } | |
386 | ||
387 | } |