1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.Runtime.InteropServices; 10 using System.Threading; 11 using Antmicro.Renode.Core; 12 using Antmicro.Migrant.Hooks; 13 using Antmicro.Migrant; 14 15 namespace Antmicro.Renode.Core 16 { 17 public sealed class SerializableMappedSegment : IMappedSegment, IDisposable 18 { SerializableMappedSegment(ulong size, ulong startingOffset)19 public SerializableMappedSegment(ulong size, ulong startingOffset) 20 { 21 Size = size; 22 StartingOffset = startingOffset; 23 MakeSegment(); 24 } 25 26 public IntPtr Pointer { get { return pointer; } } 27 28 public ulong StartingOffset { get; private set; } 29 30 public ulong Size { get; private set; } 31 Touch()32 public void Touch() 33 { 34 if(pointer != IntPtr.Zero) 35 { 36 return; 37 } 38 var sizeAsInt = checked((int)Size); 39 pointer = Marshal.AllocHGlobal(sizeAsInt); 40 var zeroBuf = new byte[sizeAsInt]; 41 Marshal.Copy(zeroBuf, 0, pointer, sizeAsInt); 42 } 43 Dispose()44 public void Dispose() 45 { 46 var oldPointer = Interlocked.Exchange(ref pointer, IntPtr.Zero); 47 if(oldPointer != IntPtr.Zero) 48 { 49 Marshal.FreeHGlobal(oldPointer); 50 } 51 } 52 53 [PreSerialization] PrepareBuffer()54 private void PrepareBuffer() 55 { 56 if(pointer == IntPtr.Zero) 57 { 58 return; 59 } 60 var sizeAsInt = checked((int)Size); 61 buffer = new byte[sizeAsInt]; 62 Marshal.Copy(pointer, buffer, 0, sizeAsInt); 63 } 64 65 [PostSerialization] DisposeBuffer()66 private void DisposeBuffer() 67 { 68 buffer = null; 69 } 70 71 [PostDeserialization] MakeSegment()72 private void MakeSegment() 73 { 74 if(pointer != IntPtr.Zero) 75 { 76 throw new InvalidOperationException("Unexpected non null pointer during initialization."); 77 } 78 if(buffer != null) 79 { 80 Touch(); 81 Marshal.Copy(buffer, 0, pointer, checked((int)Size)); 82 buffer = null; 83 } 84 } 85 86 [Transient] 87 private IntPtr pointer; 88 private byte[] buffer; 89 } 90 } 91 92