~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CtfKernelHandler.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2012 Ericsson
 
3
 * Copyright (c) 2010, 2011 Ć‰cole Polytechnique de MontrĆ©al
 
4
 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
 
5
 * 
 
6
 * All rights reserved. This program and the accompanying materials are
 
7
 * made available under the terms of the Eclipse Public License v1.0 which
 
8
 * accompanies this distribution, and is available at
 
9
 * http://www.eclipse.org/legal/epl-v10.html
 
10
 * 
 
11
 *******************************************************************************/
 
12
 
 
13
package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
 
14
 
 
15
import java.util.ArrayList;
 
16
import java.util.HashMap;
 
17
import java.util.List;
 
18
import java.util.concurrent.BlockingQueue;
 
19
 
 
20
import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
 
21
import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings;
 
22
import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues;
 
23
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
 
24
import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
 
25
import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 
26
import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
 
27
import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
 
28
import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder;
 
29
import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
 
30
import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
 
31
 
 
32
/**
 
33
 * This is the reference "state provider" for LTTng 2.0 kernel traces.
 
34
 * 
 
35
 * @author alexmont
 
36
 * 
 
37
 */
 
38
class CtfKernelHandler implements Runnable {
 
39
 
 
40
    private final BlockingQueue<CtfTmfEvent> inQueue;
 
41
    private IStateSystemBuilder ss;
 
42
 
 
43
    private CtfTmfEvent currentEvent;
 
44
 
 
45
    /*
 
46
     * We can keep handles to some Attribute Nodes so these don't need to be
 
47
     * re-found (re-hashed Strings etc.) every new event
 
48
     */
 
49
    List<Integer> currentCPUNodes;
 
50
    List<Integer> currentThreadNodes;
 
51
 
 
52
    /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
 
53
    private final HashMap<String, Integer> knownEventNames;
 
54
 
 
55
    /* Common locations in the attribute tree */
 
56
    private int cpusNode = -1;
 
57
    private int threadsNode = -1;
 
58
    private int irqsNode = -1;
 
59
    private int softIrqsNode = -1;
 
60
 
 
61
    CtfKernelHandler(BlockingQueue<CtfTmfEvent> eventsQueue) {
 
62
        assert (eventsQueue != null);
 
63
        this.inQueue = eventsQueue;
 
64
        currentCPUNodes = new ArrayList<Integer>();
 
65
        currentThreadNodes = new ArrayList<Integer>();
 
66
 
 
67
        knownEventNames = fillEventNames();
 
68
    }
 
69
 
 
70
    void assignStateSystem(IStateSystemBuilder targetSS) {
 
71
        this.ss = targetSS;
 
72
    }
 
73
 
 
74
    @Override
 
75
    public void run() {
 
76
        if (ss == null) {
 
77
            System.err.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$
 
78
            return;
 
79
        }
 
80
        CtfTmfEvent event;
 
81
        setupCommonLocations();
 
82
 
 
83
        try {
 
84
            event = inQueue.take();
 
85
            while (event.getTimestampValue() != -1) {
 
86
                processEvent(event);
 
87
                event = inQueue.take();
 
88
            }
 
89
            /* We've received the last event, clean up */
 
90
            closeStateSystem();
 
91
            return;
 
92
        } catch (InterruptedException e) {
 
93
            /* We've been interrupted abnormally */
 
94
            System.out.println("Event handler interrupted!"); //$NON-NLS-1$
 
95
            e.printStackTrace();
 
96
        }
 
97
    }
 
98
 
 
99
    private void closeStateSystem() {
 
100
        /* Close the History system, if there is one */
 
101
        if (currentEvent == null) {
 
102
            return;
 
103
        }
 
104
        try {
 
105
            ss.closeHistory(currentEvent.getTimestamp().getValue());
 
106
        } catch (TimeRangeException e) {
 
107
            /*
 
108
             * Since we're using currentEvent.getTimestamp, this shouldn't
 
109
             * cause any problem
 
110
             */
 
111
            e.printStackTrace();
 
112
        }
 
113
    }
 
114
 
 
115
    private void processEvent(CtfTmfEvent event) {
 
116
        currentEvent = event;
 
117
        ITmfEventField content = event.getContent();
 
118
        String eventName = event.getEventName();
 
119
 
 
120
        long ts = event.getTimestamp().getValue();
 
121
        int quark;
 
122
        ITmfStateValue value;
 
123
        Integer eventCpu = event.getCPU();
 
124
        Integer currentCPUNode, currentThreadNode, tidNode;
 
125
 
 
126
        /* Adjust the current nodes Vectors if we see a new CPU in an event */
 
127
        if (eventCpu >= currentCPUNodes.size()) {
 
128
            /* We need to add this node to the vector */
 
129
            for (Integer i = currentCPUNodes.size(); i < eventCpu + 1; i++) {
 
130
                quark = ss.getQuarkRelativeAndAdd(cpusNode, i.toString());
 
131
                currentCPUNodes.add(quark);
 
132
 
 
133
                quark = ss.getQuarkRelativeAndAdd(threadsNode, Attributes.UNKNOWN);
 
134
                currentThreadNodes.add(quark);
 
135
            }
 
136
        }
 
137
 
 
138
        currentCPUNode = currentCPUNodes.get(eventCpu);
 
139
        currentThreadNode = currentThreadNodes.get(eventCpu);
 
140
        assert (currentCPUNode != null);
 
141
        assert (currentThreadNode != null);
 
142
 
 
143
        try {
 
144
            /*
 
145
             * Feed event to the history system if it's known to cause a state
 
146
             * transition.
 
147
             */
 
148
            switch (getEventIndex(eventName)) {
 
149
 
 
150
            case 1: // "exit_syscall":
 
151
            /* Fields: int64 ret */
 
152
            {
 
153
                /* Clear the current system call on the process */
 
154
                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
 
155
                value = TmfStateValue.nullValue();
 
156
                ss.modifyAttribute(ts, value, quark);
 
157
 
 
158
                /* Put the process' status back to user mode */
 
159
                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
 
160
                value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE);
 
161
                ss.modifyAttribute(ts, value, quark);
 
162
 
 
163
                /* Put the CPU's status back to user mode */
 
164
                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
 
165
                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
 
166
                ss.modifyAttribute(ts, value, quark);
 
167
            }
 
168
                break;
 
169
 
 
170
            case 2: // "irq_handler_entry":
 
171
            /* Fields: int32 irq, string name */
 
172
            {
 
173
                Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue();
 
174
 
 
175
                /* Mark this IRQ as active in the resource tree.
 
176
                 * The state value = the CPU on which this IRQ is sitting */
 
177
                quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString());
 
178
                value = TmfStateValue.newValueInt(event.getCPU());
 
179
                ss.modifyAttribute(ts, value, quark);
 
180
 
 
181
                /* Change the status of the running process to interrupted */
 
182
                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
 
183
                value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
 
184
                ss.modifyAttribute(ts, value, quark);
 
185
 
 
186
                /* Change the status of the CPU to interrupted */
 
187
                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
 
188
                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IRQ);
 
189
                ss.modifyAttribute(ts, value, quark);
 
190
            }
 
191
                break;
 
192
 
 
193
            case 3: // "irq_handler_exit":
 
194
            /* Fields: int32 irq, int32 ret */
 
195
            {
 
196
                Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue();
 
197
 
 
198
                /* Put this IRQ back to inactive in the resource tree */
 
199
                quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString());
 
200
                value = TmfStateValue.nullValue();
 
201
                ss.modifyAttribute(ts, value, quark);
 
202
 
 
203
                /* Set the previous process back to running */
 
204
                setProcessToRunning(ts, currentThreadNode);
 
205
 
 
206
                /* Set the CPU status back to running or "idle" */
 
207
                cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
 
208
            }
 
