Convert Windows line delimiters to Unix.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.core / src / org / eclipse / linuxtools / internal / lttng2 / kernel / core / stateprovider / CtfKernelHandler.java
index c88827643c68a001dc7643492a2c93baaa78a6f2..8911c963f8bc3fcb0322fcf750c1cabf5de96027 100644 (file)
@@ -2,23 +2,22 @@
  * Copyright (c) 2012 Ericsson
  * Copyright (c) 2010, 2011 École Polytechnique de Montréal
  * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- * 
+ *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
  * accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
 
 import java.util.HashMap;
-import java.util.Vector;
 import java.util.concurrent.BlockingQueue;
 
 import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings;
 import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues;
-import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngStrings;
 import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
@@ -30,9 +29,9 @@ import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
 
 /**
  * This is the reference "state provider" for LTTng 2.0 kernel traces.
- * 
+ *
  * @author alexmont
- * 
+ *
  */
 class CtfKernelHandler implements Runnable {
 
@@ -41,13 +40,6 @@ class CtfKernelHandler implements Runnable {
 
     private CtfTmfEvent currentEvent;
 
-    /*
-     * We can keep handles to some Attribute Nodes so these don't need to be
-     * re-found (re-hashed Strings etc.) every new event
-     */
-    Vector<Integer> currentCPUNodes;
-    Vector<Integer> currentThreadNodes;
-
     /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
     private final HashMap<String, Integer> knownEventNames;
 
@@ -60,8 +52,6 @@ class CtfKernelHandler implements Runnable {
     CtfKernelHandler(BlockingQueue<CtfTmfEvent> eventsQueue) {
         assert (eventsQueue != null);
         this.inQueue = eventsQueue;
-        currentCPUNodes = new Vector<Integer>();
-        currentThreadNodes = new Vector<Integer>();
 
         knownEventNames = fillEventNames();
     }
@@ -112,34 +102,28 @@ class CtfKernelHandler implements Runnable {
     }
 
     private void processEvent(CtfTmfEvent event) {
-        currentEvent = event;
-        ITmfEventField content = event.getContent();
-        String eventName = event.getEventName();
-
-        long ts = event.getTimestamp().getValue();
         int quark;
         ITmfStateValue value;
-        Integer eventCpu = event.getCPU();
-        Integer currentCPUNode, currentThreadNode, tidNode;
-
-        /* Adjust the current nodes Vectors if we see a new CPU in an event */
-        if (eventCpu >= currentCPUNodes.size()) {
-            /* We need to add this node to the vector */
-            for (Integer i = currentCPUNodes.size(); i < eventCpu + 1; i++) {
-                quark = ss.getQuarkRelativeAndAdd(cpusNode, i.toString());
-                currentCPUNodes.add(quark);
-
-                quark = ss.getQuarkRelativeAndAdd(threadsNode, Attributes.UNKNOWN);
-                currentThreadNodes.add(quark);
-            }
-        }
 
-        currentCPUNode = currentCPUNodes.get(eventCpu);
-        currentThreadNode = currentThreadNodes.get(eventCpu);
-        assert (currentCPUNode != null);
-        assert (currentThreadNode != null);
+        currentEvent = event;
+
+        final ITmfEventField content = event.getContent();
+        final String eventName = event.getEventName();
+        final long ts = event.getTimestamp().getValue();
 
         try {
+            /* Shortcut for the "current CPU" attribute node */
+            final Integer currentCPUNode = ss.getQuarkRelativeAndAdd(cpusNode, String.valueOf(event.getCPU()));
+
+            /*
+             * Shortcut for the "current thread" attribute node. It requires
+             * querying the current CPU's current thread.
+             */
+            quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
+            value = ss.queryOngoingState(quark);
+            int thread = value.unboxInt();
+            final Integer currentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, String.valueOf(thread));
+
             /*
              * Feed event to the history system if it's known to cause a state
              * transition.
@@ -158,6 +142,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE);
                 ss.modifyAttribute(ts, value, quark);
+
+                /* Put the CPU's status back to user mode */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -176,11 +165,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
                 ss.modifyAttribute(ts, value, quark);
-\r
-                /* Change the status of the CPU to interrupted */\r
-                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);\r
-                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_INTERRUPTED);\r
-                ss.modifyAttribute(ts, value, quark);\r
+
+                /* Change the status of the CPU to interrupted */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IRQ);
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -196,9 +185,9 @@ class CtfKernelHandler implements Runnable {
 
                 /* Set the previous process back to running */
                 setProcessToRunning(ts, currentThreadNode);
-\r
-                /* Set the CPU status back to "busy" or "idle" */\r
-                cpuExitInterrupt(ts, currentCPUNode);\r
+
+                /* Set the CPU status back to running or "idle" */
+                cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
             }
                 break;
 
@@ -217,11 +206,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
                 ss.modifyAttribute(ts, value, quark);
-\r
-                /* Change the status of the CPU to interrupted */\r
-                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);\r
-                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_INTERRUPTED);\r
-                ss.modifyAttribute(ts, value, quark);\r
+
+                /* Change the status of the CPU to interrupted */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_SOFTIRQ);
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -237,9 +226,9 @@ class CtfKernelHandler implements Runnable {
 
                 /* Set the previous process back to running */
                 setProcessToRunning(ts, currentThreadNode);
-\r
-                /* Set the CPU status back to "busy" or "idle" */\r
-                cpuExitInterrupt(ts, currentCPUNode);\r
+
+                /* Set the CPU status back to "busy" or "idle" */
+                cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
             }
                 break;
 
