lttng: Track the CPU statuses in the event handler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.core / src / org / eclipse / linuxtools / internal / lttng2 / kernel / core / stateprovider / CtfKernelHandler.java
index e6305b638db8aa10b780f93c3ffa1cb146583e5b..f3f5d4ef6f6346801a37f84831f90ed7e7303bc9 100644 (file)
@@ -96,6 +96,9 @@ class CtfKernelHandler implements Runnable {
 
     private void closeStateSystem() {
         /* Close the History system, if there is one */
+        if (currentEvent == null) {
+            return;
+        }
         try {
             ss.closeHistory(currentEvent.getTimestamp().getValue());
         } catch (TimeRangeException e) {
@@ -149,6 +152,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
                 value = TmfStateValue.nullValue();
                 ss.modifyAttribute(ts, value, quark);
+
+                /* Put the process' status back to user mode */
+                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(Attributes.STATUS_RUN_USERMODE);
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -167,6 +175,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(Attributes.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(Attributes.CPU_STATUS_INTERRUPTED);\r
+                ss.modifyAttribute(ts, value, quark);\r
             }
                 break;
 
@@ -181,9 +194,10 @@ class CtfKernelHandler implements Runnable {
                 ss.modifyAttribute(ts, value, quark);
 
                 /* Set the previous process back to running */
-                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
-                value = TmfStateValue.newValueInt(Attributes.STATUS_RUN);
-                ss.modifyAttribute(ts, value, quark);
+                setProcessToRunning(ts, currentThreadNode);
+\r
+                /* Set the CPU status back to "busy" or "idle" */\r
+                cpuExitInterrupt(ts, currentCPUNode);\r
             }
                 break;
 
@@ -202,6 +216,11 @@ class CtfKernelHandler implements Runnable {
                 quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
                 value = TmfStateValue.newValueInt(Attributes.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(Attributes.CPU_STATUS_INTERRUPTED);\r
+                ss.modifyAttribute(ts, value, quark);\r
             }
                 break;
 
@@ -216,9 +235,10 @@ class CtfKernelHandler implements Runnable {
                 ss.modifyAttribute(ts, value, quark);
 
                 /* Set the previous process back to running */
-                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
-                value = TmfStateValue.newValueInt(Attributes.STATUS_RUN);
-                ss.modifyAttribute(ts, value, quark);
+                setProcessToRunning(ts, currentThreadNode);
+\r
+                /* Set the CPU status back to "busy" or "idle" */\r
+                cpuExitInterrupt(ts, currentCPUNode);\r
             }
                 break;
 
@@ -230,7 +250,7 @@ class CtfKernelHandler implements Runnable {
                 /* Mark this SoftIRQ as *raised* in the resource tree.
                  * State value = -2 */
                 quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
-                value = TmfStateValue.newValueInt(-2);
+                value = TmfStateValue.newValueInt(Attributes.SOFT_IRQ_RAISED);
                 ss.modifyAttribute(ts, value, quark);
             }
                 break;
@@ -241,37 +261,65 @@ class CtfKernelHandler implements Runnable {
              *         string next_comm, int32 next_tid, int32 next_prio
              */
             {
-
                 Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue();
-                Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
+                //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 newCurrentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, nextTid.toString());
-                initThreadNode(newCurrentThreadNode);
                 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(Attributes.STATUS_WAIT);
+                    ss.modifyAttribute(ts, value, quark);
+                }
+
                 /* Set the status of the new scheduled process */
-                quark = ss.getQuarkRelative(newCurrentThreadNode, Attributes.STATUS);
-                value = TmfStateValue.newValueInt(Attributes.STATUS_RUN);
-                ss.modifyAttribute(ts, value, quark);
+                setProcessToRunning(ts, newCurrentThreadNode);
 
                 /* Set the exec name of the new process */
-                quark = ss.getQuarkRelative(newCurrentThreadNode, Attributes.EXEC_NAME);
+                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME);
                 value = TmfStateValue.newValueString(nextProcessName);
                 ss.modifyAttribute(ts, value, quark);
 
-                /* Set the status of the process that got scheduled out */
-                quark = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString(), Attributes.STATUS);
-                value = TmfStateValue.newValueInt(prevState.intValue());
-                ss.modifyAttribute(ts, value, quark);
+                /*
+                 * Check if we need to set the syscall state and the PPID of
+                 * the new process (in case we haven't seen this process before)
+                 */
+                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
+                if (quark == ss.getNbAttributes()) { /* Did we just add this attribute? */
+                    value = TmfStateValue.nullValue();
+                    ss.modifyAttribute(ts, value, quark);
+                }
+                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
+                if (quark == ss.getNbAttributes()) {
+                    value = TmfStateValue.nullValue();
+                    ss.modifyAttribute(ts, value, quark);
+                }
 
                 /* Set the current scheduled process on the relevant CPU */
                 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(Attributes.CPU_STATUS_BUSY);\r
+                } else {\r
+                    value = TmfStateValue.newValueInt(Attributes.CPU_STATUS_IDLE);\r
+                }\r
+                ss.modifyAttribute(ts, value, quark);\r
             }
                 break;
 
@@ -289,20 +337,26 @@ class CtfKernelHandler implements Runnable {
                 Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue();
 
                 tidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString());
-                initThreadNode(tidNode);
 
-                /*
-                 * Add the new process with its known TID, PPID, and initial
-                 * Exec_name
-                 */
-                quark = ss.getQuarkRelative(tidNode, Attributes.PPID);
+                /* Assign the PPID to the new process */
+                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.PPID);
                 value = TmfStateValue.newValueInt(parentTid);
                 ss.modifyAttribute(ts, value, quark);
 
                 /* Set the new process' exec_name */
