1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/range.html">
9<link rel="import" href="/tracing/model/slice.html">
10
11<script>
12'use strict';
13
14tr.exportTo('tr.model', function() {
15  var Slice = tr.model.Slice;
16
17
18  var SCHEDULING_STATE = {
19    DEBUG: 'Debug',
20    EXIT_DEAD: 'Exit Dead',
21    RUNNABLE: 'Runnable',
22    RUNNING: 'Running',
23    SLEEPING: 'Sleeping',
24    STOPPED: 'Stopped',
25    TASK_DEAD: 'Task Dead',
26    UNINTR_SLEEP: 'Uninterruptible Sleep',
27    UNINTR_SLEEP_WAKE_KILL: 'Uninterruptible Sleep | WakeKill',
28    UNINTR_SLEEP_WAKING: 'Uninterruptible Sleep | Waking',
29    UNINTR_SLEEP_IO: 'Uninterruptible Sleep - Block I/O',
30    UNINTR_SLEEP_WAKE_KILL_IO: 'Uninterruptible Sleep | WakeKill - Block I/O',
31    UNINTR_SLEEP_WAKING_IO: 'Uninterruptible Sleep | Waking - Block I/O',
32    UNKNOWN: 'UNKNOWN',
33    WAKE_KILL: 'Wakekill',
34    WAKING: 'Waking',
35    ZOMBIE: 'Zombie'
36  };
37
38  /**
39   * A ThreadTimeSlice is a slice of time on a specific thread where that thread
40   * was running on a specific CPU, or in a specific sleep state.
41   *
42   * As a thread switches moves through its life, it sometimes goes to sleep and
43   * can't run. Other times, its runnable but isn't actually assigned to a CPU.
44   * Finally, sometimes it gets put on a CPU to actually execute. Each of these
45   * states is represented by a ThreadTimeSlice:
46   *
47   *   Sleeping or runnable: cpuOnWhichThreadWasRunning is undefined
48   *   Running:  cpuOnWhichThreadWasRunning is set.
49   *
50   * @constructor
51   */
52  function ThreadTimeSlice(thread, schedulingState, cat,
53                           start, args, opt_duration) {
54    Slice.call(this, cat, schedulingState,
55               this.getColorForState_(schedulingState),
56        start, args, opt_duration);
57    this.thread = thread;
58    this.schedulingState = schedulingState;
59    this.cpuOnWhichThreadWasRunning = undefined;
60  }
61
62  ThreadTimeSlice.prototype = {
63    __proto__: Slice.prototype,
64
65    getColorForState_: function(state) {
66      var getColorIdForReservedName =
67          tr.b.ColorScheme.getColorIdForReservedName;
68
69      switch (state) {
70        case SCHEDULING_STATE.RUNNABLE:
71          return getColorIdForReservedName('thread_state_runnable');
72        case SCHEDULING_STATE.RUNNING:
73          return getColorIdForReservedName('thread_state_running');
74        case SCHEDULING_STATE.SLEEPING:
75          return getColorIdForReservedName('thread_state_sleeping');
76        case SCHEDULING_STATE.DEBUG:
77        case SCHEDULING_STATE.EXIT_DEAD:
78        case SCHEDULING_STATE.STOPPED:
79        case SCHEDULING_STATE.TASK_DEAD:
80        case SCHEDULING_STATE.UNINTR_SLEEP:
81        case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:
82        case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:
83        case SCHEDULING_STATE.UNKNOWN:
84        case SCHEDULING_STATE.WAKE_KILL:
85        case SCHEDULING_STATE.WAKING:
86        case SCHEDULING_STATE.ZOMBIE:
87          return getColorIdForReservedName('thread_state_uninterruptible');
88        case SCHEDULING_STATE.UNINTR_SLEEP_IO:
89        case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:
90        case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:
91          return getColorIdForReservedName('thread_state_iowait');
92        default:
93          return getColorIdForReservedName('thread_state_unknown');
94      }
95    },
96
97    get analysisTypeName() {
98      return 'tr.ui.analysis.ThreadTimeSlice';
99    },
100
101    getAssociatedCpuSlice: function() {
102      if (!this.cpuOnWhichThreadWasRunning)
103        return undefined;
104      var cpuSlices = this.cpuOnWhichThreadWasRunning.slices;
105      for (var i = 0; i < cpuSlices.length; i++) {
106        var cpuSlice = cpuSlices[i];
107        if (cpuSlice.start !== this.start)
108          continue;
109        if (cpuSlice.duration !== this.duration)
110          continue;
111        return cpuSlice;
112      }
113      return undefined;
114    },
115
116    getCpuSliceThatTookCpu: function() {
117      if (this.cpuOnWhichThreadWasRunning)
118        return undefined;
119      var curIndex = this.thread.indexOfTimeSlice(this);
120      var cpuSliceWhenLastRunning;
121      while (curIndex >= 0) {
122        var curSlice = this.thread.timeSlices[curIndex];
123        if (!curSlice.cpuOnWhichThreadWasRunning) {
124          curIndex--;
125          continue;
126        }
127        cpuSliceWhenLastRunning = curSlice.getAssociatedCpuSlice();
128        break;
129      }
130      if (!cpuSliceWhenLastRunning)
131        return undefined;
132
133      var cpu = cpuSliceWhenLastRunning.cpu;
134      var indexOfSliceOnCpuWhenLastRunning =
135          cpu.indexOf(cpuSliceWhenLastRunning);
136      var nextRunningSlice = cpu.slices[indexOfSliceOnCpuWhenLastRunning + 1];
137      if (!nextRunningSlice)
138        return undefined;
139      if (Math.abs(nextRunningSlice.start - cpuSliceWhenLastRunning.end) <
140          0.00001)
141        return nextRunningSlice;
142      return undefined;
143    }
144  };
145
146  tr.model.EventRegistry.register(
147      ThreadTimeSlice,
148      {
149        name: 'threadTimeSlice',
150        pluralName: 'threadTimeSlices',
151        singleViewElementName: 'tr-ui-a-single-thread-time-slice-sub-view',
152        multiViewElementName: 'tr-ui-a-multi-thread-time-slice-sub-view'
153      });
154
155
156  return {
157    ThreadTimeSlice: ThreadTimeSlice,
158    SCHEDULING_STATE: SCHEDULING_STATE
159  };
160});
161</script>
162