@@ -264,26 +253,16 @@ class CtfKernelHandler implements Runnable {
             {
                 Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue();
                 //Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
-
                 String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue();
                 Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue();
 
-                /* Update the currentThreadNodes pointer */
+                Integer formerThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString());
                 Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, nextTid.toString());
-                currentThreadNodes.set(eventCpu, newCurrentThreadNode);
 
-                /*
-                 * Set the status of the process that got scheduled out, but
-                 * only in the case where that process is currently active.
-                 */
-                Integer formerThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString());
-                quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.EXEC_NAME);
-                value = ss.queryOngoingState(quark);
-                if (!value.isNull()) {
-                    quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
-                    value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
-                    ss.modifyAttribute(ts, value, quark);
-                }
+                /* Set the status of the process that got scheduled out. */
+                quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
+                ss.modifyAttribute(ts, value, quark);
 
                 /* Set the status of the new scheduled process */
                 setProcessToRunning(ts, newCurrentThreadNode);
@@ -312,15 +291,21 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
                 value = TmfStateValue.newValueInt(nextTid);
                 ss.modifyAttribute(ts, value, quark);
-\r
-                /* Set the status of the CPU itself */\r
-                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);\r
-                if (nextTid > 0) {\r
-                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_BUSY);\r
-                } else {\r
-                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);\r
-                }\r
-                ss.modifyAttribute(ts, value, quark);\r
+
+                /* Set the status of the CPU itself */
+                if (nextTid > 0) {
+                    /* Check if the entering process is in kernel or user mode */
+                    quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
+                    if (ss.queryOngoingState(quark).isNull()) {
+                        value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+                    } else {
+                        value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+                    }
+                } else {
+                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
+                }
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -328,50 +313,52 @@ class CtfKernelHandler implements Runnable {
             /* Fields: string parent_comm, int32 parent_tid,
              *         string child_comm, int32 child_tid */
             {
-                // String parentProcessName = (String)
-                // event.getFieldValue("parent_comm");
-                String childProcessName;
-                childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue();
+                // String parentProcessName = (String) event.getFieldValue("parent_comm");
+                String childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue();
                 // assert ( parentProcessName.equals(childProcessName) );
 
                 Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue();
                 Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue();
 
-                tidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString());
+                Integer parentTidNode = ss.getQuarkRelativeAndAdd(threadsNode, parentTid.toString());
+                Integer childTidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString());
 
                 /* Assign the PPID to the new process */
-                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.PPID);
+                quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID);
                 value = TmfStateValue.newValueInt(parentTid);
                 ss.modifyAttribute(ts, value, quark);
 
                 /* Set the new process' exec_name */
-                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.EXEC_NAME);
+                quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME);
                 value = TmfStateValue.newValueString(childProcessName);
                 ss.modifyAttribute(ts, value, quark);
 
                 /* Set the new process' status */
-                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.STATUS);
+                quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
                 ss.modifyAttribute(ts, value, quark);
 
-                /* Set the process' syscall state */
-                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.SYSTEM_CALL);
-                value = TmfStateValue.nullValue();
+                /* Set the process' syscall name, to be the same as the parent's */
+                quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL);
+                value = ss.queryOngoingState(quark);
+                quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
                 ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
             case 9: // "sched_process_exit":
             /* Fields: string comm, int32 tid, int32 prio */
+                break;
+
+            case 10: // "sched_process_free":
+            /* Fields: string comm, int32 tid, int32 prio */
+            /*
+             * A sched_process_free will always happen after the sched_switch
+             * that will remove the process from the cpu for the last time. So
+             * this is when we should delete everything wrt to the process.
+             */
             {
-                String processName = (String) content.getField(LttngStrings.COMM).getValue();
                 Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
-
-                /* Update the process' name, if we don't have it */
-                quark = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString(), Attributes.EXEC_NAME);
-                value = TmfStateValue.newValueString(processName);
-                ss.updateOngoingState(value, quark);
-
                 /*
                  * Remove the process and all its sub-attributes from the
                  * current state
@@ -381,19 +368,50 @@ class CtfKernelHandler implements Runnable {
             }
                 break;
 
-            case 10: // "sched_process_free":
-            /* Fields: string comm, int32 tid, int32 prio */
-                break;
+            case 11: // "lttng_statedump_process_state":
+            /* Fields:
+             * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
+             * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
+            {
+                Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
+                int ppid = ((Long) content.getField(LttngStrings.PPID).getValue()).intValue();
+                int status = ((Long) content.getField(LttngStrings.STATUS).getValue()).intValue();
+                String name = (String) content.getField(LttngStrings.NAME).getValue();
+                /*
+                 * "mode" could be interesting too, but it doesn't seem to be
+                 * populated with anything relevant for now.
+                 */
 
