singrdk/base/Kernel/Singularity/Eventing/MemoryStorage.cs

301 lines
10 KiB
C#

////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: MemoryStorage.cs
//
// Note:
//
using System;
using System.Threading;
using System.Runtime.CompilerServices;
using Microsoft.Singularity;
using Microsoft.Singularity.V1.Services;
namespace Microsoft.Singularity.Eventing
{
[CLSCompliant(false)]
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public unsafe struct ArrayType {
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public ushort Length;
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public ushort ItemSize;
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public uint Type;
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public void * Buffer;
}
[CLSCompliant(false)]
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public class MemoryStorage : EventingStorage {
private Mutex mutex;
private UnmanagedMemoryBuffer Buffers;
private LocalController hostController = null;
~MemoryStorage()
{
Destroy();
}
unsafe public bool InitializeFromExistingHandle()
{
mutex = new Mutex();
if (mutex == null) {
return false;
}
// Mirror the existing memory buffer. We do not need actually to also fetch
// the pointers since someone else has the ownership of that memory
Buffers = new UnmanagedMemoryBuffer();
hostController = Controller.GetLocalController();
return (Buffers != null);
}
unsafe public bool Initialize(ulong Size)
{
mutex = new Mutex();
if (mutex == null) {
return false;
}
UnmanagedMemoryBuffer NewBuffer = new UnmanagedMemoryBuffer();
if (NewBuffer != null) {
uint overheadSize = MemoryStorage.GetMemoryStorageOveheadImpl();
if (!NewBuffer.AllocateBuffer(overheadSize + Size)) {
return false;
}
Buffers = NewBuffer;
StorageHandle = MemoryStorage.MemoryStorageCreateImpl(
QoS.StorageSettings,
NewBuffer.GetBuffer(),
(uint)NewBuffer.GetSize(),
0);
if (Controller.GetLocalController().RegisterStorage( this )) {
hostController = Controller.GetLocalController();
return true;
}
}
return false;
}
public override bool AddBuffer(ulong Size)
{
unsafe {
UnmanagedMemoryBuffer NewBuffer = new UnmanagedMemoryBuffer();
if (NewBuffer != null) {
if (!NewBuffer.AllocateBuffer(Size)) {
return false;
}
}
mutex.AcquireMutex();
NewBuffer.Link = Buffers;
Buffers = NewBuffer;
mutex.ReleaseMutex();
MemoryStorage.MemoryStorageRegisterBufferImpl(StorageHandle,
NewBuffer.GetBuffer(),
(uint)NewBuffer.GetSize());
}
return true;
}
void Destroy() {
if (hostController != null) {
hostController.UnRegisterStorage(this);
}
}
[NoHeapAllocation]
public override unsafe UIntPtr CreateQueryView(bool forward)
{
return CreateQueryViewImpl(StorageHandle, forward);
}
[NoHeapAllocation]
public override unsafe void DeleteQueryView(UIntPtr queryHandle)
{
DeleteQueryViewImpl(queryHandle);
}
public override UIntPtr GetNextEntry(UIntPtr queryHandle,
ref QueryBuffer entryBuffer)
{
unsafe {
UInt32 offset;
UIntPtr type;
fixed(byte * ptr = &(entryBuffer.GetBuffer()[0])) {
entryBuffer.EntryHandle = MemoryStorage.GetNextEntryImpl(queryHandle ,
&type,
&offset,
ptr,
entryBuffer.GetBufferSize());
entryBuffer.Type = type;
entryBuffer.UserOffset = offset;
return entryBuffer.EntryHandle;
}
}
}
// ABI interfaces
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
static extern unsafe uint GetMemoryStorageOveheadImpl();
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
static extern unsafe UIntPtr MemoryStorageCreateImpl(uint Flags,
byte * memoryBuffer,
uint bufferSize,
uint ZoneSize);
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
static extern unsafe void MemoryStorageRegisterBufferImpl(UIntPtr Storage,
byte * memoryBuffer,
uint bufferSize);
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
public static extern unsafe UIntPtr CreateQueryViewImpl(UIntPtr Storage, bool forward);
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
public static extern unsafe void DeleteQueryViewImpl(UIntPtr queryHandle);
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
public static extern unsafe UIntPtr WalkEventDescriptorImpl(UIntPtr eventHandle,
UIntPtr currentField,
UInt16 * offset,
UInt16 * type,
char * bufferName,
UInt16 bufferSize );
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(256)]
[NoHeapAllocation]
public static extern unsafe UIntPtr GetNextEntryImpl(UIntPtr queryHandle,
UIntPtr * type,
UInt32 * userOffset,
byte * buffer,
UInt16 bufferSize );
}
[CLSCompliant(false)]
[AccessedByRuntime("output to header : defined in MemoryStorage.cpp")]
public class GlobalStorage : EventingStorage {
~GlobalStorage()
{
Destroy();
}
public GlobalStorage(UIntPtr storageId)
{
StorageHandle = DiagnosisService.OpenGlobalStorage(storageId);
}
void Destroy() {
if (StorageHandle != 0) {
DiagnosisService.CloseGlobalStorage(StorageHandle);
}
}
[NoHeapAllocation]
public override unsafe UIntPtr CreateQueryView(bool forward)
{
return DiagnosisService.CreateQueryView(StorageHandle, forward);
}
[NoHeapAllocation]
public override unsafe void DeleteQueryView(UIntPtr queryHandle)
{
DiagnosisService.DeleteQueryView(queryHandle);
}
public override Controller GetController()
{
return Controller.GetSystemController();
}
public override UIntPtr GetNextEntry(UIntPtr queryHandle,
ref QueryBuffer entryBuffer)
{
unsafe {
UInt32 offset;
UIntPtr type;
fixed(byte * ptr = &(entryBuffer.GetBuffer()[0])) {
entryBuffer.EntryHandle = DiagnosisService.GetNextEntry(queryHandle ,
&type,
&offset,
ptr,
entryBuffer.GetBufferSize());
entryBuffer.Type = type;
entryBuffer.UserOffset = offset;
return entryBuffer.EntryHandle;
}
}
}
}
}