209
                break;
 
210
 
 
211
            case 4: // "softirq_entry":
 
212
            /* Fields: int32 vec */
 
213
            {
 
214
                Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
 
215
 
 
216
                /* Mark this SoftIRQ as active in the resource tree.
 
217
                 * The state value = the CPU on which this SoftIRQ is processed */
 
218
                quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
 
219
                value = TmfStateValue.newValueInt(event.getCPU());
 
220
                ss.modifyAttribute(ts, value, quark);
 
221
 
 
222
                /* Change the status of the running process to interrupted */
 
223
                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
 
224
                value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
 
225
                ss.modifyAttribute(ts, value, quark);
 
226
 
 
227
                /* Change the status of the CPU to interrupted */
 
228
                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
 
229
                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_SOFTIRQ);
 
230
                ss.modifyAttribute(ts, value, quark);
 
231
            }
 
232
                break;
 
233
 
 
234
            case 5: // "softirq_exit":
 
235
            /* Fields: int32 vec */
 
236
            {
 
237
                Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
 
238
 
 
239
                /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
 
240
                quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
 
241
                value = TmfStateValue.nullValue();
 
242
                ss.modifyAttribute(ts, value, quark);
 
243
 
 
244
                /* Set the previous process back to running */
 
245
                setProcessToRunning(ts, currentThreadNode);
 
246
 
 
247
                /* Set the CPU status back to "busy" or "idle" */
 
248
                cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
 
249
            }
 
