276 lines
12 KiB
C#
276 lines
12 KiB
C#
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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);
|
|
*/
|
|
}
|
|
}
|