//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Monitoring.cs // // Note: Provides a little bit more sophisticated runtime monitoring (i.e., // writing and reading events will be possible concurrently at runtime) // facility for performance and other debugging // // using System; using System.Diagnostics; using System.Text; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; using Microsoft.Singularity; using Microsoft.Singularity.Memory; namespace Microsoft.Singularity { [NoCCtor] [CLSCompliant(false)] [AccessedByRuntime("referenced from Monitoring.cpp")] public class Monitoring { [AccessedByRuntime("referenced from Monitoring.cpp")] public struct LogEntry { [AccessedByRuntime("referenced from Monitoring.cpp")] public ulong cycleCount; // bytes 0..7 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr eip; // bytes 8..11 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort threadId; // bytes 12..13 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort processId; // bytes 14..15 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort provider; // bytes 16..17 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort type; // bytes 18..19 [AccessedByRuntime("referenced from Monitoring.cpp")] public unsafe byte * text; // bytes 20..23 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort cpu; // bytes 24..25 [AccessedByRuntime("referenced from Monitoring.cpp")] public ushort version; // bytes 26..27 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr arg0; // bytes 28..31 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr arg1; // bytes 32..35 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr arg2; // bytes 36..38 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr arg3; // bytes 40..43 [AccessedByRuntime("referenced from Monitoring.cpp")] public UIntPtr arg4; // bytes 44..47 } // This does not work, probably a Bartok problem // [AccessedByRuntime("referenced from Monitoring.cpp")] // public struct IndexEntry // { // [AccessedByRuntime("referenced from Monitoring.cpp")] // public /*volatile*/ ulong data; // bytes 0..7 // } // Note: These fields are initialized by the code in Monitoring.cpp. // [AccessedByRuntime("referenced from Monitoring.cpp")] private static unsafe byte * buffer; // // End Note. [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void Initialize(); #if SINGULARITY_KERNEL [AccessedByRuntime("output to header : defined in Monitoring.cpp")] private static unsafe void InitPages(UIntPtr bytes) { UIntPtr pages = MemoryManager.PagesFromBytes( MemoryManager.PagePad(bytes)); buffer = (byte *)MemoryManager.KernelAllocate( pages, null, 0, System.GCs.PageType.NonGC).ToPointer(); } [AccessedByRuntime("output to header : defined in Monitoring.cpp")] private static unsafe UIntPtr InitText(UIntPtr bytes) { UIntPtr pages = MemoryManager.PagesFromBytes( MemoryManager.PagePad(bytes)); return MemoryManager.KernelAllocate( pages, null, 0, System.GCs.PageType.NonGC); } #endif // Well-known provider IDs public struct Provider { public const ushort SysInfo = 1; public const ushort Cassini = 3; public const ushort Shell = 5; public const ushort Endpoint = 8; public const ushort ChannelService = 9; public const ushort WaitHandle = 10; public const ushort AutoResetEvent = 11; public const ushort Mutex = 12; public const ushort ManualResetEvent = 13; public const ushort EndpointCore = 14; public const ushort Process = 19; public const ushort Thread = 20; public const ushort DiskIo = 21; public const ushort WebServer = 22; // Not Cassini public const ushort Directory = 23; // see Windows\ETS\Directory.tmf public const ushort GC = 25; public const ushort Iso9660 = 26; public const ushort Processor = 30; } [Conditional("Monitoring")] [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern void Log(ushort provider, ushort type, ushort version, uint a0, uint a1, uint a2, uint a3, uint a4); [Conditional("Monitoring")] [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern void Log(ushort provider, ushort type); [Conditional("Monitoring")] [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern void Log(ushort provider, ushort type, string s); // \brief Return one LogEntry to caller // \param min_counter minimum event counter to read event for, will be // modified and contains the actually read event in // it after return // \param log log entry to be filled // public static unsafe int GetEntry(ref ulong min_counter, out LogEntry log) { int ret; fixed (LogEntry * pl = &log) { fixed (ulong * pm = &min_counter) { ret = FillLogEntry(pl, pm); } } return ret; } // \brief Return text part for log entry // \param src where to get the data from // \param counter counter to expect at start of src // \param dst where to copy the byte array to // \param max_size copy max_size bytes at max // public static unsafe int GetText(byte * src, ulong counter, byte * dst, int max_size) { int ret; ret = FillTextEntry(src, counter, dst, max_size); return ret; } [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern int FillLogEntry(LogEntry * log, ulong * min_counter); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern int FillTextEntry(byte * src, ulong counter, byte * dst, int max_size); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(32)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern bool isActive(); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(32)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern void setActive(bool active); } }