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