-                quark = ss.getQuarkRelative(tidNode, Attributes.EXEC_NAME);
+                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.EXEC_NAME);
                 value = TmfStateValue.newValueString(childProcessName);
                 ss.modifyAttribute(ts, value, quark);
+
+                /* Set the new process' status */
+                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.STATUS);
+                value = TmfStateValue.newValueInt(Attributes.STATUS_WAIT);
+                ss.modifyAttribute(ts, value, quark);
+
+                /* Set the process' syscall state */
+                quark = ss.getQuarkRelativeAndAdd(tidNode, Attributes.SYSTEM_CALL);
+                value = TmfStateValue.nullValue();
+                ss.modifyAttribute(ts, value, quark);
             }
                 break;
 
@@ -354,6 +408,11 @@ class CtfKernelHandler implements Runnable {
                     quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
                     value = TmfStateValue.newValueString(eventName);
                     ss.modifyAttribute(ts, value, quark);
+
+                    /* Put the process in system call mode */
+                    quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+                    value = TmfStateValue.newValueInt(Attributes.STATUS_RUN_SYSCALL);
+                    ss.modifyAttribute(ts, value, quark);
                 }
             }
                 break;
@@ -403,16 +462,6 @@ class CtfKernelHandler implements Runnable {
         }
     }
 
-    /**
-     * Ensure we always have some sub-attributes available for every "TID" node.
-     */
-    private void initThreadNode(int currentThreadNode) {
-        ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.PPID);
-        ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.EXEC_NAME);
-        ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
-        ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
-    }
-
     private void setupCommonLocations() {
         cpusNode = ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
         threadsNode = ss.getQuarkAbsoluteAndAdd(Attributes.THREADS);
@@ -445,4 +494,53 @@ class CtfKernelHandler implements Runnable {
         Integer ret = knownEventNames.get(eventName);
         return (ret != null) ? ret : -1;
     }
+
+    /**
+     * When we want to set a process back to a "running" state, first check
+     * its current System_call attribute. If there is a system call active, we
+     * put the process back in the syscall state. If not, we put it back in
+     * user mode state.
+     */
+    private void setProcessToRunning(long ts, int currentThreadNode)
+            throws AttributeNotFoundException, TimeRangeException,
+            StateValueTypeException {
+        int quark;
+        ITmfStateValue value;
+
+        quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+        if (ss.queryOngoingState(quark).isNull()) {
+            /* We were in user mode before the interruption */
+            value = TmfStateValue.newValueInt(Attributes.STATUS_RUN_USERMODE);
+        } else {
+            /* We were previously in kernel mode */
+            value = TmfStateValue.newValueInt(Attributes.STATUS_RUN_SYSCALL);
+        }
+        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(Attributes.CPU_STATUS_BUSY);\r
+        } else {\r
+            /* There was no real process scheduled, CPU was idle */\r
+            value = TmfStateValue.newValueInt(Attributes.CPU_STATUS_IDLE);\r
+        }\r
+        quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);\r
+        ss.modifyAttribute(ts, value, quark);\r
+    }\r
 }
This page took 0.026325 seconds and 5 git commands to generate.