250
                break;
 
251
 
 
252
            case 6: // "softirq_raise":
 
253
            /* Fields: int32 vec */
 
254
            {
 
255
                Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
 
256
 
 
257
                /* Mark this SoftIRQ as *raised* in the resource tree.
 
258
                 * State value = -2 */
 
259
                quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
 
260
                value = TmfStateValue.newValueInt(StateValues.SOFT_IRQ_RAISED);
 
261
                ss.modifyAttribute(ts, value, quark);
 
262
            }
 
263
                break;
 
264
 
 
265
            case 7: // "sched_switch":
 
266
            /*
 
267
             * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
 
268
             *         string next_comm, int32 next_tid, int32 next_prio
 
269
             */
 
270
            {
 
271
                Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue();
 
272
                //Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
 
273
 
 
274
                String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue();
 
275
                Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue();
 
276
 
 
277
                /* Update the currentThreadNodes pointer */
 
278
                Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, nextTid.toString());
 
279
                currentThreadNodes.set(eventCpu, newCurrentThreadNode);
 
280
 
 
281
                /*
 
282
                 * Set the status of the process that got scheduled out, but
 
283
                 * only in the case where that process is currently active.
 
284
                 */
 
285
                Integer formerThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString());
 
286
                quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.EXEC_NAME);
 
287
                value = ss.queryOngoingState(quark);
 
288
                if (!value.isNull()) {
 
289
                    quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
 
290
                    value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
 
291
                    ss.modifyAttribute(ts, value, quark);
 
292
                }
 
293
 
 
294
                /* Set the status of the new scheduled process */
 
295
                setProcessToRunning(ts, newCurrentThreadNode);
 
296
 
 
297
                /* Set the exec name of the new process */
 
298
                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME);
 
299
                value = TmfStateValue.newValueString(nextProcessName);
 
300
                ss.modifyAttribute(ts, value, quark);
 
301
 
 
302
                /*
 
303
                 * Check if we need to set the syscall state and the PPID of
 
304
                 * the new process (in case we haven't seen this process before)
 
305
                 */
 
306
                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
 
307
                if (quark == ss.getNbAttributes()) { /* Did we just add this attribute? */
 
308
                    value = TmfStateValue.nullValue();
 
309
                    ss.modifyAttribute(ts, value, quark);
 
310
                }
 
311
                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
 
312
                if (quark == ss.getNbAttributes()) {
 
313
                    value = TmfStateValue.nullValue();
 
314
                    ss.modifyAttribute(ts, value, quark);
 
315
                }
 
316
 
 
317
                /* Set the current scheduled process on the relevant CPU */
 
318
                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
 
319
                value = TmfStateValue.newValueInt(nextTid);
 
320
                ss.modifyAttribute(ts, value, quark);
 
321
 
 
322
                /* Set the status of the CPU itself */
 
323
                if (nextTid > 0) {
 
324
                    /* Check if the entering process is in kernel or user mode */
 
325
                    quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
 
326
                    if (ss.queryOngoingState(quark).isNull()) {
 
327
                        value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
 
328
                    } else {
 
329
                        value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
 
330
                    }
 
331
                } else {
 
332
                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
 
333
                }
 
334
                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
 
335
                ss.modifyAttribute(ts, value, quark);
 
336
            }
 
337
                break;
 
338
 
 
339
            case 8: // "sched_process_fork":
 
340
            /* Fields: string parent_comm, int32 parent_tid,
 
341
             *         string child_comm, int32 child_tid */
 
342
            {
 
343
                // String parentProcessName = (String)
 
344
                // event.getFieldValue("parent_comm");
 
345
                String childProcessName;
 
346
                childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue();
 
347
                // assert ( parentProcessName.equals(childProcessName) );
 
348
 
 
349
                Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue();
 
350
                Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue();
 
351
 
 
352
                tidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString());
 
353
 
 
354
                /* Assign the PPID to the new process */
 
355
                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.PPID);
 