-            // FIXME In CTF it's as "syscall_exec". Will have to be adapted.
-            // case LTT_EVENT_EXEC:
-            // filename = new String((byte[]) event.getField(0));
-            //
-            // /* Change the Exec_name of the process */
-            // quark = ss.getQuarkRelativePath(true, currentThreadNode,
-            // "Exec_name");
-            // ss.modifyAttribute(ts, filename, quark);
-            // break;
+                int curThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString());
+
+                /* Set the process' name */
+                quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME);
+                if (ss.queryOngoingState(quark).isNull()) {
+                    /* If the value didn't exist previously, set it */
+                    value = TmfStateValue.newValueString(name);
+                    ss.modifyAttribute(ts, value, quark);
+                }
+
+                /* Set the process' PPID */
+                quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID);
+                if (ss.queryOngoingState(quark).isNull()) {
+                    value = TmfStateValue.newValueInt(ppid);
+                    ss.modifyAttribute(ts, value, quark);
+                }
+
+                /* Set the process' status */
+                quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.STATUS);
+                if (ss.queryOngoingState(quark).isNull()) {
+                    /*"5" here means "LTTNG_WAIT" in the LTTng kernel tracer */
+                    if (status == 5) {
+                        value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
+                    } else {
+                        value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_UNKNOWN);
+                    }
+                    ss.modifyAttribute(ts, value, quark);
+                }
+            }
+                break;
 
             default:
             /* Other event types not covered by the main switch */
@@ -414,6 +432,11 @@ class CtfKernelHandler implements Runnable {
                     quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                     value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL);
                     ss.modifyAttribute(ts, value, quark);
+
+                    /* Put the CPU in system call (kernel) mode */
+                    quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+                    value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+                    ss.modifyAttribute(ts, value, quark);
                 }
             }
                 break;
@@ -487,6 +510,7 @@ class CtfKernelHandler implements Runnable {
         map.put(LttngStrings.SCHED_PROCESS_FORK, 8);
         map.put(LttngStrings.SCHED_PROCESS_EXIT, 9);
         map.put(LttngStrings.SCHED_PROCESS_FREE, 10);
+        map.put(LttngStrings.STATEDUMP_PROCESS_STATE, 11);
 
         return map;
     }
@@ -519,29 +543,36 @@ class CtfKernelHandler implements Runnable {
         quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
         ss.modifyAttribute(ts, value, quark);
     }
-\r
-    /**\r
-     * Similar logic as above, but to set the CPU's status when it's coming out\r
-     * of an interruption.\r
-     * @throws AttributeNotFoundException \r
-     * @throws StateValueTypeException \r
-     * @throws TimeRangeException \r
-     */\r
-    private void cpuExitInterrupt(long ts, int currentCpuNode)\r
-            throws StateValueTypeException, AttributeNotFoundException,\r
-            TimeRangeException {\r
-        int quark;\r
-        ITmfStateValue value;\r
-\r
-        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);\r
-        if (ss.queryOngoingState(quark).unboxInt() > 0) {\r
-            /* There was a process on the CPU */\r
-            value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_BUSY);\r
-        } else {\r
-            /* There was no real process scheduled, CPU was idle */\r
-            value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);\r
-        }\r
-        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);\r
-        ss.modifyAttribute(ts, value, quark);\r
-    }\r
+
+    /**
+     * Similar logic as above, but to set the CPU's status when it's coming out
+     * of an interruption.
+     * @throws AttributeNotFoundException
+     * @throws StateValueTypeException
+     * @throws TimeRangeException
+     */
+    private void cpuExitInterrupt(long ts, int currentCpuNode, int currentThreadNode)
+            throws StateValueTypeException, AttributeNotFoundException,
+            TimeRangeException {
+        int quark;
+        ITmfStateValue value;
+
+        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);
+        if (ss.queryOngoingState(quark).unboxInt() > 0) {
+            /* There was a process on the CPU */
+            quark = ss.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL);
+            if (ss.queryOngoingState(quark).isNull()) {
+                /* That process was in user mode */
+                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+            } else {
+                /* That process was in a system call */
+                value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+            }
+        } else {
+            /* There was no real process scheduled, CPU was idle */
+            value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
+        }
+        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);
+        ss.modifyAttribute(ts, value, quark);
+    }
 }
This page took 0.029453 seconds and 5 git commands to generate.