//////////////////////////////////////////////////////////////////////////////// // // 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)] 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 [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void Finalize(); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern byte * CompareExchange(byte **dest, byte *exch, byte *comp); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern LogEntry * CompareExchange(LogEntry **dest, LogEntry *exch, LogEntry *comp); public static unsafe void GetMonitoringHeaders(out byte * _buffer) { _buffer = buffer; } [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern LogEntry * IndexToPointer(ushort index); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern ushort Dequeue(); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern void Enqueue(ushort newElement); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern void Enqueue(ushort newElement, ulong * ptr); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(64)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern byte * AddText(byte *buffer, string arg); /* 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); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern void DebugTest(out ulong h_ts, out ulong t_ts, out ulong min, out ulong max); [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe extern uint ConsistencyCheck(); /* [AccessedByRuntime("output to header : defined in Monitoring.cpp")] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern LogEntry * CreateLog(byte severity, UIntPtr eip, int chars, out byte *text); */ } }