Merge pull request #27 from sinkap/issue_23_v2

sched: SchedMultiAssert: Add missing pids argument
diff --git a/bart/sched/SchedAssert.py b/bart/sched/SchedAssert.py
index 906eead..b3cadfc 100755
--- a/bart/sched/SchedAssert.py
+++ b/bart/sched/SchedAssert.py
@@ -445,7 +445,19 @@
         return operator(run_time, expected_value)
 
     def getPeriod(self, window=None, align="start"):
-        """Return average period of the task in (ms)
+        """Return the period of the task in (ms)
+
+        Let's say a task started execution at the following times:
+
+            .. math::
+
+                T_1, T_2, ...T_n
+
+        The period is defined as:
+
+            .. math::
+
+                Median((T_2 - T_1), (T_4 - T_3), ....(T_n - T_{n-1}))
 
         :param window: A (start, end) tuple to limit the scope of the
             residency calculation.
@@ -460,12 +472,12 @@
         """
 
         agg = self._aggregator(sconf.period)
-        period = agg.aggregate(level="all", window=window)[0]
-        total, length = map(sum, zip(*period))
-        if length == 0:
+        deltas = agg.aggregate(level="all", window=window)[0]
+
+        if not len(deltas):
             return float("NaN")
         else:
-            return (total * 1000) / length
+            return np.median(deltas) * 1000
 
     def assertPeriod(
             self,
diff --git a/docs/notebooks/sched/SchedDeadline.ipynb b/docs/notebooks/sched/SchedDeadline.ipynb
index 0172bb2..dac2890 100644
--- a/docs/notebooks/sched/SchedDeadline.ipynb
+++ b/docs/notebooks/sched/SchedDeadline.ipynb
@@ -1,623 +1,4 @@
 {
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Setup"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "from trappy.stats.Topology import Topology\n",
-    "from bart.sched.SchedMultiAssert import SchedMultiAssert\n",
-    "from bart.sched.SchedAssert import SchedAssert\n",
-    "import trappy\n",
-    "import os\n",
-    "import operator\n",
-    "import json\n",
-    "\n",
-    "#Define a CPU Topology (for multi-cluster systems)\n",
-    "BIG = [1, 2]\n",
-    "LITTLE = [0, 3, 4, 5]\n",
-    "CLUSTERS = [BIG, LITTLE]\n",
-    "topology = Topology(clusters=CLUSTERS)\n",
-    "\n",
-    "BASE_PATH = \"/Users/kapileshwarsingh/AnalysisRawData/LPC/sched_deadline/\"\n",
-    "\n",
-    "THRESHOLD = 10.0\n",
-    "def between_threshold(a, b):\n",
-    "    return abs(((a - b) * 100.0) / b) < THRESHOLD"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Periodic Yield"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The thread periodic_yeild is woken up at 30ms intervals where it calls sched_yield and relinquishes its time-slice.\n",
-    "The expectation is that the task will have a duty cycle < 1% and a period of 30ms.\n",
-    "\n",
-    "There are two threads, and the rank=1 conveys that the condition is true for one of the threads with the name \"periodic_yeild\"\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "PASS: Period\n",
-      "{\n",
-      "   \"1844\": {\n",
-      "      \"period\": 1.0085000000401578, \n",
-      "      \"task_name\": \"periodic_yield\"\n",
-      "   }, \n",
-      "   \"1845\": {\n",
-      "      \"period\": 29.822017857142669, \n",
-      "      \"task_name\": \"periodic_yield\"\n",
-      "   }\n",
-      "}\n",
-      "\n",
-      "PASS: DutyCycle\n",
-      "{\n",
-      "   \"1844\": {\n",
-      "      \"task_name\": \"periodic_yield\", \n",
-      "      \"dutycycle\": 0.074749999998857675\n",
-      "   }, \n",
-      "   \"1845\": {\n",
-      "      \"task_name\": \"periodic_yield\", \n",
-      "      \"dutycycle\": 0.03862499999343072\n",
-      "   }\n",
-      "}\n"
-     ]
-    }
-   ],
-   "source": [
-    "TRACE_FILE = os.path.join(BASE_PATH, \"yield\")\n",
-    "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
-    "\n",
-    "# Assert Period\n",
-    "s = SchedMultiAssert(run, topology, execnames=\"periodic_yield\")\n",
-    "if s.assertPeriod(30, between_threshold, rank=1):\n",
-    "    print \"PASS: Period\"\n",
-    "    print json.dumps(s.getPeriod(), indent=3)\n",
-    "\n",
-    "print \"\"\n",
-    "    \n",
-    "# Assert DutyCycle    \n",
-    "if s.assertDutyCycle(1, operator.lt, window=(0,4), rank=2):\n",
-    "    print \"PASS: DutyCycle\"\n",
-    "    print json.dumps(s.getDutyCycle(window=(0,4)), indent=3)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# CPU Hog"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The reservation of a CPU hogging task is set to 10ms for every 100ms. The assertion ensures a duty cycle of 10%"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<style>\n",
-       "/*\n",
-       "\n",
-       " *    Copyright 2015-2015 ARM Limited\n",
-       "\n",
-       " *\n",
-       "\n",
-       " * Licensed under the Apache License, Version 2.0 (the \"License\");\n",
-       "\n",
-       " * you may not use this file except in compliance with the License.\n",
-       "\n",
-       " * You may obtain a copy of the License at\n",
-       "\n",
-       " *\n",
-       "\n",
-       " *     http://www.apache.org/licenses/LICENSE-2.0\n",
-       "\n",
-       " *\n",
-       "\n",
-       " * Unless required by applicable law or agreed to in writing, software\n",
-       "\n",
-       " * distributed under the License is distributed on an \"AS IS\" BASIS,\n",
-       "\n",
-       " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
-       "\n",
-       " * See the License for the specific language governing permissions and\n",
-       "\n",
-       " * limitations under the License.\n",
-       "\n",
-       " */\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip {\n",
-       "\n",
-       "  line-height: 1;\n",
-       "\n",
-       "  padding: 12px;\n",
-       "\n",
-       "  background: rgba(0, 0, 0, 0.6);\n",
-       "\n",
-       "  color: #fff;\n",
-       "\n",
-       "  border-radius: 2px;\n",
-       "\n",
-       "  position: absolute !important;\n",
-       "\n",
-       "  z-index: 99999;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip:after {\n",
-       "\n",
-       "  box-sizing: border-box;\n",
-       "\n",
-       "  pointer-events: none;\n",
-       "\n",
-       "  display: inline;\n",
-       "\n",
-       "  font-size: 10px;\n",
-       "\n",
-       "  width: 100%;\n",
-       "\n",
-       "  line-height: 1;\n",
-       "\n",
-       "  color: rgba(0, 0, 0, 0.6);\n",
-       "\n",
-       "  content: \"\\25BC\";\n",
-       "\n",
-       "  position: absolute !important;\n",
-       "\n",
-       "  z-index: 99999;\n",
-       "\n",
-       "  text-align: center;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip.n:after {\n",
-       "\n",
-       "  margin: -1px 0 0 0;\n",
-       "\n",
-       "  top: 100%;\n",
-       "\n",
-       "  left: 0;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".chart {\n",
-       "\n",
-       "  shape-rendering: crispEdges;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".mini text {\n",
-       "\n",
-       "  font: 9px sans-serif;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".main text {\n",
-       "\n",
-       "  font: 12px sans-serif;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".axis line, .axis path {\n",
-       "\n",
-       "  stroke: black;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".miniItem {\n",
-       "\n",
-       "  stroke-width: 8;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".brush .extent {\n",
-       "\n",
-       "\n",
-       "\n",
-       "  stroke: #000;\n",
-       "\n",
-       "  fill-opacity: .125;\n",
-       "\n",
-       "  shape-rendering: crispEdges;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "</style>\n",
-       "<div id=\"fig_41c7653cedde4765ae1f166e75c4fb08\" class=\"eventplot\">\n",
-       "        <script>\n",
-       "            var req = require.config( {\n",
-       "\n",
-       "                paths: {\n",
-       "\n",
-       "                    \"EventPlot\": \"https://rawgit.com/sinkap/7f89de3e558856b81f10/raw/46144f8f8c5da670c54f826f0c634762107afc66/EventPlot\",\n",
-       "                    \"d3-tip\": \"http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3\",\n",
-       "                    \"d3\": \"http://d3js.org/d3.v3.min\"\n",
-       "                },\n",
-       "                shim: {\n",
-       "                    \"d3-tip\": [\"d3\"],\n",
-       "                    \"EventPlot\": {\n",
-       "\n",
-       "                        \"deps\": [\"d3-tip\", \"d3\" ],\n",
-       "                        \"exports\":  \"EventPlot\"\n",
-       "                    }\n",
-       "                }\n",
-       "            });\n",
-       "            req([\"require\", \"EventPlot\"], function() {\n",
-       "               EventPlot.generate('fig_41c7653cedde4765ae1f166e75c4fb08', 'https://rawgit.com/sinkap/e9bc2394cf322f4dad0d/raw/014fae226c847a467fba541fbc390e18acea127b/fig_41c7653cedde4765ae1f166e75c4fb08.json');\n",
-       "            });\n",
-       "        </script>\n",
-       "        </div>"
-      ],
-      "text/plain": [
-       "<IPython.core.display.HTML object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "PASS: DutyCycle\n",
-      "{\n",
-      "   \"1852\": {\n",
-      "      \"task_name\": \"cpuhog\", \n",
-      "      \"dutycycle\": 10.050119999991693\n",
-      "   }\n",
-      "}\n"
-     ]
-    }
-   ],
-   "source": [
-    "TRACE_FILE = os.path.join(BASE_PATH, \"cpuhog\")\n",
-    "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
-    "s = SchedMultiAssert(run, topology, execnames=\"cpuhog\")\n",
-    "s.plot().view()\n",
-    "\n",
-    "# Assert DutyCycle\n",
-    "if s.assertDutyCycle(10, between_threshold, window=(0, 5), rank=1):\n",
-    "    print \"PASS: DutyCycle\"\n",
-    "    print json.dumps(s.getDutyCycle(window=(0, 5)), indent=3)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Changing Reservations"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "A CPU hogging task has reservations set in the increasing order starting from 10%  followed by a 2s period of normal execution"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<style>\n",
-       "/*\n",
-       "\n",
-       " *    Copyright 2015-2015 ARM Limited\n",
-       "\n",
-       " *\n",
-       "\n",
-       " * Licensed under the Apache License, Version 2.0 (the \"License\");\n",
-       "\n",
-       " * you may not use this file except in compliance with the License.\n",
-       "\n",
-       " * You may obtain a copy of the License at\n",
-       "\n",
-       " *\n",
-       "\n",
-       " *     http://www.apache.org/licenses/LICENSE-2.0\n",
-       "\n",
-       " *\n",
-       "\n",
-       " * Unless required by applicable law or agreed to in writing, software\n",
-       "\n",
-       " * distributed under the License is distributed on an \"AS IS\" BASIS,\n",
-       "\n",
-       " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
-       "\n",
-       " * See the License for the specific language governing permissions and\n",
-       "\n",
-       " * limitations under the License.\n",
-       "\n",
-       " */\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip {\n",
-       "\n",
-       "  line-height: 1;\n",
-       "\n",
-       "  padding: 12px;\n",
-       "\n",
-       "  background: rgba(0, 0, 0, 0.6);\n",
-       "\n",
-       "  color: #fff;\n",
-       "\n",
-       "  border-radius: 2px;\n",
-       "\n",
-       "  position: absolute !important;\n",
-       "\n",
-       "  z-index: 99999;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip:after {\n",
-       "\n",
-       "  box-sizing: border-box;\n",
-       "\n",
-       "  pointer-events: none;\n",
-       "\n",
-       "  display: inline;\n",
-       "\n",
-       "  font-size: 10px;\n",
-       "\n",
-       "  width: 100%;\n",
-       "\n",
-       "  line-height: 1;\n",
-       "\n",
-       "  color: rgba(0, 0, 0, 0.6);\n",
-       "\n",
-       "  content: \"\\25BC\";\n",
-       "\n",
-       "  position: absolute !important;\n",
-       "\n",
-       "  z-index: 99999;\n",
-       "\n",
-       "  text-align: center;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".d3-tip.n:after {\n",
-       "\n",
-       "  margin: -1px 0 0 0;\n",
-       "\n",
-       "  top: 100%;\n",
-       "\n",
-       "  left: 0;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".chart {\n",
-       "\n",
-       "  shape-rendering: crispEdges;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".mini text {\n",
-       "\n",
-       "  font: 9px sans-serif;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".main text {\n",
-       "\n",
-       "  font: 12px sans-serif;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".axis line, .axis path {\n",
-       "\n",
-       "  stroke: black;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".miniItem {\n",
-       "\n",
-       "  stroke-width: 8;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "\n",
-       "\n",
-       ".brush .extent {\n",
-       "\n",
-       "\n",
-       "\n",
-       "  stroke: #000;\n",
-       "\n",
-       "  fill-opacity: .125;\n",
-       "\n",
-       "  shape-rendering: crispEdges;\n",
-       "\n",
-       "}\n",
-       "\n",
-       "</style>\n",
-       "<div id=\"fig_421afa8cc8234df49030c900b680220b\" class=\"eventplot\">\n",
-       "        <script>\n",
-       "            var req = require.config( {\n",
-       "\n",
-       "                paths: {\n",
-       "\n",
-       "                    \"EventPlot\": \"https://rawgit.com/sinkap/7f89de3e558856b81f10/raw/46144f8f8c5da670c54f826f0c634762107afc66/EventPlot\",\n",
-       "                    \"d3-tip\": \"http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3\",\n",
-       "                    \"d3\": \"http://d3js.org/d3.v3.min\"\n",
-       "                },\n",
-       "                shim: {\n",
-       "                    \"d3-tip\": [\"d3\"],\n",
-       "                    \"EventPlot\": {\n",
-       "\n",
-       "                        \"deps\": [\"d3-tip\", \"d3\" ],\n",
-       "                        \"exports\":  \"EventPlot\"\n",
-       "                    }\n",
-       "                }\n",
-       "            });\n",
-       "            req([\"require\", \"EventPlot\"], function() {\n",
-       "               EventPlot.generate('fig_421afa8cc8234df49030c900b680220b', 'https://rawgit.com/sinkap/a207675f6483aa0b9342/raw/825717935112f36fe996b77093c0c71d3871fee4/fig_421afa8cc8234df49030c900b680220b.json');\n",
-       "            });\n",
-       "        </script>\n",
-       "        </div>"
-      ],
-      "text/plain": [
-       "<IPython.core.display.HTML object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "WINDOW -> [0.00, 2.00]\n",
-      "PASS: Expected=10 Actual=10.38 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [2.00, 4.00]\n",
-      "PASS: Expected=100 Actual=99.60 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [4.00, 6.00]\n",
-      "PASS: Expected=20 Actual=21.06 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [6.00, 8.00]\n",
-      "PASS: Expected=100 Actual=95.69 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [8.00, 10.00]\n",
-      "PASS: Expected=30 Actual=31.78 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [10.00, 12.00]\n",
-      "PASS: Expected=100 Actual=98.23 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [12.00, 14.00]\n",
-      "PASS: Expected=40 Actual=40.74 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [14.00, 16.00]\n",
-      "PASS: Expected=100 Actual=97.58 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [16.00, 18.00]\n",
-      "PASS: Expected=50 Actual=52.51 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [18.00, 20.00]\n",
-      "PASS: Expected=100 Actual=96.38 THRESHOLD=10.0\n",
-      "\n",
-      "WINDOW -> [20.00, 22.00]\n",
-      "PASS: Expected=60 Actual=60.71 THRESHOLD=10.0\n",
-      "\n"
-     ]
-    }
-   ],
-   "source": [
-    "TRACE_FILE = os.path.join(BASE_PATH, \"cancel_dl_timer\")\n",
-    "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
-    "s = SchedAssert(run, topology, execname=\"cpuhog\")\n",
-    "s.plot().view()\n",
-    "\n",
-    "NUM_PHASES = 10\n",
-    "PHASE_DURATION = 2\n",
-    "start = s.getStartTime()\n",
-    "DUTY_CYCLE_FACTOR = 10\n",
-    "\n",
-    "\n",
-    "for phase in range(NUM_PHASES + 1):\n",
-    "    window = (start + (phase * PHASE_DURATION),\n",
-    "              start + ((phase + 1) * PHASE_DURATION))\n",
-    "    \n",
-    "    if phase % 2 == 0:\n",
-    "        DUTY_CYCLE = (phase + 2) * DUTY_CYCLE_FACTOR / 2\n",
-    "    else:\n",
-    "        DUTY_CYCLE = 100\n",
-    "\n",
-    "\n",
-    "    print \"WINDOW -> [{:.2f}, {:.2f}]\".format(window[0],\n",
-    "                                            window[1])\n",
-    "    \n",
-    "    \n",
-    "    \n",
-    "    if s.assertDutyCycle(DUTY_CYCLE, between_threshold, window=window):\n",
-    "        print \"PASS: Expected={} Actual={:.2f} THRESHOLD={}\".format(DUTY_CYCLE,\n",
-    "                                                                s.getDutyCycle(window=window),\n",
-    "                                                                THRESHOLD)\n",
-    "    else:\n",
-    "        print \"FAIL: Expected={} Actual={:.2f} THRESHOLD={}\".format(DUTY_CYCLE,\n",
-    "                                                                s.getDutyCycle(window=window),\n",
-    "                                                                THRESHOLD)\n",
-    "    \n",
-    "    print \"\""
-   ]
-  }
- ],
  "metadata": {
   "kernelspec": {
    "display_name": "Python 2",
@@ -635,8 +16,633 @@
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython2",
    "version": "2.7.9"
-  }
+  },
+  "name": ""
  },
- "nbformat": 4,
- "nbformat_minor": 0
-}
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "heading",
+     "level": 1,
+     "metadata": {},
+     "source": [
+      "Setup"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from trappy.stats.Topology import Topology\n",
+      "from bart.sched.SchedMultiAssert import SchedMultiAssert\n",
+      "from bart.sched.SchedAssert import SchedAssert\n",
+      "import trappy\n",
+      "import os\n",
+      "import operator\n",
+      "import json\n",
+      "\n",
+      "#Define a CPU Topology (for multi-cluster systems)\n",
+      "BIG = [1, 2]\n",
+      "LITTLE = [0, 3, 4, 5]\n",
+      "CLUSTERS = [BIG, LITTLE]\n",
+      "topology = Topology(clusters=CLUSTERS)\n",
+      "\n",
+      "BASE_PATH = \"/Users/kapileshwarsingh/AnalysisRawData/LPC/sched_deadline/\"\n",
+      "\n",
+      "THRESHOLD = 10.0\n",
+      "def between_threshold(a, b):\n",
+      "    return abs(((a - b) * 100.0) / b) < THRESHOLD"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "heading",
+     "level": 1,
+     "metadata": {},
+     "source": [
+      "Periodic Yield"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The thread periodic_yeild is woken up at 30ms intervals where it calls sched_yield and relinquishes its time-slice.\n",
+      "The expectation is that the task will have a duty cycle < 1% and a period of 30ms.\n",
+      "\n",
+      "There are two threads, and the rank=1 conveys that the condition is true for one of the threads with the name \"periodic_yeild\"\n"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "TRACE_FILE = os.path.join(BASE_PATH, \"yield\")\n",
+      "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
+      "\n",
+      "# Assert Period\n",
+      "s = SchedMultiAssert(run, topology, execnames=\"periodic_yield\")\n",
+      "if s.assertPeriod(30, between_threshold, rank=1):\n",
+      "    print \"PASS: Period\"\n",
+      "    print json.dumps(s.getPeriod(), indent=3)\n",
+      "\n",
+      "print \"\"\n",
+      "    \n",
+      "# Assert DutyCycle    \n",
+      "if s.assertDutyCycle(1, operator.lt, window=(0,4), rank=2):\n",
+      "    print \"PASS: DutyCycle\"\n",
+      "    print json.dumps(s.getDutyCycle(window=(0,4)), indent=3)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "PASS: Period\n",
+        "{\n",
+        "   \"1844\": {\n",
+        "      \"period\": 1.0085000000401578, \n",
+        "      \"task_name\": \"periodic_yield\"\n",
+        "   }, \n",
+        "   \"1845\": {\n",
+        "      \"period\": 29.822017857142669, \n",
+        "      \"task_name\": \"periodic_yield\"\n",
+        "   }\n",
+        "}\n",
+        "\n",
+        "PASS: DutyCycle\n",
+        "{\n",
+        "   \"1844\": {\n",
+        "      \"task_name\": \"periodic_yield\", \n",
+        "      \"dutycycle\": 0.074749999998857675\n",
+        "   }, \n",
+        "   \"1845\": {\n",
+        "      \"task_name\": \"periodic_yield\", \n",
+        "      \"dutycycle\": 0.03862499999343072\n",
+        "   }\n",
+        "}\n"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "heading",
+     "level": 1,
+     "metadata": {},
+     "source": [
+      "CPU Hog"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The reservation of a CPU hogging task is set to 10ms for every 100ms. The assertion ensures a duty cycle of 10%"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "TRACE_FILE = os.path.join(BASE_PATH, \"cpuhog\")\n",
+      "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
+      "s = SchedMultiAssert(run, topology, execnames=\"cpuhog\")\n",
+      "s.plot().view()\n",
+      "\n",
+      "# Assert DutyCycle\n",
+      "if s.assertDutyCycle(10, between_threshold, window=(0, 5), rank=1):\n",
+      "    print \"PASS: DutyCycle\"\n",
+      "    print json.dumps(s.getDutyCycle(window=(0, 5)), indent=3)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<style>\n",
+        "/*\n",
+        "\n",
+        " *    Copyright 2015-2015 ARM Limited\n",
+        "\n",
+        " *\n",
+        "\n",
+        " * Licensed under the Apache License, Version 2.0 (the \"License\");\n",
+        "\n",
+        " * you may not use this file except in compliance with the License.\n",
+        "\n",
+        " * You may obtain a copy of the License at\n",
+        "\n",
+        " *\n",
+        "\n",
+        " *     http://www.apache.org/licenses/LICENSE-2.0\n",
+        "\n",
+        " *\n",
+        "\n",
+        " * Unless required by applicable law or agreed to in writing, software\n",
+        "\n",
+        " * distributed under the License is distributed on an \"AS IS\" BASIS,\n",
+        "\n",
+        " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
+        "\n",
+        " * See the License for the specific language governing permissions and\n",
+        "\n",
+        " * limitations under the License.\n",
+        "\n",
+        " */\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip {\n",
+        "\n",
+        "  line-height: 1;\n",
+        "\n",
+        "  padding: 12px;\n",
+        "\n",
+        "  background: rgba(0, 0, 0, 0.6);\n",
+        "\n",
+        "  color: #fff;\n",
+        "\n",
+        "  border-radius: 2px;\n",
+        "\n",
+        "  position: absolute !important;\n",
+        "\n",
+        "  z-index: 99999;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip:after {\n",
+        "\n",
+        "  box-sizing: border-box;\n",
+        "\n",
+        "  pointer-events: none;\n",
+        "\n",
+        "  display: inline;\n",
+        "\n",
+        "  font-size: 10px;\n",
+        "\n",
+        "  width: 100%;\n",
+        "\n",
+        "  line-height: 1;\n",
+        "\n",
+        "  color: rgba(0, 0, 0, 0.6);\n",
+        "\n",
+        "  content: \"\\25BC\";\n",
+        "\n",
+        "  position: absolute !important;\n",
+        "\n",
+        "  z-index: 99999;\n",
+        "\n",
+        "  text-align: center;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip.n:after {\n",
+        "\n",
+        "  margin: -1px 0 0 0;\n",
+        "\n",
+        "  top: 100%;\n",
+        "\n",
+        "  left: 0;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".chart {\n",
+        "\n",
+        "  shape-rendering: crispEdges;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".mini text {\n",
+        "\n",
+        "  font: 9px sans-serif;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".main text {\n",
+        "\n",
+        "  font: 12px sans-serif;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".axis line, .axis path {\n",
+        "\n",
+        "  stroke: black;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".miniItem {\n",
+        "\n",
+        "  stroke-width: 8;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".brush .extent {\n",
+        "\n",
+        "\n",
+        "\n",
+        "  stroke: #000;\n",
+        "\n",
+        "  fill-opacity: .125;\n",
+        "\n",
+        "  shape-rendering: crispEdges;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "</style>\n",
+        "<div id=\"fig_41c7653cedde4765ae1f166e75c4fb08\" class=\"eventplot\">\n",
+        "        <script>\n",
+        "            var req = require.config( {\n",
+        "\n",
+        "                paths: {\n",
+        "\n",
+        "                    \"EventPlot\": \"https://rawgit.com/sinkap/7f89de3e558856b81f10/raw/46144f8f8c5da670c54f826f0c634762107afc66/EventPlot\",\n",
+        "                    \"d3-tip\": \"http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3\",\n",
+        "                    \"d3\": \"http://d3js.org/d3.v3.min\"\n",
+        "                },\n",
+        "                shim: {\n",
+        "                    \"d3-tip\": [\"d3\"],\n",
+        "                    \"EventPlot\": {\n",
+        "\n",
+        "                        \"deps\": [\"d3-tip\", \"d3\" ],\n",
+        "                        \"exports\":  \"EventPlot\"\n",
+        "                    }\n",
+        "                }\n",
+        "            });\n",
+        "            req([\"require\", \"EventPlot\"], function() {\n",
+        "               EventPlot.generate('fig_41c7653cedde4765ae1f166e75c4fb08', 'https://rawgit.com/sinkap/e9bc2394cf322f4dad0d/raw/014fae226c847a467fba541fbc390e18acea127b/fig_41c7653cedde4765ae1f166e75c4fb08.json');\n",
+        "            });\n",
+        "        </script>\n",
+        "        </div>"
+       ],
+       "metadata": {},
+       "output_type": "display_data",
+       "text": [
+        "<IPython.core.display.HTML object>"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "PASS: DutyCycle\n",
+        "{\n",
+        "   \"1852\": {\n",
+        "      \"task_name\": \"cpuhog\", \n",
+        "      \"dutycycle\": 10.050119999991693\n",
+        "   }\n",
+        "}\n"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "heading",
+     "level": 1,
+     "metadata": {},
+     "source": [
+      "Changing Reservations"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "A CPU hogging task has reservations set in the increasing order starting from 10%  followed by a 2s period of normal execution"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "TRACE_FILE = os.path.join(BASE_PATH, \"cancel_dl_timer\")\n",
+      "run = trappy.Run(TRACE_FILE, \"cpuhog\")\n",
+      "s = SchedAssert(run, topology, execname=\"cpuhog\")\n",
+      "s.plot().view()\n",
+      "\n",
+      "NUM_PHASES = 10\n",
+      "PHASE_DURATION = 2\n",
+      "start = s.getStartTime()\n",
+      "DUTY_CYCLE_FACTOR = 10\n",
+      "\n",
+      "\n",
+      "for phase in range(NUM_PHASES + 1):\n",
+      "    window = (start + (phase * PHASE_DURATION),\n",
+      "              start + ((phase + 1) * PHASE_DURATION))\n",
+      "    \n",
+      "    if phase % 2 == 0:\n",
+      "        DUTY_CYCLE = (phase + 2) * DUTY_CYCLE_FACTOR / 2\n",
+      "    else:\n",
+      "        DUTY_CYCLE = 100\n",
+      "\n",
+      "\n",
+      "    print \"WINDOW -> [{:.2f}, {:.2f}]\".format(window[0],\n",
+      "                                            window[1])\n",
+      "    \n",
+      "    \n",
+      "    \n",
+      "    if s.assertDutyCycle(DUTY_CYCLE, between_threshold, window=window):\n",
+      "        print \"PASS: Expected={} Actual={:.2f} THRESHOLD={}\".format(DUTY_CYCLE,\n",
+      "                                                                s.getDutyCycle(window=window),\n",
+      "                                                                THRESHOLD)\n",
+      "    else:\n",
+      "        print \"FAIL: Expected={} Actual={:.2f} THRESHOLD={}\".format(DUTY_CYCLE,\n",
+      "                                                                s.getDutyCycle(window=window),\n",
+      "                                                                THRESHOLD)\n",
+      "    \n",
+      "    print \"\""
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<style>\n",
+        "/*\n",
+        "\n",
+        " *    Copyright 2015-2015 ARM Limited\n",
+        "\n",
+        " *\n",
+        "\n",
+        " * Licensed under the Apache License, Version 2.0 (the \"License\");\n",
+        "\n",
+        " * you may not use this file except in compliance with the License.\n",
+        "\n",
+        " * You may obtain a copy of the License at\n",
+        "\n",
+        " *\n",
+        "\n",
+        " *     http://www.apache.org/licenses/LICENSE-2.0\n",
+        "\n",
+        " *\n",
+        "\n",
+        " * Unless required by applicable law or agreed to in writing, software\n",
+        "\n",
+        " * distributed under the License is distributed on an \"AS IS\" BASIS,\n",
+        "\n",
+        " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
+        "\n",
+        " * See the License for the specific language governing permissions and\n",
+        "\n",
+        " * limitations under the License.\n",
+        "\n",
+        " */\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip {\n",
+        "\n",
+        "  line-height: 1;\n",
+        "\n",
+        "  padding: 12px;\n",
+        "\n",
+        "  background: rgba(0, 0, 0, 0.6);\n",
+        "\n",
+        "  color: #fff;\n",
+        "\n",
+        "  border-radius: 2px;\n",
+        "\n",
+        "  position: absolute !important;\n",
+        "\n",
+        "  z-index: 99999;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip:after {\n",
+        "\n",
+        "  box-sizing: border-box;\n",
+        "\n",
+        "  pointer-events: none;\n",
+        "\n",
+        "  display: inline;\n",
+        "\n",
+        "  font-size: 10px;\n",
+        "\n",
+        "  width: 100%;\n",
+        "\n",
+        "  line-height: 1;\n",
+        "\n",
+        "  color: rgba(0, 0, 0, 0.6);\n",
+        "\n",
+        "  content: \"\\25BC\";\n",
+        "\n",
+        "  position: absolute !important;\n",
+        "\n",
+        "  z-index: 99999;\n",
+        "\n",
+        "  text-align: center;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".d3-tip.n:after {\n",
+        "\n",
+        "  margin: -1px 0 0 0;\n",
+        "\n",
+        "  top: 100%;\n",
+        "\n",
+        "  left: 0;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".chart {\n",
+        "\n",
+        "  shape-rendering: crispEdges;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".mini text {\n",
+        "\n",
+        "  font: 9px sans-serif;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".main text {\n",
+        "\n",
+        "  font: 12px sans-serif;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".axis line, .axis path {\n",
+        "\n",
+        "  stroke: black;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".miniItem {\n",
+        "\n",
+        "  stroke-width: 8;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "\n",
+        "\n",
+        ".brush .extent {\n",
+        "\n",
+        "\n",
+        "\n",
+        "  stroke: #000;\n",
+        "\n",
+        "  fill-opacity: .125;\n",
+        "\n",
+        "  shape-rendering: crispEdges;\n",
+        "\n",
+        "}\n",
+        "\n",
+        "</style>\n",
+        "<div id=\"fig_421afa8cc8234df49030c900b680220b\" class=\"eventplot\">\n",
+        "        <script>\n",
+        "            var req = require.config( {\n",
+        "\n",
+        "                paths: {\n",
+        "\n",
+        "                    \"EventPlot\": \"https://rawgit.com/sinkap/7f89de3e558856b81f10/raw/46144f8f8c5da670c54f826f0c634762107afc66/EventPlot\",\n",
+        "                    \"d3-tip\": \"http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3\",\n",
+        "                    \"d3\": \"http://d3js.org/d3.v3.min\"\n",
+        "                },\n",
+        "                shim: {\n",
+        "                    \"d3-tip\": [\"d3\"],\n",
+        "                    \"EventPlot\": {\n",
+        "\n",
+        "                        \"deps\": [\"d3-tip\", \"d3\" ],\n",
+        "                        \"exports\":  \"EventPlot\"\n",
+        "                    }\n",
+        "                }\n",
+        "            });\n",
+        "            req([\"require\", \"EventPlot\"], function() {\n",
+        "               EventPlot.generate('fig_421afa8cc8234df49030c900b680220b', 'https://rawgit.com/sinkap/a207675f6483aa0b9342/raw/825717935112f36fe996b77093c0c71d3871fee4/fig_421afa8cc8234df49030c900b680220b.json');\n",
+        "            });\n",
+        "        </script>\n",
+        "        </div>"
+       ],
+       "metadata": {},
+       "output_type": "display_data",
+       "text": [
+        "<IPython.core.display.HTML object>"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "WINDOW -> [0.00, 2.00]\n",
+        "PASS: Expected=10 Actual=10.38 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [2.00, 4.00]\n",
+        "PASS: Expected=100 Actual=99.60 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [4.00, 6.00]\n",
+        "PASS: Expected=20 Actual=21.06 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [6.00, 8.00]\n",
+        "PASS: Expected=100 Actual=95.69 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [8.00, 10.00]\n",
+        "PASS: Expected=30 Actual=31.78 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [10.00, 12.00]\n",
+        "PASS: Expected=100 Actual=98.23 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [12.00, 14.00]\n",
+        "PASS: Expected=40 Actual=40.74 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [14.00, 16.00]\n",
+        "PASS: Expected=100 Actual=97.58 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [16.00, 18.00]\n",
+        "PASS: Expected=50 Actual=52.51 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [18.00, 20.00]\n",
+        "PASS: Expected=100 Actual=96.38 THRESHOLD=10.0\n",
+        "\n",
+        "WINDOW -> [20.00, 22.00]\n",
+        "PASS: Expected=60 Actual=60.71 THRESHOLD=10.0\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 4
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file