<!DOCTYPE html>
<!--
Copyright (c) 2014 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="/extras/importer/etw/parser.html">

<script>
'use strict';

/**
 * @fileoverview Parses threads events in the Windows event trace format.
 *
 * The Windows thread events are:
 *
 * - DCStart: Describes a thread that was already running when the trace
 *    started. ETW automatically generates these events for all running
 *    threads at the beginning of the trace.
 * - Start: Describes a thread that started during the tracing session.
 * - End: Describes a thread that ended during the tracing session.
 * - DCEnd: Describes a thread that was still alive when the trace ended.
 *
 * See http://msdn.microsoft.com/library/windows/desktop/aa364132.aspx
 */
tr.exportTo('tr.e.importer.etw', function() {
  var Parser = tr.e.importer.etw.Parser;

  // Constants for Thread events.
  var guid = '3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';
  var kThreadStartOpcode = 1;
  var kThreadEndOpcode = 2;
  var kThreadDCStartOpcode = 3;
  var kThreadDCEndOpcode = 4;
  var kThreadCSwitchOpcode = 36;

  /**
   * Parses Windows threads trace events.
   * @constructor
   */
  function ThreadParser(importer) {
    Parser.call(this, importer);

    // Register handlers.
    importer.registerEventHandler(guid, kThreadStartOpcode,
        ThreadParser.prototype.decodeStart.bind(this));
    importer.registerEventHandler(guid, kThreadEndOpcode,
        ThreadParser.prototype.decodeEnd.bind(this));
    importer.registerEventHandler(guid, kThreadDCStartOpcode,
        ThreadParser.prototype.decodeDCStart.bind(this));
    importer.registerEventHandler(guid, kThreadDCEndOpcode,
        ThreadParser.prototype.decodeDCEnd.bind(this));
    importer.registerEventHandler(guid, kThreadCSwitchOpcode,
        ThreadParser.prototype.decodeCSwitch.bind(this));
  }

  ThreadParser.prototype = {
    __proto__: Parser.prototype,

    decodeFields: function(header, decoder) {
      if (header.version > 3)
        throw new Error('Incompatible Thread event version.');

      // Common fields to all Thread events.
      var processId = decoder.decodeUInt32();
      var threadId = decoder.decodeUInt32();

      // Extended fields.
      var stackBase;
      var stackLimit;
      var userStackBase;
      var userStackLimit;
      var affinity;
      var startAddr;
      var win32StartAddr;
      var tebBase;
      var subProcessTag;
      var basePriority;
      var pagePriority;
      var ioPriority;
      var threadFlags;
      var waitMode;

      if (header.version == 1) {
        // On version 1, only start events have extended information.
        if (header.opcode == kThreadStartOpcode ||
            header.opcode == kThreadDCStartOpcode) {
          stackBase = decoder.decodeUInteger(header.is64);
          stackLimit = decoder.decodeUInteger(header.is64);
          userStackBase = decoder.decodeUInteger(header.is64);
          userStackLimit = decoder.decodeUInteger(header.is64);
          startAddr = decoder.decodeUInteger(header.is64);
          win32StartAddr = decoder.decodeUInteger(header.is64);
          waitMode = decoder.decodeInt8();
          decoder.skip(3);
        }
      } else {
        stackBase = decoder.decodeUInteger(header.is64);
        stackLimit = decoder.decodeUInteger(header.is64);
        userStackBase = decoder.decodeUInteger(header.is64);
        userStackLimit = decoder.decodeUInteger(header.is64);

        // Version 2 produces a field named 'startAddr'.
        if (header.version == 2)
          startAddr = decoder.decodeUInteger(header.is64);
        else
          affinity = decoder.decodeUInteger(header.is64);

        win32StartAddr = decoder.decodeUInteger(header.is64);
        tebBase = decoder.decodeUInteger(header.is64);
        subProcessTag = decoder.decodeUInt32();

        if (header.version == 3) {
          basePriority = decoder.decodeUInt8();
          pagePriority = decoder.decodeUInt8();
          ioPriority = decoder.decodeUInt8();
          threadFlags = decoder.decodeUInt8();
        }
      }

      return {
        processId: processId,
        threadId: threadId,
        stackBase: stackBase,
        stackLimit: stackLimit,
        userStackBase: userStackBase,
        userStackLimit: userStackLimit,
        affinity: affinity,
        startAddr: startAddr,
        win32StartAddr: win32StartAddr,
        tebBase: tebBase,
        subProcessTag: subProcessTag,
        waitMode: waitMode,
        basePriority: basePriority,
        pagePriority: pagePriority,
        ioPriority: ioPriority,
        threadFlags: threadFlags
      };
    },

    decodeCSwitchFields: function(header, decoder) {
      if (header.version != 2)
        throw new Error('Incompatible Thread event version.');

      // Decode CSwitch payload.
      var newThreadId = decoder.decodeUInt32();
      var oldThreadId = decoder.decodeUInt32();
      var newThreadPriority = decoder.decodeInt8();
      var oldThreadPriority = decoder.decodeInt8();
      var previousCState = decoder.decodeUInt8();
      var spareByte = decoder.decodeInt8();
      var oldThreadWaitReason = decoder.decodeInt8();
      var oldThreadWaitMode = decoder.decodeInt8();
      var oldThreadState = decoder.decodeInt8();
      var oldThreadWaitIdealProcessor = decoder.decodeInt8();
      var newThreadWaitTime = decoder.decodeUInt32();
      var reserved = decoder.decodeUInt32();

      return {
        newThreadId: newThreadId,
        oldThreadId: oldThreadId,
        newThreadPriority: newThreadPriority,
        oldThreadPriority: oldThreadPriority,
        previousCState: previousCState,
        spareByte: spareByte,
        oldThreadWaitReason: oldThreadWaitReason,
        oldThreadWaitMode: oldThreadWaitMode,
        oldThreadState: oldThreadState,
        oldThreadWaitIdealProcessor: oldThreadWaitIdealProcessor,
        newThreadWaitTime: newThreadWaitTime,
        reserved: reserved
      };
    },

    decodeStart: function(header, decoder) {
      var fields = this.decodeFields(header, decoder);
      this.importer.createThreadIfNeeded(fields.processId, fields.threadId);
      return true;
    },

    decodeEnd: function(header, decoder) {
      var fields = this.decodeFields(header, decoder);
      this.importer.removeThreadIfPresent(fields.threadId);
      return true;
    },

    decodeDCStart: function(header, decoder) {
      var fields = this.decodeFields(header, decoder);
      this.importer.createThreadIfNeeded(fields.processId, fields.threadId);
      return true;
    },

    decodeDCEnd: function(header, decoder) {
      var fields = this.decodeFields(header, decoder);
      this.importer.removeThreadIfPresent(fields.threadId);
      return true;
    },

    decodeCSwitch: function(header, decoder) {
      var fields = this.decodeCSwitchFields(header, decoder);
      var cpu = this.importer.getOrCreateCpu(header.cpu);
      var new_thread =
          this.importer.getThreadFromWindowsTid(fields.newThreadId);

      // Generate the new thread name. If some events were lost, it's possible
      // that information about the new thread or process is not available.
      var new_thread_name;
      if (new_thread && new_thread.userFriendlyName) {
        new_thread_name = new_thread.userFriendlyName;
      } else {
        var new_process_id = this.importer.getPidFromWindowsTid(
            fields.newThreadId);
        var new_process = this.model.getProcess(new_process_id);
        var new_process_name;
        if (new_process)
          new_process_name = new_process.name;
        else
          new_process_name = 'Unknown process';

        new_thread_name =
            new_process_name + ' (tid ' + fields.newThreadId + ')';
      }

      cpu.switchActiveThread(
          header.timestamp,
          {},
          fields.newThreadId,
          new_thread_name,
          fields);
      return true;
    }

  };

  Parser.register(ThreadParser);

  return {
    ThreadParser: ThreadParser
  };
});
</script>

