| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="/base/range.html"> |
| <link rel="import" href="/model/slice.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.model', function() { |
| var Slice = tr.model.Slice; |
| |
| |
| var SCHEDULING_STATE = { |
| DEBUG: 'Debug', |
| EXIT_DEAD: 'Exit Dead', |
| RUNNABLE: 'Runnable', |
| RUNNING: 'Running', |
| SLEEPING: 'Sleeping', |
| STOPPED: 'Stopped', |
| TASK_DEAD: 'Task Dead', |
| UNINTR_SLEEP: 'Uninterruptible Sleep', |
| UNINTR_SLEEP_WAKE_KILL: 'Uninterruptible Sleep | WakeKill', |
| UNINTR_SLEEP_WAKING: 'Uninterruptible Sleep | Waking', |
| UNKNOWN: 'UNKNOWN', |
| WAKE_KILL: 'Wakekill', |
| WAKING: 'Waking', |
| ZOMBIE: 'Zombie' |
| }; |
| |
| /** |
| * A ThreadTimeSlice is a slice of time on a specific thread where that thread |
| * was running on a specific CPU, or in a specific sleep state. |
| * |
| * As a thread switches moves through its life, it sometimes goes to sleep and |
| * can't run. Other times, its runnable but isn't actually assigned to a CPU. |
| * Finally, sometimes it gets put on a CPU to actually execute. Each of these |
| * states is represented by a ThreadTimeSlice: |
| * |
| * Sleeping or runnable: cpuOnWhichThreadWasRunning is undefined |
| * Running: cpuOnWhichThreadWasRunning is set. |
| * |
| * @constructor |
| */ |
| function ThreadTimeSlice(thread, schedulingState, cat, |
| start, args, opt_duration) { |
| Slice.call(this, cat, schedulingState, |
| this.getColorForState_(schedulingState), |
| start, args, opt_duration); |
| this.thread = thread; |
| this.schedulingState = schedulingState; |
| this.cpuOnWhichThreadWasRunning = undefined; |
| } |
| |
| ThreadTimeSlice.prototype = { |
| __proto__: Slice.prototype, |
| |
| getColorForState_: function(state) { |
| var getColorIdForReservedName = tr.ui.b.getColorIdForReservedName; |
| switch (state) { |
| case SCHEDULING_STATE.RUNNABLE: |
| return getColorIdForReservedName('thread_state_runnable'); |
| case SCHEDULING_STATE.RUNNING: |
| return getColorIdForReservedName('thread_state_running'); |
| case SCHEDULING_STATE.SLEEPING: |
| return getColorIdForReservedName('thread_state_sleeping'); |
| case SCHEDULING_STATE.DEBUG: |
| case SCHEDULING_STATE.EXIT_DEAD: |
| case SCHEDULING_STATE.STOPPED: |
| case SCHEDULING_STATE.TASK_DEAD: |
| case SCHEDULING_STATE.UNINTR_SLEEP: |
| case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL: |
| case SCHEDULING_STATE.UNINTR_SLEEP_WAKING: |
| case SCHEDULING_STATE.UNKNOWN: |
| case SCHEDULING_STATE.WAKE_KILL: |
| case SCHEDULING_STATE.WAKING: |
| case SCHEDULING_STATE.ZOMBIE: |
| return getColorIdForReservedName('thread_state_iowait'); |
| default: |
| return getColorIdForReservedName('thread_state_unknown'); |
| } |
| }, |
| |
| get analysisTypeName() { |
| return 'tr.ui.analysis.ThreadTimeSlice'; |
| }, |
| |
| getAssociatedCpuSlice: function() { |
| if (!this.cpuOnWhichThreadWasRunning) |
| return undefined; |
| var cpuSlices = this.cpuOnWhichThreadWasRunning.slices; |
| for (var i = 0; i < cpuSlices.length; i++) { |
| var cpuSlice = cpuSlices[i]; |
| if (cpuSlice.start !== this.start) |
| continue; |
| if (cpuSlice.duration !== this.duration) |
| continue; |
| return cpuSlice; |
| } |
| return undefined; |
| }, |
| |
| getCpuSliceThatTookCpu: function() { |
| if (this.cpuOnWhichThreadWasRunning) |
| return undefined; |
| var curIndex = this.thread.indexOfTimeSlice(this); |
| var cpuSliceWhenLastRunning; |
| while (curIndex >= 0) { |
| var curSlice = this.thread.timeSlices[curIndex]; |
| if (!curSlice.cpuOnWhichThreadWasRunning) { |
| curIndex--; |
| continue; |
| } |
| cpuSliceWhenLastRunning = curSlice.getAssociatedCpuSlice(); |
| break; |
| } |
| if (!cpuSliceWhenLastRunning) |
| return undefined; |
| |
| var cpu = cpuSliceWhenLastRunning.cpu; |
| var indexOfSliceOnCpuWhenLastRunning = |
| cpu.indexOf(cpuSliceWhenLastRunning); |
| var nextRunningSlice = cpu.slices[indexOfSliceOnCpuWhenLastRunning + 1]; |
| if (!nextRunningSlice) |
| return undefined; |
| if (Math.abs(nextRunningSlice.start - cpuSliceWhenLastRunning.end) < |
| 0.00001) |
| return nextRunningSlice; |
| return undefined; |
| } |
| }; |
| |
| tr.model.EventRegistry.register( |
| ThreadTimeSlice, |
| { |
| name: 'threadTimeSlice', |
| pluralName: 'threadTimeSlices', |
| singleViewElementName: 'tr-ui-a-single-thread-time-slice-sub-view', |
| multiViewElementName: 'tr-ui-a-multi-thread-time-slice-sub-view' |
| }); |
| |
| |
| return { |
| ThreadTimeSlice: ThreadTimeSlice, |
| SCHEDULING_STATE: SCHEDULING_STATE |
| }; |
| }); |
| </script> |