15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System; 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System.Collections; 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System.Collections.Generic; 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System.Diagnostics; 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System.Runtime.InteropServices; 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using System.Text; 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace StatsViewer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The stats table shared memory segment contains this 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// header structure. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [StructLayout(LayoutKind.Sequential)] 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal struct StatsFileHeader { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int version; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int size; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int max_counters; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int max_threads; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// An entry in the StatsTable. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsTableEntry { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTableEntry(int id, string name, StatsTable table) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_ = id; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_ = name; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_ = table; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The unique id for this entry 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int id { get { return id_; } } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The name for this entry. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public string name { get { return name_; } } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The value of this entry now. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetValue(int filter_pid) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return table_.GetValue(id_, filter_pid); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private int id_; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private string name_; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTable table_; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An interface for StatsCounters 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface IStatsCounter { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The name of the counter 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name { get; } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A counter. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsCounter : IStatsCounter { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsCounter(StatsTableEntry entry) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = entry; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public string name { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry_.name; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetValue(int filter_pid) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry_.GetValue(filter_pid); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTableEntry entry_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A timer. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsTimer : IStatsCounter { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTimer(StatsTableEntry entry) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = entry; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public string name { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry_.name; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetValue(int filter_pid) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry_.GetValue(filter_pid); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTableEntry entry_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A rate. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsCounterRate : IStatsCounter 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsCounterRate(StatsCounter counter, StatsTimer timer) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter_ = counter; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_ = timer; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public string name { get { return counter_.name; } } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetCount(int filter_pid) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return counter_.GetValue(filter_pid); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetTime(int filter_pid) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return timer_.GetValue(filter_pid); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsCounter counter_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTimer timer_; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// This is a C# reader for the chrome stats_table. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsTable { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal const int kMaxThreadNameLength = 32; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal const int kMaxCounterNameLength = 32; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Open a StatsTable 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTable() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Public Properties 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get access to the counters in the table. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTableCounters Counters() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new StatsTableCounters(this); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get access to the processes in the table 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ICollection Processes { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new StatsTableProcesses(this); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Internal Properties 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The internal methods are accessible to the enumerators 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and helper classes below. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Access to the table header 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal StatsFileHeader Header { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { return header_; } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get the offset of the ThreadName table 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal long ThreadNamesOffset { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return memory_.ToInt64() + Marshal.SizeOf(typeof(StatsFileHeader)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get the offset of the PIDs table 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal long PidsOffset { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = ThreadNamesOffset; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thread names table 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += AlignedSize(header_.max_threads * kMaxThreadNameLength * 2); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thread TID table 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += AlignedSize(header_.max_threads * 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Marshal.SizeOf(typeof(int))); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get the offset of the CounterName table 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal long CounterNamesOffset { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = PidsOffset; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thread PID table 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += AlignedSize(header_.max_threads * 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Marshal.SizeOf(typeof(int))); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get the offset of the Data table 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal long DataOffset { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = CounterNamesOffset; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Counter names table 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += AlignedSize(header_.max_counters * 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMaxCounterNameLength * 2); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Public Methods 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Opens the memory map 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <returns></returns> 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="name">The name of the file to open</param> 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public bool Open(string name) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_handle_ = 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Win32.OpenFileMapping((int)Win32.MapAccess.FILE_MAP_WRITE, false, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (map_handle_ == IntPtr.Zero) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_ = 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Win32.MapViewOfFile(map_handle_, (int)Win32.MapAccess.FILE_MAP_WRITE, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0,0, 0); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memory_ == IntPtr.Zero) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Win32.CloseHandle(map_handle_); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = (StatsFileHeader)Marshal.PtrToStructure(memory_, header_.GetType()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Close the mapped file. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void Close() { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Win32.UnmapViewOfFile(memory_); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Win32.CloseHandle(map_handle_); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Zero out the stats file. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void Zero() { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = DataOffset; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int threads = 0; threads < header_.max_threads; threads++) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int counters = 0; counters < header_.max_counters; counters++) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Marshal.WriteInt32((IntPtr) offset, 0); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += Marshal.SizeOf(typeof(int)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Get the value for a StatsCounterEntry now. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <returns></returns> 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="filter_pid">If a specific PID is being queried, filter to this PID. 0 means use all data.</param> 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="id">The id of the CounterEntry to get the value for.</param> 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int GetValue(int id, int filter_pid) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long pid_offset = PidsOffset; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long data_offset = DataOffset; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset += id * (Header.max_threads * 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Marshal.SizeOf(typeof(int))); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = 0; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int cols = 0; cols < Header.max_threads; cols++) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pid = Marshal.ReadInt32((IntPtr)pid_offset); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_pid == 0 || filter_pid == pid) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv += Marshal.ReadInt32((IntPtr)data_offset); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset += Marshal.SizeOf(typeof(int)); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_offset += Marshal.SizeOf(typeof(int)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Private Methods 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Align to 4-byte boundaries 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="size"></param> 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <returns></returns> 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private long AlignedSize(long size) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Debug.Assert(sizeof(int) == 4); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size + (sizeof(int) - (size % sizeof(int))) % sizeof(int); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Private Members 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private IntPtr memory_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private IntPtr map_handle_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsFileHeader header_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Enumerable list of Counters in the StatsTable 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsTableCounters : ICollection { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Create the list of counters 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="table"></param> 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// pid</param> 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTableCounters(StatsTable table) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_ = table; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter_hi_water_mark_ = -1; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_ = new List<IStatsCounter>(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindCounters(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Scans the table for new entries. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void Update() { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindCounters(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region IEnumerable Members 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public IEnumerator GetEnumerator() { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return counters_.GetEnumerator(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region ICollection Members 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void CopyTo(Array array, int index) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int Count { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return counters_.Count; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public bool IsSynchronized { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public object SyncRoot { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Private Methods 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Create a counter based on an entry 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="id"></param> 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="name"></param> 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <returns></returns> 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private IStatsCounter NameToCounter(int id, string name) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IStatsCounter rv = null; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check if the name has a type encoded 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name.Length > 2 && name[1] == ':') 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatsTableEntry entry = new StatsTableEntry(id, name.Substring(2), table_); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (name[0]) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 't': 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = new StatsTimer(entry); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'c': 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = new StatsCounter(entry); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatsTableEntry entry = new StatsTableEntry(id, name, table_); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = new StatsCounter(entry); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have two StatsTableEntries with the same name, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempt to upgrade them to a higher level type. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Example: A counter + a timer == a rate! 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private void UpgradeCounter(IStatsCounter old_counter, IStatsCounter counter) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_counter is StatsCounter && counter is StatsTimer) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatsCounterRate rate = new StatsCounterRate(old_counter as StatsCounter, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter as StatsTimer); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_.Remove(old_counter); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_.Add(rate); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (old_counter is StatsTimer && counter is StatsCounter) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatsCounterRate rate = new StatsCounterRate(counter as StatsCounter, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_counter as StatsTimer); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_.Remove(old_counter); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_.Add(rate); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Find the counters in the table and insert into the counters_ 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// hash table. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private void FindCounters() 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Debug.Assert(table_.Header.max_counters > 0); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = counter_hi_water_mark_; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find an entry in the table. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index++; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = table_.CounterNamesOffset + 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (index * StatsTable.kMaxCounterNameLength * 2); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = Marshal.PtrToStringUni((IntPtr)offset); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name.Length == 0) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record that we've already looked at this StatsTableEntry. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter_hi_water_mark_ = index; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IStatsCounter counter = NameToCounter(index, name); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (counter != null) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IStatsCounter old_counter = FindExistingCounter(counter.name); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_counter != null) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpgradeCounter(old_counter, counter); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counters_.Add(counter); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (index < table_.Header.max_counters - 1); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Find an existing counter in our table 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="name"></param> 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private IStatsCounter FindExistingCounter(string name) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foreach (IStatsCounter ctr in counters_) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctr.name == name) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ctr; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Private Members 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTable table_; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private List<IStatsCounter> counters_; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Highest index of counters processed. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private int counter_hi_water_mark_; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// A collection of processes 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StatsTableProcesses : ICollection 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Constructor 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <param name="table"></param> 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public StatsTableProcesses(StatsTable table) { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_ = table; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pids_ = new List<int>(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region ICollection Members 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void CopyTo(Array array, int index) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public int Count { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pids_.Count; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public bool IsSynchronized { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public object SyncRoot { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Exception("The method or operation is not implemented."); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region IEnumerable Members 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public IEnumerator GetEnumerator() { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pids_.GetEnumerator(); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <summary> 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Initialize the pid list. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </summary> 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private void Initialize() { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long offset = table_.ThreadNamesOffset; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < table_.Header.max_threads; index++) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string thread_name = Marshal.PtrToStringUni((IntPtr)offset); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_name.Length > 0) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long pidOffset = table_.PidsOffset + index * 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Marshal.SizeOf(typeof(int)); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pid = Marshal.ReadInt32((IntPtr)pidOffset); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pids_.Contains(pid)) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pids_.Add(pid); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += StatsTable.kMaxThreadNameLength * 2; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #region Private Members 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StatsTable table_; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private List<int> pids_; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endregion 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 547