356
                value = TmfStateValue.newValueInt(parentTid);
 
357
                ss.modifyAttribute(ts, value, quark);
 
358
 
 
359
                /* Set the new process' exec_name */
 
360
                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.EXEC_NAME);
 
361
                value = TmfStateValue.newValueString(childProcessName);
 
362
                ss.modifyAttribute(ts, value, quark);
 
363
 
 
364
                /* Set the new process' status */
 
365
                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.STATUS);
 
366
                value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
 
367
                ss.modifyAttribute(ts, value, quark);
 
368
 
 
369
                /* Set the process' syscall state */
 
370
                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.SYSTEM_CALL);
 
371
                value = TmfStateValue.nullValue();
 
372
                ss.modifyAttribute(ts, value, quark);
 
373
            }
 
374
                break;
 
375
 
 
376
            case 9: // "sched_process_exit":
 
377
            /* Fields: string comm, int32 tid, int32 prio */
 
378
            {
 
379
                String processName = (String) content.getField(LttngStrings.COMM).getValue();
 
380
                Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
 
381
 
 
382
                /* Update the process' name, if we don't have it */
 
383
                quark = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString(), Attributes.EXEC_NAME);
 
384
                value = TmfStateValue.newValueString(processName);
 
385
                ss.updateOngoingState(value, quark);
 
386
 
 
387
                /*
 
388
                 * Remove the process and all its sub-attributes from the
 
389
                 * current state
 
390
                 */
 
391
                quark = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString());
 
392
                ss.removeAttribute(ts, quark);
 
393
            }
 
394
                break;
 
395
 
 
396
            case 10: // "sched_process_free":
 
397
            /* Fields: string comm, int32 tid, int32 prio */
 
398
                break;
 
399
 
 
400
            // FIXME In CTF it's as "syscall_exec". Will have to be adapted.
 
401
            // case LTT_EVENT_EXEC:
 
402
            // filename = new String((byte[]) event.getField(0));
 
403
            //
 
404
            // /* Change the Exec_name of the process */
 
405
            // quark = ss.getQuarkRelativePath(true, currentThreadNode,
 
406
            // "Exec_name");
 
407
            // ss.modifyAttribute(ts, filename, quark);
 
408
            // break;
 
409
 
 
410
            default:
 
411
            /* Other event types not covered by the main switch */
 
412
            {
 
413
                if (eventName.startsWith(LttngStrings.SYSCALL_PREFIX)
 
414
                        || eventName.startsWith(LttngStrings.COMPAT_SYSCALL_PREFIX)) {
 
415
                    /*
 
416
                     * This is a replacement for the old sys_enter event. Now
 
417
                     * syscall names are listed into the event type
 
418
                     */
 
419
 
 
420
                    /* Assign the new system call to the process */
 
421
                    quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
 
422
                    value = TmfStateValue.newValueString(eventName);
 
423
                    ss.modifyAttribute(ts, value, quark);
 
424
 
 
425
                    /* Put the process in system call mode */
 
426
                    quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
 
427
                    value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL);
 
428
                    ss.modifyAttribute(ts, value, quark);
 
429
 
 
430
                    /* Put the CPU in system call (kernel) mode */
 
431
                    quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
 
432
                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
 
433
                    ss.modifyAttribute(ts, value, quark);
 
434
                }
 
435
            }
 
436
                break;
 
437
            } // End of big switch
 
438
 
 
439
            /*
 
440
             * Statistics
 
441
             */
 
442
 
 
443
            /* Number of events of each type, globally */
 
444
//             quark = ss.getQuarkAbsoluteAndAdd(Attributes.STATISTICS,
 
445
//                     Attributes.EVENT_TYPES, eventName);
 
446
//             ss.incrementAttribute(ts, quark);
 
447
 
 
448
            /* Number of events per CPU */
 
449
//             quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
 
450
//                     Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
 
451
//             ss.incrementAttribute(ts, quark);
 
452
 
 
453
            /* Number of events per process */
 
454
//             quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
 
455
//                     Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
 
456
//             ss.incrementAttribute(ts, quark);
 
