Re-structure LTTng sub-project as per the Linux Tools guidelines
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.core / src / org / eclipse / linuxtools / lttng / core / state / evProcessor / state / StateUpdateHandlers.java
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
11 * Michel Dagenais (michel.dagenais@polymtl.ca) - Reference C implementation, used with permission
12 *******************************************************************************/
13
14 package org.eclipse.linuxtools.lttng.core.state.evProcessor.state;
15
16 import java.util.Map;
17
18 import org.eclipse.linuxtools.lttng.core.LttngConstants;
19 import org.eclipse.linuxtools.lttng.core.TraceDebug;
20 import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
21 import org.eclipse.linuxtools.lttng.core.state.StateStrings;
22 import org.eclipse.linuxtools.lttng.core.state.StateStrings.BdevMode;
23 import org.eclipse.linuxtools.lttng.core.state.StateStrings.CpuMode;
24 import org.eclipse.linuxtools.lttng.core.state.StateStrings.Events;
25 import org.eclipse.linuxtools.lttng.core.state.StateStrings.ExecutionMode;
26 import org.eclipse.linuxtools.lttng.core.state.StateStrings.ExecutionSubMode;
27 import org.eclipse.linuxtools.lttng.core.state.StateStrings.Fields;
28 import org.eclipse.linuxtools.lttng.core.state.StateStrings.IRQMode;
29 import org.eclipse.linuxtools.lttng.core.state.StateStrings.ProcessStatus;
30 import org.eclipse.linuxtools.lttng.core.state.StateStrings.ProcessType;
31 import org.eclipse.linuxtools.lttng.core.state.evProcessor.ILttngEventProcessor;
32 import org.eclipse.linuxtools.lttng.core.state.model.LTTngCPUState;
33 import org.eclipse.linuxtools.lttng.core.state.model.LttngBdevState;
34 import org.eclipse.linuxtools.lttng.core.state.model.LttngExecutionState;
35 import org.eclipse.linuxtools.lttng.core.state.model.LttngIRQState;
36 import org.eclipse.linuxtools.lttng.core.state.model.LttngProcessState;
37 import org.eclipse.linuxtools.lttng.core.state.model.LttngSoftIRQState;
38 import org.eclipse.linuxtools.lttng.core.state.model.LttngTraceState;
39 import org.eclipse.linuxtools.lttng.core.state.model.LttngTrapState;
40 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
41
42 /**
43 * Wraps the creation of individual handlers, each method creates and instance
44 * of the corresponding handler
45 *
46 * @author alvaro
47 *
48 */
49 class StateUpdateHandlers {
50
51 final ILttngEventProcessor getSyscallEntryHandler() {
52 AbsStateUpdate handler = new AbsStateUpdate() {
53
54 // @Override
55 @Override
56 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
57
58 Long cpu = trcEvent.getCpuId();
59
60 // No syscall_entry update for initialization process
61 LttngProcessState process = traceSt.getRunning_process().get(
62 cpu);
63 if ((process != null) && (process.getPid() != null)
64 && (process.getPid().longValue() == 0L)) {
65 return true;
66 }
67
68 // Get the expected event field
69 Long syscall = getAFieldLong(trcEvent, traceSt,
70 Fields.LTT_FIELD_SYSCALL_ID);
71
72 String submode = null;
73 int submodeId = 0;
74 if (syscall == null) {
75 TraceDebug
76 .debug("Syscall Field not found, traceVent time: " //$NON-NLS-1$
77 + trcEvent.getTimestamp());
78 } else {
79 submode = traceSt.getSyscall_names().get(syscall);
80 // Note: For statistics performance improvement only the integer value of syscall is used
81 // as well as a bit mask is applied!
82 submodeId = syscall.intValue() | LttngConstants.STATS_SYS_CALL_NAME_ID;
83 }
84
85 if (submode == null) {
86 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.getInName();
87 submodeId = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.ordinal() | LttngConstants.STATS_NONE_ID;
88 }
89
90 push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL,
91 submode, submodeId, trcEvent.getTimestamp(), traceSt);
92 return false;
93 }
94 };
95 return handler;
96 }
97
98 final ILttngEventProcessor getsySyscallExitHandler() {
99 AbsStateUpdate handler = new AbsStateUpdate() {
100
101 // @Override
102 @Override
103 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
104
105 Long cpu = trcEvent.getCpuId();
106 LttngProcessState process = traceSt.getRunning_process().get(
107 cpu);
108
109 // No syscall_entry update for initialization process
110 if ((process != null) && (process.getPid() != null)
111 && (process.getPid().longValue() == 0L)) {
112 return true;
113 }
114
115 pop_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL,
116 traceSt, trcEvent.getTimestamp());
117 return false;
118
119 }
120 };
121 return handler;
122 }
123
124 /**
125 * Update stacks related to the parsing of an LttngEvent
126 *
127 * @return
128 */
129 final ILttngEventProcessor getTrapEntryHandler() {
130 AbsStateUpdate handler = new AbsStateUpdate() {
131
132 // @Override
133 @Override
134 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
135 Long cpu = trcEvent.getCpuId();
136
137 Long trap = getAFieldLong(trcEvent, traceSt,
138 Fields.LTT_FIELD_TRAP_ID);
139 if (trap == null) {
140 TraceDebug
141 .debug("Trap field could not be found, event time: " //$NON-NLS-1$
142 + trcEvent.getTimestamp());
143 return true;
144 }
145
146 // ready the trap submode name
147 String submode = traceSt.getTrap_names().get(trap);
148 // Note: For statistics performance improvement only the integer value of trap is used
149 // as well as a bit mask is applied!
150
151 int submodeId = trap.intValue() | LttngConstants.STATS_TRAP_NAME_ID;
152
153 if (submode == null) {
154 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.getInName();
155 submodeId = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.ordinal() | LttngConstants.STATS_NONE_ID;
156 }
157
158 /* update process state */
159 push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_TRAP,
160 submode, submodeId, trcEvent.getTimestamp(), traceSt);
161
162 /* update cpu status */
163 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
164 cpu_push_mode(cpust, StateStrings.CpuMode.LTTV_CPU_TRAP);
165 cpust.pushToTrapStack(trap); /* update trap status */
166
167 // update Trap State
168 LttngTrapState trap_state = null;
169 trap_state = traceSt.getTrap_states().get(trap);
170
171 // If the trape_state exists, just increment it's counter,
172 // otherwise, create it
173 if ( trap_state == null ) {
174 trap_state = new LttngTrapState();
175 trap_state.incrementRunning();
176 traceSt.getTrap_states().put(trap, trap_state);
177 }
178 else {
179 trap_state.incrementRunning();
180 }
181
182 return false;
183
184 }
185 };
186 return handler;
187 }
188
189 /**
190 *
191 * @return
192 */
193 final ILttngEventProcessor getTrapExitHandler() {
194 AbsStateUpdate handler = new AbsStateUpdate() {
195
196 // @Override
197 @Override
198 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
199
200 Long cpu = trcEvent.getCpuId();
201 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
202 Long trap = cpust.popFromTrapStack();
203
204 /* update process state */
205 pop_state(cpu, ExecutionMode.LTTV_STATE_TRAP, traceSt, trcEvent
206 .getTimestamp());
207
208 /* update cpu status */
209 cpu_pop_mode(cpust);
210
211 if (trap != -1L) {
212 traceSt.getTrap_states().get(trap).decrementRunning();
213 }
214 // else {
215 // TraceDebug.debug("remove this line");
216 // }
217
218 return false;
219
220 }
221 };
222 return handler;
223 }
224
225 /**
226 *
227 * @return
228 */
229 final ILttngEventProcessor getIrqEntryHandler() {
230 AbsStateUpdate handler = new AbsStateUpdate() {
231
232 // @Override
233 @Override
234 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
235
236 Long cpu = trcEvent.getCpuId();
237
238 Long irq = getAFieldLong(trcEvent, traceSt,
239 Fields.LTT_FIELD_IRQ_ID);
240 if (irq == null || traceSt.getIrq_states().get(irq) == null) {
241 if (irq != null) {
242 TraceDebug.debug("Invalid irq (" + irq + "), ts = " + trcEvent.getOriginalTimestamp()); //$NON-NLS-1$ //$NON-NLS-2$
243 }
244 return true;
245 }
246
247 String submode;
248 submode = traceSt.getIrq_names().get(irq);
249 // Note: For statistics performance improvement only the integer value of irq is used
250 // as well as a bit mask is applied!
251 int submodeId = irq.intValue() | LttngConstants.STATS_IRQ_NAME_ID;
252
253 if (submode == null) {
254 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.getInName();
255 submodeId = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.ordinal() | LttngConstants.STATS_NONE_ID;
256 }
257
258 /*
259 * Do something with the info about being in user or system mode
260 * when int?
261 */
262 push_state(cpu, ExecutionMode.LTTV_STATE_IRQ, submode, submodeId, trcEvent
263 .getTimestamp(), traceSt);
264
265 /* update cpu state */
266 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
267 cpu_push_mode(cpust, CpuMode.LTTV_CPU_IRQ); /* mode stack */
268 cpust.pushToIrqStack(irq); /* last irq */
269
270 /* udpate irq state */
271 irq_push_mode(traceSt.getIrq_states().get(irq),
272 IRQMode.LTTV_IRQ_BUSY);
273 return false;
274
275 }
276 };
277 return handler;
278 }
279
280 /**
281 *
282 * @return
283 */
284 final ILttngEventProcessor getSoftIrqExitHandler() {
285 AbsStateUpdate handler = new AbsStateUpdate() {
286
287 // @Override
288 @Override
289 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
290
291 Long cpu = trcEvent.getCpuId();
292 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
293 Long softirq = cpust.popFromSoftIrqStack();
294
295 // Update process status
296 pop_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, traceSt,
297 trcEvent.getTimestamp());
298
299 /* update softirq status */
300 if (softirq != -1) {
301 LttngSoftIRQState softIrqstate = traceSt
302 .getSoft_irq_states().get(softirq);
303 if (softIrqstate != null) {
304 softIrqstate.decrementRunning();
305 }
306 }
307
308 /* update cpu status */
309 cpu_pop_mode(cpust);
310
311 return false;
312 }
313 };
314 return handler;
315 }
316
317 /**
318 *
319 * @return
320 */
321 final ILttngEventProcessor getIrqExitHandler() {
322 AbsStateUpdate handler = new AbsStateUpdate() {
323
324 // @Override
325 @Override
326 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
327
328 Long cpu = trcEvent.getCpuId();
329
330 /* update process state */
331 pop_state(cpu, ExecutionMode.LTTV_STATE_IRQ, traceSt, trcEvent
332 .getTimestamp());
333
334 /* update cpu status */
335 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
336 cpu_pop_mode(cpust);
337
338 /* update irq status */
339 Long last_irq = cpust.popFromIrqStack();
340 if (last_irq != -1L) {
341 LttngIRQState irq_state = traceSt.getIrq_states().get(
342 last_irq);
343 irq_pop_mode(irq_state);
344 }
345
346 return false;
347
348 }
349 };
350 return handler;
351 }
352
353 /**
354 *
355 * @return
356 */
357 final ILttngEventProcessor getSoftIrqRaiseHandler() {
358 AbsStateUpdate handler = new AbsStateUpdate() {
359
360 private Events eventType = Events.LTT_EVENT_SOFT_IRQ_RAISE;
361
362 // @Override
363 @Override
364 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
365
366 // Long cpu = trcEvent.getCpuId();
367
368 // get event field
369 Long softirq = getAFieldLong(trcEvent, traceSt,
370 Fields.LTT_FIELD_SOFT_IRQ_ID);
371
372 if (softirq == null) {
373 TraceDebug.debug("Soft_irq_id not found in " //$NON-NLS-1$
374 + eventType.getInName() + " time: " //$NON-NLS-1$
375 + trcEvent.getTimestamp());
376 return true;
377 }
378
379 // String submode;
380 // String[] softIrqNames = traceSt.getSoft_irq_names();
381 // if (softirq < softIrqNames.length) {
382 // submode = softIrqNames[softirq];
383 // } else {
384 // submode = "softirq " + softirq;
385 // }
386
387 /* update softirq status */
388 /* a soft irq raises are not cumulative */
389 LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get(
390 softirq);
391 if (irqState != null) {
392 irqState.setPending(1L);
393 } else {
394 TraceDebug
395 .debug("unexpected soft irq id value: " + softirq); //$NON-NLS-1$
396 }
397
398 return false;
399
400 }
401 };
402 return handler;
403 }
404
405 /**
406 *
407 * @return
408 */
409 final ILttngEventProcessor getSoftIrqEntryHandler() {
410 AbsStateUpdate handler = new AbsStateUpdate() {
411
412 // @Override
413 @Override
414 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
415
416 // obtrain cpu
417 Long cpu = trcEvent.getCpuId();
418
419 // get event field
420 Long softirq = getAFieldLong(trcEvent, traceSt,
421 Fields.LTT_FIELD_SOFT_IRQ_ID);
422
423 if (softirq == null) {
424 TraceDebug.debug("Soft IRQ ID not found, eventTime: " //$NON-NLS-1$
425 + trcEvent.getTimestamp());
426 return true;
427 }
428
429 // obtain submode
430 Map<Long, String> softIrqNames = traceSt.getSoft_irq_names();
431 String submode = softIrqNames.get(softirq);
432 if (submode == null) {
433 submode = "softirq " + softirq; //$NON-NLS-1$
434 softIrqNames.put(softirq, submode);
435 }
436
437 // Note: For statistics performance improvement only the integer value of softirq is used
438 // as well as a bit mask is applied!
439 int submodeId = softirq.intValue() | LttngConstants.STATS_SOFT_IRQ_NAME_ID;
440
441 /* update softirq status */
442 LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get(
443 softirq);
444 if (irqState != null) {
445 irqState.decrementPending();
446 irqState.incrementRunning();
447 } else {
448 TraceDebug
449 .debug("unexpected soft irq id value: " + softirq); //$NON-NLS-1$
450 }
451
452 /* update cpu state */
453 LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu);
454 cpu_state.pushToSoftIrqStack(softirq);
455 cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_SOFT_IRQ);
456
457 /* update process execution mode state stack */
458 push_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, submode, submodeId,
459 trcEvent.getTimestamp(), traceSt);
460
461 return false;
462
463 }
464 };
465 return handler;
466 }
467
468 /**
469 * Method to handle the event: LTT_EVENT_LIST_INTERRRUPT
470 *
471 * @return
472 */
473 final ILttngEventProcessor getEnumInterruptHandler() {
474 AbsStateUpdate handler = new AbsStateUpdate() {
475
476 private Events eventType = Events.LTT_EVENT_LIST_INTERRUPT;
477
478 // @Override
479 @Override
480 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
481 String action = getAFieldString(trcEvent, traceSt,
482 Fields.LTT_FIELD_ACTION);
483 Long irq = getAFieldLong(trcEvent, traceSt,
484 Fields.LTT_FIELD_IRQ_ID);
485
486 if (action == null) {
487 TraceDebug.debug("Field Action not found in event " //$NON-NLS-1$
488 + eventType.getInName() + " time: " //$NON-NLS-1$
489 + trcEvent.getTimestamp());
490 return true;
491 }
492
493 if (irq == null) {
494 TraceDebug.debug("Field irq_id not found in event " //$NON-NLS-1$
495 + eventType.getInName() + " time: " //$NON-NLS-1$
496 + trcEvent.getTimestamp());
497 return true;
498 }
499
500 Map<Long, String> irq_names = traceSt.getIrq_names();
501
502 irq_names.put(irq, action);
503 return false;
504
505 }
506 };
507 return handler;
508 }
509
510 /**
511 * Handle the event LTT_EVENT_REQUEST_ISSUE
512 *
513 * @return
514 */
515 final ILttngEventProcessor getBdevRequestIssueHandler() {
516 AbsStateUpdate handler = new AbsStateUpdate() {
517
518 // @Override
519 @Override
520 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
521
522 // Get Fields
523 Long major = getAFieldLong(trcEvent, traceSt,
524 Fields.LTT_FIELD_MAJOR);
525 Long minor = getAFieldLong(trcEvent, traceSt,
526 Fields.LTT_FIELD_MINOR);
527 Long operation = getAFieldLong(trcEvent, traceSt,
528 Fields.LTT_FIELD_OPERATION);
529
530 // calculate bdevcode
531 Long devcode = mkdev(major, minor);
532
533 if (devcode == null) {
534 TraceDebug
535 .debug("incorrect calcualtion of bdevcode input( major: " //$NON-NLS-1$
536 + major
537 + " minor: " //$NON-NLS-1$
538 + minor
539 + " operation: " + operation); //$NON-NLS-1$
540 return true;
541 }
542
543 Map<Long, LttngBdevState> bdev_states = traceSt
544 .getBdev_states();
545 // Get the instance
546 LttngBdevState bdevState = bdev_states.get(devcode);
547 if (bdevState == null) {
548 bdevState = new LttngBdevState();
549 }
550
551 // update the mode in the stack
552 if (operation == 0L) {
553 bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_READING);
554 } else {
555 bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_WRITING);
556 }
557
558 // make sure it is included in the set
559 bdev_states.put(devcode, bdevState);
560 return false;
561
562 }
563 };
564 return handler;
565 }
566
567 /**
568 * <p>
569 * Handling event: LTT_EVENT_REQUEST_COMPLETE
570 * </p>
571 * <p>
572 * FIELDS(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION
573 * </p>
574 *
575 * @return
576 */
577 final ILttngEventProcessor getBdevRequestCompleteHandler() {
578 AbsStateUpdate handler = new AbsStateUpdate() {
579
580 // @Override
581 @Override
582 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
583
584 // Get Fields
585 Long major = getAFieldLong(trcEvent, traceSt,
586 Fields.LTT_FIELD_MAJOR);
587 Long minor = getAFieldLong(trcEvent, traceSt,
588 Fields.LTT_FIELD_MINOR);
589 Long operation = getAFieldLong(trcEvent, traceSt,
590 Fields.LTT_FIELD_OPERATION);
591
592 // calculate bdevcode
593 Long devcode = mkdev(major, minor);
594
595 if (devcode == null) {
596 TraceDebug
597 .debug("incorrect calcualtion of bdevcode input( major: " //$NON-NLS-1$
598 + major
599 + " minor: " //$NON-NLS-1$
600 + minor
601 + " operation: " + operation); //$NON-NLS-1$
602 return true;
603 }
604
605 Map<Long, LttngBdevState> bdev_states = traceSt
606 .getBdev_states();
607 // Get the instance
608 LttngBdevState bdevState = bdev_states.get(devcode);
609 if (bdevState == null) {
610 bdevState = new LttngBdevState();
611 }
612
613 /* update block device */
614 bdev_pop_mode(bdevState);
615
616 return false;
617
618 }
619 };
620 return handler;
621 }
622
623 /**
624 * <p>
625 * Handles event: LTT_EVENT_FUNCTION_ENTRY
626 * </p>
627 * <p>
628 * FIELDS: LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE
629 * </p>
630 *
631 * @return
632 */
633 final ILttngEventProcessor getFunctionEntryHandler() {
634 AbsStateUpdate handler = new AbsStateUpdate() {
635
636 // @Override
637 @Override
638 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
639 Long cpu = trcEvent.getCpuId();
640 Long funcptr = getAFieldLong(trcEvent, traceSt,
641 Fields.LTT_FIELD_THIS_FN);
642
643 push_function(traceSt, funcptr, cpu);
644 return false;
645
646 }
647 };
648 return handler;
649 }
650
651 /**
652 *
653 * @return
654 */
655 final ILttngEventProcessor getFunctionExitHandler() {
656 AbsStateUpdate handler = new AbsStateUpdate() {
657
658 // @Override
659 @Override
660 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
661
662 Long funcptr = getAFieldLong(trcEvent, traceSt,
663 Fields.LTT_FIELD_THIS_FN);
664
665 pop_function(traceSt, trcEvent, funcptr);
666 return false;
667
668 }
669 };
670 return handler;
671 }
672
673 /**
674 * <p>
675 * process event: LTT_EVENT_SYS_CALL_TABLE
676 * </p>
677 * <p>
678 * fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
679 * </p>
680 *
681 * @return
682 */
683 final ILttngEventProcessor getDumpSyscallHandler() {
684 AbsStateUpdate handler = new AbsStateUpdate() {
685
686 // @Override
687 @Override
688 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
689 // obtain the syscall id
690 Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID);
691
692 // Long address = getAFieldLong(trcEvent, traceSt,
693 // Fields.LTT_FIELD_ADDRESS);
694
695 // Obtain the symbol
696 String symbol = getAFieldString(trcEvent, traceSt,
697 Fields.LTT_FIELD_SYMBOL);
698
699 // fill the symbol to the sycall_names collection
700 traceSt.getSyscall_names().put(id, symbol);
701
702 return false;
703 }
704 };
705 return handler;
706 }
707
708 /**
709 * <p>
710 * Handles event: LTT_EVENT_KPROBE_TABLE
711 * </p>
712 * <p>
713 * Fields: LTT_FIELD_IP, LTT_FIELD_SYMBOL
714 * </p>
715 *
716 * @return
717 */
718 final ILttngEventProcessor getDumpKprobeHandler() {
719 AbsStateUpdate handler = new AbsStateUpdate() {
720
721 // @Override
722 @Override
723 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
724
725 Long ip = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_IP);
726 String symbol = getAFieldString(trcEvent, traceSt,
727 Fields.LTT_FIELD_SYMBOL);
728
729 traceSt.getKprobe_table().put(ip, symbol);
730
731 return false;
732
733 }
734 };
735 return handler;
736 }
737
738 /**
739 * <p>
740 * Handles: LTT_EVENT_SOFTIRQ_VEC
741 * </p>
742 * <p>
743 * Fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
744 * </p>
745 *
746 * @return
747 */
748 final ILttngEventProcessor getDumpSoftIrqHandler() {
749 AbsStateUpdate handler = new AbsStateUpdate() {
750
751 // @Override
752 @Override
753 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
754
755 // Get id
756 Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID);
757
758 // Address not needed
759 // Long address = ltt_event_get_long_unsigned(e,
760 // lttv_trace_get_hook_field(th,
761 // 1));
762
763 // Get symbol
764 String symbol = getAFieldString(trcEvent, traceSt,
765 Fields.LTT_FIELD_SYMBOL);
766
767 // Register the soft irq name
768 traceSt.getSoft_irq_names().put(id, symbol);
769 return false;
770
771 }
772 };
773 return handler;
774 }
775
776 /**
777 * <p>
778 * Handles: LTT_EVENT_SCHED_SCHEDULE
779 * </p>
780 * <p>
781 * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
782 * </p>
783 *
784 * @return
785 */
786 final ILttngEventProcessor getSchedChangeHandler() {
787 AbsStateUpdate handler = new AbsStateUpdate() {
788
789 // @Override
790 @Override
791 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
792
793 Long cpu = trcEvent.getCpuId();
794 TmfTimestamp eventTime = trcEvent.getTimestamp();
795
796 LttngProcessState process = traceSt.getRunning_process().get(
797 cpu);
798
799 Long pid_out = getAFieldLong(trcEvent, traceSt,
800 Fields.LTT_FIELD_PREV_PID);
801 Long pid_in = getAFieldLong(trcEvent, traceSt,
802 Fields.LTT_FIELD_NEXT_PID);
803 Long state_out = getAFieldLong(trcEvent, traceSt,
804 Fields.LTT_FIELD_PREV_STATE);
805
806 if (process != null) {
807
808 /*
809 * We could not know but it was not the idle process
810 * executing. This should only happen at the beginning,
811 * before the first schedule event, and when the initial
812 * information (current process for each CPU) is missing. It
813 * is not obvious how we could, after the fact, compensate
814 * the wrongly attributed statistics.
815 */
816
817 // This test only makes sense once the state is known and if
818 // there
819 // is no
820 // missing events. We need to silently ignore schedchange
821 // coming
822 // after a
823 // process_free, or it causes glitches. (FIXME)
824 // if(unlikely(process->pid != pid_out)) {
825 // g_assert(process->pid == 0);
826 // }
827 if ((process.getPid().longValue() == 0L)
828 && (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
829 if ((pid_out != null) && (pid_out.longValue() == 0L)) {
830 /*
831 * Scheduling out of pid 0 at beginning of the trace
832 * : we know for sure it is in syscall mode at this
833 * point.
834 */
835
836 process.getState().setExec_mode(
837 ExecutionMode.LTTV_STATE_SYSCALL);
838 process.getState().setProc_status(
839 ProcessStatus.LTTV_STATE_WAIT);
840 process.getState().setChange_Time(
841 trcEvent.getTimestamp().getValue());
842 process.getState().setEntry_Time(
843 trcEvent.getTimestamp().getValue());
844 }
845 } else {
846 if (process.getState().getProc_status() == ProcessStatus.LTTV_STATE_EXIT) {
847 process.getState().setProc_status(
848 ProcessStatus.LTTV_STATE_ZOMBIE);
849 process.getState().setChange_Time(
850 trcEvent.getTimestamp().getValue());
851 } else {
852 if ((state_out != null)
853 && (state_out.longValue() == 0L)) {
854 process.getState().setProc_status(
855 ProcessStatus.LTTV_STATE_WAIT_CPU);
856 } else {
857 process.getState().setProc_status(
858 ProcessStatus.LTTV_STATE_WAIT);
859 }
860
861 process.getState().setChange_Time(
862 trcEvent.getTimestamp().getValue());
863 }
864
865 if ((state_out != null)
866 && (state_out == 32L || state_out == 64L)) { /*
867 * EXIT_DEAD
868 * ||
869 * TASK_DEAD
870 */
871 /* see sched.h for states */
872 if (!exit_process(traceSt, process)) {
873 process.getState().setProc_status(
874 ProcessStatus.LTTV_STATE_DEAD);
875 process.getState().setChange_Time(
876 trcEvent.getTimestamp().getValue());
877 }
878 }
879 }
880 }
881 process = lttv_state_find_process_or_create(traceSt, cpu,
882 pid_in, eventTime);
883
884 traceSt.getRunning_process().put(cpu, process);
885
886 process.getState().setProc_status(ProcessStatus.LTTV_STATE_RUN);
887 process.getState().setChange_Time(eventTime.getValue());
888 process.setCpu(cpu);
889 // process->state->s = LTTV_STATE_RUN;
890 // if(process->usertrace)
891 // process->usertrace->cpu = cpu;
892 // process->last_cpu_index =
893 // ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
894
895 // process->state->change = s->parent.timestamp;
896
897 LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu);
898 /* update cpu status */
899 if ((pid_in != null) && (pid_in.longValue() == 0L)) {
900
901 /* going to idle task */
902 cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_IDLE);
903 } else {
904 /*
905 * scheduling a real task. we must be careful here: if we
906 * just schedule()'ed to a process that is in a trap, we
907 * must put the cpu in trap mode
908 */
909 cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_BUSY);
910 if (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_TRAP) {
911 cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_TRAP);
912 }
913 }
914 return false;
915
916 }
917 };
918 return handler;
919 }
920
921 /**
922 * <p>
923 * Handles: LTT_EVENT_PROCESS_FORK
924 * </p>
925 * <p>
926 * Fields: FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID,
927 * LTT_FIELD_CHILD_TGID)
928 * </p>
929 *
930 * @return
931 */
932 final ILttngEventProcessor getProcessForkHandler() {
933 AbsStateUpdate handler = new AbsStateUpdate() {
934
935 // @Override
936 @Override
937 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
938
939 Long cpu = trcEvent.getCpuId();
940 LttngProcessState process = traceSt.getRunning_process().get(
941 cpu);
942 TmfTimestamp timeStamp = trcEvent.getTimestamp();
943
944 // /* Parent PID */
945 // Long parent_pid = getAFieldLong(trcEvent, traceSt,
946 // Fields.LTT_FIELD_PARENT_PID);
947
948 /* Child PID */
949 /* In the Linux Kernel, there is one PID per thread. */
950 Long child_pid = getAFieldLong(trcEvent, traceSt,
951 Fields.LTT_FIELD_CHILD_PID);
952
953 /* Child TGID */
954 /* tgid in the Linux kernel is the "real" POSIX PID. */
955 Long child_tgid = getAFieldLong(trcEvent, traceSt,
956 Fields.LTT_FIELD_CHILD_TGID);
957 if (child_tgid == null) {
958 child_tgid = 0L;
959 }
960
961 /*
962 * Mathieu : it seems like the process might have been scheduled
963 * in before the fork, and, in a rare case, might be the current
964 * process. This might happen in a SMP case where we don't have
965 * enough precision on the clocks.
966 *
967 * Test reenabled after precision fixes on time. (Mathieu)
968 */
969 // #if 0
970 // zombie_process = lttv_state_find_process(ts, ANY_CPU,
971 // child_pid);
972 //
973 // if(unlikely(zombie_process != NULL)) {
974 // /* Reutilisation of PID. Only now we are sure that the old
975 // PID
976 // * has been released. FIXME : should know when release_task
977 // happens
978 // instead.
979 // */
980 // guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
981 // guint i;
982 // for(i=0; i< num_cpus; i++) {
983 // g_assert(zombie_process != ts->running_process[i]);
984 // }
985 //
986 // exit_process(s, zombie_process);
987 // }
988 // #endif //0
989
990 if (process.getPid().equals(child_pid)) {
991 TraceDebug
992 .debug("Unexpected, process pid equal to child pid: " //$NON-NLS-1$
993 + child_pid
994 + " Event Time: " //$NON-NLS-1$
995 + trcEvent.getTimestamp());
996 }
997
998 // g_assert(process->pid != child_pid);
999 // FIXME : Add this test in the "known state" section
1000 // g_assert(process->pid == parent_pid);
1001 LttngProcessState child_process = lttv_state_find_process(
1002 traceSt, ANY_CPU, child_pid);
1003 if (child_process == null) {
1004 child_process = create_process(traceSt, cpu, child_pid,
1005 child_tgid, timeStamp);
1006 child_process.setPpid(process.getPid(), timeStamp.getValue());
1007 } else {
1008 /*
1009 * The process has already been created : due to time
1010 * imprecision between multiple CPUs : it has been scheduled
1011 * in before creation. Note that we shouldn't have this kind
1012 * of imprecision.
1013 *
1014 * Simply put a correct parent.
1015 */
1016 StringBuilder sb = new StringBuilder("Process " + child_pid); //$NON-NLS-1$
1017 sb.append(" has been created at [" //$NON-NLS-1$
1018 + child_process.getCreation_time() + "] "); //$NON-NLS-1$
1019 sb.append("and inserted at [" //$NON-NLS-1$
1020 + child_process.getInsertion_time() + "] "); //$NON-NLS-1$
1021 sb.append("before \nfork on cpu " + cpu + " Event time: [" //$NON-NLS-1$ //$NON-NLS-2$
1022 + trcEvent + "]\n."); //$NON-NLS-1$
1023 sb
1024 .append("Probably an unsynchronized TSD problem on the traced machine."); //$NON-NLS-1$
1025 TraceDebug.debug(sb.toString());
1026
1027 // g_assert(0); /* This is a problematic case : the process
1028 // has
1029 // beencreated
1030 // before the fork event */
1031 child_process.setPpid(process.getPid());
1032 child_process.setTgid(child_tgid);
1033 }
1034
1035 if (!child_process.getName().equals(
1036 ProcessStatus.LTTV_STATE_UNNAMED.getInName())) {
1037 TraceDebug.debug("Unexpected child process status: " //$NON-NLS-1$
1038 + child_process.getName());
1039 }
1040
1041 child_process.setName(process.getName());
1042 child_process.setBrand(process.getBrand());
1043
1044 return false;
1045
1046 }
1047 };
1048 return handler;
1049 }
1050
1051 /**
1052 * <p>
1053 * Handles: LTT_EVENT_KTHREAD_CREATE
1054 * </p>
1055 * <p>
1056 * Fields: LTT_FIELD_PID
1057 * </p>
1058 *
1059 * @return
1060 */
1061 final ILttngEventProcessor getProcessKernelThreadHandler() {
1062 AbsStateUpdate handler = new AbsStateUpdate() {
1063
1064 // @Override
1065 @Override
1066 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1067 /*
1068 * We stamp a newly created process as kernel_thread. The thread
1069 * should not be running yet.
1070 */
1071
1072 LttngExecutionState exState;
1073 Long pid;
1074 LttngProcessState process;
1075
1076 /* PID */
1077 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1078 // s->parent.target_pid = pid;
1079
1080 process = lttv_state_find_process_or_create(traceSt, ANY_CPU,
1081 pid, new TmfTimestamp());
1082
1083 if (!process.getState().getProc_status().equals(
1084 ProcessStatus.LTTV_STATE_DEAD)) {
1085 // Leave only the first element in the stack with execution
1086 // mode to
1087 // syscall
1088 exState = process.getFirstElementFromExecutionStack();
1089 exState.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1090 process.clearExecutionStack();
1091 process.pushToExecutionStack(exState);
1092 }
1093
1094 process.setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1095
1096 return false;
1097
1098 }
1099 };
1100 return handler;
1101 }
1102
1103 /**
1104 * <p>
1105 * Handles: LTT_EVENT_PROCESS_EXIT
1106 * </p>
1107 * <p>
1108 * LTT_FIELD_PID
1109 * </p>
1110 *
1111 * @return
1112 */
1113 final ILttngEventProcessor getProcessExitHandler() {
1114 AbsStateUpdate handler = new AbsStateUpdate() {
1115
1116 // @Override
1117 @Override
1118 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1119
1120 Long pid;
1121 LttngProcessState process;
1122
1123 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1124 // s->parent.target_pid = pid;
1125
1126 // FIXME : Add this test in the "known state" section
1127 // g_assert(process->pid == pid);
1128
1129 process = lttv_state_find_process(traceSt, ANY_CPU, pid);
1130 if (process != null) {
1131 process.getState().setProc_status(
1132 ProcessStatus.LTTV_STATE_EXIT);
1133 }
1134 return false;
1135
1136 }
1137 };
1138 return handler;
1139 }
1140
1141 /**
1142 * <p>
1143 * Handles: LTT_EVENT_PROCESS_FREE
1144 * </p>
1145 * <p>
1146 * Fields: LTT_FIELD_PID
1147 * </p>
1148 *
1149 * @return
1150 */
1151 final ILttngEventProcessor getProcessFreeHandler() {
1152 AbsStateUpdate handler = new AbsStateUpdate() {
1153
1154 // @Override
1155 @Override
1156 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1157
1158 Long release_pid;
1159 LttngProcessState process;
1160
1161 /* PID of the process to release */
1162 release_pid = getAFieldLong(trcEvent, traceSt,
1163 Fields.LTT_FIELD_PID);
1164 // s->parent.target_pid = release_pid;
1165
1166 if ((release_pid != null) && (release_pid.longValue() == 0L)) {
1167 TraceDebug.debug("Unexpected release_pid: 0, Event time: " //$NON-NLS-1$
1168 + trcEvent.getTimestamp());
1169 }
1170
1171 process = lttv_state_find_process(traceSt, ANY_CPU, release_pid);
1172 if (process != null) {
1173 exit_process(traceSt, process);
1174 }
1175
1176 return false;
1177 // DISABLED
1178 // if(process != null) {
1179 /*
1180 * release_task is happening at kernel level : we can now safely
1181 * release the data structure of the process
1182 */
1183 // This test is fun, though, as it may happen that
1184 // at time t : CPU 0 : process_free
1185 // at time t+150ns : CPU 1 : schedule out
1186 // Clearly due to time imprecision, we disable it. (Mathieu)
1187 // If this weird case happen, we have no choice but to put the
1188 // Currently running process on the cpu to 0.
1189 // I re-enable it following time precision fixes. (Mathieu)
1190 // Well, in the case where an process is freed by a process on
1191 // another
1192 // CPU
1193 // and still scheduled, it happens that this is the schedchange
1194 // that
1195 // will
1196 // drop the last reference count. Do not free it here!
1197
1198 // int num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1199 // guint i;
1200 // for(i=0; i< num_cpus; i++) {
1201 // //g_assert(process != ts->running_process[i]);
1202 // if(process == ts->running_process[i]) {
1203 // //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
1204 // break;
1205 // }
1206 // }
1207 // if(i == num_cpus) /* process is not scheduled */
1208 // exit_process(s, process);
1209 // }
1210 //
1211 // return false;
1212
1213 }
1214 };
1215 return handler;
1216 }
1217
1218 /**
1219 * <p>
1220 * Handles: LTT_EVENT_EXEC
1221 * </p>
1222 * <p>
1223 * FIELDS: LTT_FIELD_FILENAME
1224 * </p>
1225 *
1226 * @return
1227 */
1228 final ILttngEventProcessor getProcessExecHandler() {
1229 AbsStateUpdate handler = new AbsStateUpdate() {
1230
1231 // @Override
1232 @Override
1233 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1234
1235 Long cpu = trcEvent.getCpuId();
1236 LttngProcessState process = traceSt.getRunning_process().get(
1237 cpu);
1238
1239 // #if 0//how to use a sequence that must be transformed in a
1240 // string
1241 // /* PID of the process to release */
1242 // guint64 name_len = ltt_event_field_element_number(e,
1243 // lttv_trace_get_hook_field(th, 0));
1244 // //name = ltt_event_get_string(e,
1245 // lttv_trace_get_hook_field(th, 0));
1246 // LttField *child = ltt_event_field_element_select(e,
1247 // lttv_trace_get_hook_field(th, 0), 0);
1248 // gchar *name_begin =
1249 // (gchar*)(ltt_event_data(e)+ltt_event_field_offset(e, child));
1250 // gchar *null_term_name = g_new(gchar, name_len+1);
1251 // memcpy(null_term_name, name_begin, name_len);
1252 // null_term_name[name_len] = '\0';
1253 // process->name = g_quark_from_string(null_term_name);
1254 // #endif //0
1255
1256 process.setName(getAFieldString(trcEvent, traceSt,
1257 Fields.LTT_FIELD_FILENAME));
1258 process.setBrand(StateStrings.LTTV_STATE_UNBRANDED);
1259 return false;
1260
1261 }
1262 };
1263 return handler;
1264 }
1265
1266 /**
1267 * <p>
1268 * LTT_EVENT_THREAD_BRAND
1269 * </p>
1270 * <p>
1271 * FIELDS: LTT_FIELD_NAME
1272 * </p>
1273 *
1274 * @return
1275 */
1276 final ILttngEventProcessor GetThreadBrandHandler() {
1277 AbsStateUpdate handler = new AbsStateUpdate() {
1278
1279 // @Override
1280 @Override
1281 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1282
1283 String name;
1284 Long cpu = trcEvent.getCpuId();
1285 LttngProcessState process = traceSt.getRunning_process().get(
1286 cpu);
1287
1288 name = getAFieldString(trcEvent, traceSt, Fields.LTT_FIELD_NAME);
1289 process.setBrand(name);
1290 return false;
1291
1292 }
1293 };
1294 return handler;
1295 }
1296
1297 /**
1298 * @return
1299 */
1300 final ILttngEventProcessor getStateDumpEndHandler() {
1301 AbsStateUpdate handler = new AbsStateUpdate() {
1302
1303 // @Override
1304 @Override
1305 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1306
1307 /* For all processes */
1308 /*
1309 * if kernel thread, if stack[0] is unknown, set to syscall
1310 * mode, wait
1311 */
1312 /* else, if stack[0] is unknown, set to user mode, running */
1313 LttngProcessState[] processes = traceSt.getProcesses();
1314 TmfTimestamp time = trcEvent.getTimestamp();
1315
1316 for (int pos = 0; pos < processes.length; pos++) {
1317 fix_process(processes[pos], time);
1318 }
1319
1320 // Set the current process to be running
1321 // TODO Should we do it for all process running on a cpu?
1322 LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId());
1323 process.getState().setProc_status(ProcessStatus.LTTV_STATE_RUN);
1324
1325 return false;
1326
1327 }
1328
1329 /**
1330 * Private method used to establish the first execution state in the
1331 * stack for a given process
1332 *
1333 * @param process
1334 * @param timestamp
1335 */
1336 private void fix_process(LttngProcessState process,
1337 TmfTimestamp timestamp) {
1338
1339 LttngExecutionState es;
1340
1341 if (process.getType() == ProcessType.LTTV_STATE_KERNEL_THREAD) {
1342 es = process.getFirstElementFromExecutionStack();
1343
1344 if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) {
1345 es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1346 es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName());
1347 // Note: For statistics performance improvement a integer representation of the submode is used
1348 // as well as a bit mask is applied!
1349 es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.ordinal() | LttngConstants.STATS_NONE_ID);
1350 es.setEntry_Time(timestamp.getValue());
1351 es.setChange_Time(timestamp.getValue());
1352 es.setCum_cpu_time(0L);
1353 if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) {
1354 es.setProc_status(ProcessStatus.LTTV_STATE_WAIT);
1355 }
1356 }
1357 } else {
1358 es = process.getFirstElementFromExecutionStack();
1359 if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) {
1360 es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE);
1361 es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName());
1362 // Note: For statistics performance improvement a integer representation of the submode is used
1363 // as well as a bit mask is applied!
1364 es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.ordinal() | LttngConstants.STATS_NONE_ID);
1365 es.setEntry_Time(timestamp.getValue());
1366 es.setChange_Time(timestamp.getValue());
1367 es.setCum_cpu_time(0L);
1368 if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) {
1369 es.setProc_status(ProcessStatus.LTTV_STATE_RUN);
1370 }
1371
1372 // If the first element is also the one on top... mean
1373 // we have ONE element on the stack
1374 if (process.getFirstElementFromExecutionStack() == process
1375 .peekFromExecutionStack()) {
1376 /*
1377 * Still in bottom unknown mode, means never did a
1378 * system call May be either in user mode, syscall
1379 * mode, running or waiting.
1380 */
1381 /*
1382 * FIXME : we may be tagging syscall mode when being
1383 * user mode
1384 */
1385 // Get a new execution State
1386 es = new LttngExecutionState();
1387
1388 // initialize values
1389 es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1390 es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName());
1391 // Note: For statistics performance improvement a integer representation of the submode is used
1392 // as well as a bit mask is applied!
1393 es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.ordinal() | LttngConstants.STATS_NONE_ID);
1394 es.setEntry_Time(timestamp.getValue());
1395 es.setChange_Time(timestamp.getValue());
1396 es.setCum_cpu_time(0L);
1397 es.setProc_status(ProcessStatus.LTTV_STATE_WAIT);
1398
1399 // Push the new state to the stack
1400 process.pushToExecutionStack(es);
1401 }
1402 }
1403 }
1404 }
1405 };
1406 return handler;
1407 }
1408
1409 /**
1410 * <p>
1411 * Handles: LTT_EVENT_PROCESS_STATE
1412 * </p>
1413 * <p>
1414 * FIELDS: LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
1415 * LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, LTT_FIELD_STATUS,
1416 * LTT_FIELD_TGID
1417 * </p>
1418 *
1419 * @return
1420 */
1421 final ILttngEventProcessor getEnumProcessStateHandler() {
1422 AbsStateUpdate handler = new AbsStateUpdate() {
1423
1424 // @Override
1425 @Override
1426 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1427
1428 Long parent_pid;
1429 Long pid;
1430 Long tgid;
1431 String command;
1432 Long cpu = trcEvent.getCpuId();
1433
1434 LttngProcessState process = traceSt.getRunning_process().get(
1435 cpu);
1436 LttngProcessState parent_process;
1437 String type;
1438 // String mode, submode, status;
1439 LttngExecutionState es;
1440
1441 /* PID */
1442 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1443
1444 /* Parent PID */
1445 parent_pid = getAFieldLong(trcEvent, traceSt,
1446 Fields.LTT_FIELD_PARENT_PID);
1447
1448 /* Command name */
1449 command = getAFieldString(trcEvent, traceSt,
1450 Fields.LTT_FIELD_NAME);
1451
1452 Long typeVal = getAFieldLong(trcEvent, traceSt,
1453 Fields.LTT_FIELD_TYPE);
1454
1455 type = ProcessType.LTTV_STATE_KERNEL_THREAD.getInName();
1456 if ((typeVal != null) && (typeVal.longValue() == 0L)) {
1457 type = ProcessType.LTTV_STATE_USER_THREAD.getInName();
1458 }
1459
1460 // /* mode */
1461 // mode = getAFieldString(trcEvent, traceSt,
1462 // Fields.LTT_FIELD_MODE);
1463 //
1464 // /* submode */
1465 // submode = getAFieldString(trcEvent, traceSt,
1466 // Fields.LTT_FIELD_SUBMODE);
1467 //
1468 // /* status */
1469 // status = getAFieldString(trcEvent, traceSt,
1470 // Fields.LTT_FIELD_STATUS);
1471
1472 /* TGID */
1473 tgid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_TGID);
1474 if (tgid == null) {
1475 tgid = 0L;
1476 }
1477
1478 if ((pid != null) && (pid.longValue() == 0L)) {
1479 for (Long acpu : traceSt.getCpu_states().keySet()) {
1480 process = lttv_state_find_process(traceSt, acpu, pid);
1481 if (process != null) {
1482 process.setPpid(parent_pid);
1483 process.setTgid(tgid);
1484 process.setName(command);
1485 process
1486 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1487 } else {
1488 StringBuilder sb = new StringBuilder(
1489 "Unexpected, null process read from the TraceState list of processes, event time: " //$NON-NLS-1$
1490 + trcEvent.getTimestamp());
1491 TraceDebug.debug(sb.toString());
1492 }
1493 }
1494 } else {
1495 /*
1496 * The process might exist if a process was forked while
1497 * performing the state dump.
1498 */
1499 process = lttv_state_find_process(traceSt, ANY_CPU, pid);
1500 if (process == null) {
1501 parent_process = lttv_state_find_process(traceSt,
1502 ANY_CPU, parent_pid);
1503 TmfTimestamp eventTime = trcEvent.getTimestamp();
1504 process = create_process(traceSt, cpu, pid, tgid,
1505 command, eventTime);
1506 if (parent_process != null) {
1507 process.setPpid(parent_process.getPid(), eventTime.getValue());
1508 }
1509
1510 /* Keep the stack bottom : a running user mode */
1511 /*
1512 * Disabled because of inconsistencies in the current
1513 * statedump states.
1514 */
1515 if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD
1516 .getInName())) {
1517 /*
1518 * FIXME Kernel thread : can be in syscall or
1519 * interrupt or trap.
1520 */
1521 /*
1522 * Will cause expected trap when in fact being
1523 * syscall (even after end of statedump event) Will
1524 * cause expected interrupt when being syscall.
1525 * (only before end of statedump event)
1526 */
1527 // process type is USER_THREAD by default.
1528 process
1529 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1530
1531 }
1532
1533 //Only one entry needed in the execution stack
1534 process.popFromExecutionStack();
1535 es = process.getState();
1536 es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN);
1537 es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED);
1538 es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
1539 .getInName());
1540 // Note: For statistics performance improvement a integer representation of the submode is used
1541 // as well as a bit mask is applied!
1542 es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.ordinal() | LttngConstants.STATS_NONE_ID);
1543
1544 // #if 0
1545 // /* UNKNOWN STATE */
1546 // {
1547 // es = process->state =
1548 // &g_array_index(process->execution_stack,
1549 // LttvExecutionState, 1);
1550 // es->t = LTTV_STATE_MODE_UNKNOWN;
1551 // es->s = LTTV_STATE_UNNAMED;
1552 // es->n = LTTV_STATE_SUBMODE_UNKNOWN;
1553 // }
1554 // #endif //0
1555 } else {
1556 /*
1557 * The process has already been created : Probably was
1558 * forked while dumping the process state or was simply
1559 * scheduled in prior to get the state dump event.
1560 */
1561 process.setPpid(parent_pid);
1562 process.setTgid(tgid);
1563 process.setName(command);
1564 if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD
1565 .getInName())) {
1566 process
1567 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1568 } else {
1569 process.setType(ProcessType.LTTV_STATE_USER_THREAD);
1570 }
1571
1572 // es =
1573 // &g_array_index(process->execution_stack,
1574 // LttvExecutionState,
1575 // 0);
1576 // #if 0
1577 // if(es->t == LTTV_STATE_MODE_UNKNOWN) {
1578 // if(type == LTTV_STATE_KERNEL_THREAD)
1579 // es->t = LTTV_STATE_SYSCALL;
1580 // else
1581 // es->t = LTTV_STATE_USER_MODE;
1582 // }
1583 // #endif //0
1584 /*
1585 * Don't mess around with the stack, it will eventually
1586 * become ok after the end of state dump.
1587 */
1588 }
1589 }
1590
1591 return false;
1592
1593 }
1594 };
1595 return handler;
1596 }
1597
1598 }
This page took 0.073474 seconds and 5 git commands to generate.