/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity - Singularity ABI // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: SharedHeapService.cs // // Note: // using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Singularity.V1.Types; namespace Microsoft.Singularity.V1.Services { public struct SharedHeapService { public struct AllocationOwnerId { // No fields visible to ABI callers. } #if !ROUTE_INDIRECTION_THROUGH_KERNEL [StructLayout(LayoutKind.Sequential)] public struct Allocation { public UIntPtr data; // Address of the allocated memory region. public UIntPtr size; // Size of above in bytes. public UIntPtr type; // Type information. private UIntPtr next; // Next on owner's list. private UIntPtr prev; // Previous on owner's list. public int owner; } #if DEBUG [Inline] [NoHeapAllocation] public static unsafe UIntPtr GetData(Allocation *allocation) { // CANNOT CHECK THE OWNER HERE UNLESS WE MAKE CURRENTPROCESS visible // to this compilation // // Check owner! // if (allocation->owner != Thread.CurrentProcess.ProcessId) { // DebugStub.Break(); // } return allocation->data; } #else [Inline] [NoHeapAllocation] public static unsafe UIntPtr GetData(Allocation *allocation) { return allocation->data; } #endif [Inline] [NoHeapAllocation] public static unsafe UIntPtr GetSize(Allocation *allocation) { return allocation->size; // return (allocation != null) ? allocation->size : UIntPtr.Zero; } [Inline] [NoHeapAllocation] public static unsafe UIntPtr GetType(Allocation *allocation) { return allocation->type; } [Inline] [NoHeapAllocation] public static unsafe void SetOwnerProcessId(Allocation *allocation, int processId) { allocation->owner = processId; } #else // ROUTE_INDIRECTION_THROUGH_KERNEL public struct Allocation { // No fields visible to ABI callers. } [OutsideGCDomain] [NoHeapAllocation] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe UIntPtr GetData(Allocation *allocation); [OutsideGCDomain] [NoHeapAllocation] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe UIntPtr GetSize(Allocation *allocation); [OutsideGCDomain] [NoHeapAllocation] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe UIntPtr GetType(Allocation *allocation); [OutsideGCDomain] [NoHeapAllocation] [StackBound(128)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe UIntPtr SetOwnerProcessId(Allocation *allocation, int processId); #endif // ROUTE_INDIRECTION_THROUGH_KERNEL [OutsideGCDomain] [NoHeapAllocation] [StackBound(1024)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe Allocation *Allocate(UIntPtr size, SystemType type, uint alignment); /// true if last reference was freed [OutsideGCDomain] [NoHeapAllocation] [StackBound(960)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe bool Free(Allocation *allocation); [OutsideGCDomain] [NoHeapAllocation] [StackBound(960)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe Allocation *Share(Allocation *allocation, UIntPtr startOffset, UIntPtr endOffset); [OutsideGCDomain] [NoHeapAllocation] [StackBound(960)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe Allocation *Split(Allocation *allocation, UIntPtr offset); [OutsideGCDomain] [NoHeapAllocation] [StackBound(960)] [MethodImpl(MethodImplOptions.InternalCall)] public static extern unsafe void Truncate(Allocation *allocation, UIntPtr offset); #if NOT_YET [OutsideGCDomain] [NoHeapAllocation] [StackBound(256)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe void TransferTo( Allocation *allocation, AllocationOwnerId newOwner); [OutsideGCDomain] [NoHeapAllocation] [StackBound(256)] [MethodImpl(MethodImplOptions.InternalCall)] public static unsafe void TransferFrom( Allocation *allocation, AllocationOwnerId oldOwner); #endif } }