457
 
 
458
        } catch (AttributeNotFoundException ae) {
 
459
            /*
 
460
             * This would indicate a problem with the logic of the manager here,
 
461
             * so it shouldn't happen.
 
462
             */
 
463
            ae.printStackTrace();
 
464
 
 
465
        } catch (TimeRangeException tre) {
 
466
            /*
 
467
             * This would happen if the events in the trace aren't ordered
 
468
             * chronologically, which should never be the case ...
 
469
             */
 
470
            System.err.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
 
471
            System.err.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
 
472
            tre.printStackTrace();
 
473
 
 
474
        } catch (StateValueTypeException sve) {
 
475
            /*
 
476
             * This would happen if we were trying to push/pop attributes not of
 
477
             * type integer. Which, once again, should never happen.
 
478
             */
 
479
            sve.printStackTrace();
 
480
        }
 
481
    }
 
482
 
 
483
    private void setupCommonLocations() {
 
484
        cpusNode = ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
 
485
        threadsNode = ss.getQuarkAbsoluteAndAdd(Attributes.THREADS);
 
486
        irqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS);
 
487
        softIrqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS);
 
488
    }
 
489
 
 
490
    private static HashMap<String, Integer> fillEventNames() {
 
491
        /*
 
492
         * TODO Replace with straight strings in the switch/case once we move to
 
493
         * Java 7
 
494
         */
 
495
        HashMap<String, Integer> map = new HashMap<String, Integer>();
 
496
 
 
497
        map.put(LttngStrings.EXIT_SYSCALL, 1);
 
498
        map.put(LttngStrings.IRQ_HANDLER_ENTRY, 2);
 
499
        map.put(LttngStrings.IRQ_HANDLER_EXIT, 3);
 
500
        map.put(LttngStrings.SOFTIRQ_ENTRY, 4);
 
501
        map.put(LttngStrings.SOFTIRQ_EXIT, 5);
 
502
        map.put(LttngStrings.SOFTIRQ_RAISE, 6);
 
503
        map.put(LttngStrings.SCHED_SWITCH, 7);
 
504
        map.put(LttngStrings.SCHED_PROCESS_FORK, 8);
 
505
        map.put(LttngStrings.SCHED_PROCESS_EXIT, 9);
 
506
        map.put(LttngStrings.SCHED_PROCESS_FREE, 10);
 
507
 
 
508
        return map;
 
509
    }
 
510
 
 
511
    private int getEventIndex(String eventName) {
 
512
        Integer ret = knownEventNames.get(eventName);
 
513
        return (ret != null) ? ret : -1;
 
514
    }
 
515
 
 
516
    /**
 
517
     * When we want to set a process back to a "running" state, first check
 
518
     * its current System_call attribute. If there is a system call active, we
 
519
     * put the process back in the syscall state. If not, we put it back in
 
520
     * user mode state.
 
521
     */
 
522
    private void setProcessToRunning(long ts, int currentThreadNode)
 
523
            throws AttributeNotFoundException, TimeRangeException,
 
524
            StateValueTypeException {
 
525
        int quark;
 
526
        ITmfStateValue value;
 
527
 
 
528
        quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
 
529
        if (ss.queryOngoingState(quark).isNull()) {
 
530
            /* We were in user mode before the interruption */
 
531
            value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE);
 
532
        } else {
 
533
            /* We were previously in kernel mode */
 
534
            value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL);
 
535
        }
 
536
        quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
 
537
        ss.modifyAttribute(ts, value, quark);
 
538
    }
 
539
 
 
540
    /**
 
541
     * Similar logic as above, but to set the CPU's status when it's coming out
 
542
     * of an interruption.
 
543
     * @throws AttributeNotFoundException 
 
544
     * @throws StateValueTypeException 
 
545
     * @throws TimeRangeException 
 
546
     */
 
547
    private void cpuExitInterrupt(long ts, int currentCpuNode, int currentThreadNode)
 
548
            throws StateValueTypeException, AttributeNotFoundException,
 
549
            TimeRangeException {
 
550
        int quark;
 
551
        ITmfStateValue value;
 
552
 
 
553
        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);
 
554
        if (ss.queryOngoingState(quark).unboxInt() > 0) {
 
555
            /* There was a process on the CPU */
 
556
            quark = ss.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL);
 
557
            if (ss.queryOngoingState(quark).isNull()) {
 
558
                /* That process was in user mode */
 
559
                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
 
560
            } else {
 
561
                /* That process was in a system call */
 
562
                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
 
563
            }
 
564
        } else {
 
565
            /* There was no real process scheduled, CPU was idle */
 
566
            value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
 
567
        }
 
568
        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);
 
569
        ss.modifyAttribute(ts, value, quark);
 
570
    }
 
571
}