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