323 lines
13 KiB
C#
323 lines
13 KiB
C#
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity - Singularity ABI
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: DiagnosisService.cs
|
||
|
//
|
||
|
// Note:
|
||
|
//
|
||
|
|
||
|
using System;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using System.Threading;
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.Memory;
|
||
|
using Microsoft.Singularity.Eventing;
|
||
|
|
||
|
namespace Microsoft.Singularity.V1.Services
|
||
|
{
|
||
|
[CLSCompliant(false)]
|
||
|
public struct DiagnosisService
|
||
|
{
|
||
|
|
||
|
public static ulong SIPBufferSize = 0;
|
||
|
public static ulong SIPProfileOptions = 0;
|
||
|
|
||
|
public static ulong KernelBufferSize = 0;
|
||
|
public static ulong KernelProfileOptions = 0;
|
||
|
|
||
|
// External entry points
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe int GCProfileSettings(
|
||
|
ulong *defaultMemorySize,
|
||
|
ulong *Options
|
||
|
)
|
||
|
{
|
||
|
|
||
|
*defaultMemorySize = SIPBufferSize;
|
||
|
*Options = SIPProfileOptions;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static bool RegisterEventingController(
|
||
|
UIntPtr controllerHandle,
|
||
|
UIntPtr executionContextHandle
|
||
|
)
|
||
|
{
|
||
|
return KernelController.KernelControllerObject.RegisterControllerImpl(
|
||
|
controllerHandle,
|
||
|
executionContextHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static bool DebugPrintLogEntry(UIntPtr controllerHandle, UIntPtr entryHandle)
|
||
|
{
|
||
|
return KernelController.DebugPrintLogEntry(
|
||
|
controllerHandle,
|
||
|
entryHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static bool TestKernelStorage()
|
||
|
{
|
||
|
return KernelController.TestKernelStorageImpl();
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static UIntPtr OpenGlobalStorage(UIntPtr storageHandle)
|
||
|
{
|
||
|
return KernelController.OpenStorageImpl(storageHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static void CloseGlobalStorage(UIntPtr storageHandle)
|
||
|
{
|
||
|
KernelController.KernelControllerObject.CloseStorageImpl(storageHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
[NoHeapAllocation]
|
||
|
public static unsafe UIntPtr LogSourceEntry(UIntPtr sourceHandle,
|
||
|
uint flags,
|
||
|
UIntPtr eventType,
|
||
|
byte * buffer,
|
||
|
int size)
|
||
|
{
|
||
|
return KernelController.LogSourceEntryImpl(sourceHandle,
|
||
|
flags,
|
||
|
eventType,
|
||
|
buffer,
|
||
|
size);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
[NoHeapAllocation]
|
||
|
public static unsafe UIntPtr LogSourceEntry(UIntPtr sourceHandle,
|
||
|
uint flags,
|
||
|
UIntPtr eventType,
|
||
|
byte * buffer,
|
||
|
int size,
|
||
|
int stringsCount,
|
||
|
void ** strings)
|
||
|
{
|
||
|
return KernelController.LogSourceEntryImpl(sourceHandle,
|
||
|
flags,
|
||
|
eventType,
|
||
|
buffer,
|
||
|
size,
|
||
|
stringsCount,
|
||
|
strings);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
[NoHeapAllocation]
|
||
|
public static UIntPtr CreateQueryView(UIntPtr storageHandle, bool forward)
|
||
|
{
|
||
|
return KernelController.CreateQueryViewImpl(storageHandle, forward);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
[NoHeapAllocation]
|
||
|
public static void DeleteQueryView(UIntPtr storageHandle)
|
||
|
{
|
||
|
KernelController.DeleteQueryViewImpl(storageHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe UIntPtr GetNextEntry(UIntPtr queryHandle,
|
||
|
UIntPtr * type,
|
||
|
UInt32 * userOffset,
|
||
|
byte * buffer,
|
||
|
UInt16 bufferSize )
|
||
|
{
|
||
|
return KernelController.GetNextEntryImpl(queryHandle,
|
||
|
type,
|
||
|
userOffset,
|
||
|
buffer,
|
||
|
bufferSize);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool RegisterEvent(char * eventName, char * eventDescription, UIntPtr * eventHandle) {
|
||
|
|
||
|
return KernelController.RegisterEvent(eventName, eventDescription, eventHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool RegisterEventField(UIntPtr eventHandle,
|
||
|
char * fieldName,
|
||
|
UInt16 offset,
|
||
|
UInt16 type) {
|
||
|
|
||
|
return KernelController.RegisterEventField(eventHandle,
|
||
|
fieldName,
|
||
|
offset,
|
||
|
type);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool RegisterEventGenericField(UIntPtr eventHandle,
|
||
|
char * fieldName,
|
||
|
UInt16 offset,
|
||
|
UInt16 size,
|
||
|
UIntPtr fieldTypeHandle) {
|
||
|
|
||
|
return KernelController.RegisterEventGenericField(eventHandle,
|
||
|
fieldName,
|
||
|
offset,
|
||
|
size,
|
||
|
fieldTypeHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool RegisterEnum(char * enumName, UInt16 type, UIntPtr * eventHandle)
|
||
|
{
|
||
|
|
||
|
return KernelController.RegisterEnum(enumName, type, eventHandle);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool RegisterEnumValue(UIntPtr eventHandle,
|
||
|
char * valueName,
|
||
|
UInt64 value,
|
||
|
byte flagChar)
|
||
|
{
|
||
|
|
||
|
return KernelController.RegisterEnumValue(eventHandle,
|
||
|
valueName,
|
||
|
value,
|
||
|
flagChar);
|
||
|
}
|
||
|
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe UIntPtr WalkEventDescriptor(UIntPtr eventHandle,
|
||
|
UIntPtr currentField,
|
||
|
UInt16 * offset,
|
||
|
UInt16 * type,
|
||
|
char * bufferName,
|
||
|
UInt16 bufferSize )
|
||
|
{
|
||
|
return KernelController.WalkEventDescriptor(eventHandle,
|
||
|
currentField,
|
||
|
offset,
|
||
|
type,
|
||
|
bufferName,
|
||
|
bufferSize);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool GetSourceInformation(UIntPtr sourceHandle,
|
||
|
UIntPtr * storageHandle,
|
||
|
UIntPtr * eventType,
|
||
|
UInt16 * count,
|
||
|
char * bufferName,
|
||
|
UInt16 bufferSize )
|
||
|
{
|
||
|
return KernelController.GetSourceInformation(sourceHandle,
|
||
|
storageHandle,
|
||
|
eventType,
|
||
|
count,
|
||
|
bufferName,
|
||
|
bufferSize);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe int QuerySourcesList(UIntPtr * buffer, int size)
|
||
|
{
|
||
|
return KernelController.QuerySourcesList(buffer, size);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe int QueryEventTypeList(UIntPtr * buffer, int size)
|
||
|
{
|
||
|
return KernelController.QueryEventTypeList(buffer, size);
|
||
|
}
|
||
|
|
||
|
[ExternalEntryPoint]
|
||
|
[CLSCompliant(false)]
|
||
|
public static unsafe bool ReadActiveSourceItem(UIntPtr sourceHandle,
|
||
|
int item,
|
||
|
UIntPtr * type,
|
||
|
byte * buffer,
|
||
|
UInt16 bufferSize )
|
||
|
{
|
||
|
return KernelController.KernelControllerObject.ReadActiveSourceItem(sourceHandle,
|
||
|
item,
|
||
|
type,
|
||
|
buffer,
|
||
|
bufferSize );
|
||
|
|
||
|
}
|
||
|
|
||
|
// Wrap this up with a consistent definition with the SIP side
|
||
|
// we need to fix the silent drop of unsafe
|
||
|
public static int GCProfileSettingsImpl(
|
||
|
out ulong defaultMemorySize,
|
||
|
out ulong Options
|
||
|
)
|
||
|
{
|
||
|
defaultMemorySize = KernelBufferSize;
|
||
|
Options = KernelProfileOptions;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
internal const uint DEFERED_COMMAND_ENABLE_KERNEL_GC = 1;
|
||
|
internal const uint DEFERED_COMMAND_FORCE_GC_COLLECTION = 2;
|
||
|
|
||
|
internal static uint DeferedCommand = 0;
|
||
|
|
||
|
public static void DeferedUpdateNotification()
|
||
|
{
|
||
|
uint CapturedValue = DeferedCommand;
|
||
|
|
||
|
DeferedCommand = 0;
|
||
|
|
||
|
// TODO: This needs to be be moved later in a work item thread pool mechanism
|
||
|
// of some sort
|
||
|
|
||
|
if ((CapturedValue & DEFERED_COMMAND_ENABLE_KERNEL_GC) != 0) {
|
||
|
// TODO: This API has disappeared in the arm branch
|
||
|
// - may need to get moved to a new API
|
||
|
// GCProfilerLogger.StartProfiling();
|
||
|
}
|
||
|
|
||
|
if ((CapturedValue & DEFERED_COMMAND_FORCE_GC_COLLECTION) != 0) {
|
||
|
DebugStub.WriteLine("Kernel GC collection started\n");
|
||
|
System.GC.Collect();
|
||
|
System.GC.WaitForPendingFinalizers();
|
||
|
System.GC.Collect();
|
||
|
DebugStub.WriteLine("Kernel GC collection completed\n");
|
||
|
DebugStub.Break();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|