Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
MemoryFailPoint.cs
Go to the documentation of this file.
1using System.IO;
4
5namespace System.Runtime;
6
8{
9 private static readonly ulong s_topOfMemory = GetTopOfMemory();
10
12
14
15 private static readonly ulong s_GCSegmentSize = GC.GetSegmentSize();
16
17 private static long s_failPointReservedMemory;
18
19 private readonly ulong _reservedMemory;
20
22
23 private static long LastKnownFreeAddressSpace
24 {
25 get
26 {
28 }
29 set
30 {
32 }
33 }
34
35 private static long LastTimeCheckingAddressSpace
36 {
37 get
38 {
40 }
41 set
42 {
44 }
45 }
46
48
49 private static void AddToLastKnownFreeAddressSpace(long addend)
50 {
52 }
53
54 public MemoryFailPoint(int sizeInMegabytes)
55 {
56 if (sizeInMegabytes <= 0)
57 {
59 }
60 ulong num = (_reservedMemory = (ulong)((long)sizeInMegabytes << 20));
61 ulong num2 = (ulong)(Math.Ceiling((double)num / (double)s_GCSegmentSize) * (double)s_GCSegmentSize);
62 if (num2 >= s_topOfMemory)
63 {
65 }
66 ulong num3 = (ulong)(Math.Ceiling((double)sizeInMegabytes / 16.0) * 16.0);
67 num3 <<= 20;
68 for (int i = 0; i < 3; i++)
69 {
70 if (!CheckForAvailableMemory(out var availPageFile, out var totalAddressSpaceFree))
71 {
72 return;
73 }
74 ulong memoryFailPointReservedMemory = MemoryFailPointReservedMemory;
75 ulong num4 = num2 + memoryFailPointReservedMemory;
76 bool flag = num4 < num2 || num4 < memoryFailPointReservedMemory;
77 bool flag2 = availPageFile < num3 + memoryFailPointReservedMemory + 16777216 || flag;
78 bool flag3 = totalAddressSpaceFree < num4 || flag;
79 long num5 = Environment.TickCount;
81 {
82 CheckForFreeAddressSpace(num2, shouldThrow: false);
83 }
84 bool flag4 = (ulong)LastKnownFreeAddressSpace < num2;
85 if (!flag2 && !flag3 && !flag4)
86 {
87 break;
88 }
89 switch (i)
90 {
91 case 0:
92 GC.Collect();
93 break;
94 case 1:
95 if (flag2)
96 {
97 UIntPtr numBytes = new UIntPtr(num2);
99 }
100 break;
101 case 2:
102 if (flag2 || flag3)
103 {
105 throw ex;
106 }
107 if (flag4)
108 {
110 throw ex2;
111 }
112 break;
113 }
114 }
115 AddToLastKnownFreeAddressSpace((long)(0L - num));
117 {
118 CheckForFreeAddressSpace(num2, shouldThrow: true);
119 }
122 }
123
125 {
126 Dispose(disposing: false);
127 }
128
129 public void Dispose()
130 {
131 Dispose(disposing: true);
132 GC.SuppressFinalize(this);
133 }
134
135 private void Dispose(bool disposing)
136 {
138 {
141 }
142 }
143
144 internal static long AddMemoryFailPointReservation(long size)
145 {
146 return Interlocked.Add(ref s_failPointReservedMemory, size);
147 }
148
149 private static ulong GetTopOfMemory()
150 {
151 Interop.Kernel32.GetSystemInfo(out var lpSystemInfo);
152 return (ulong)(long)lpSystemInfo.lpMaximumApplicationAddress;
153 }
154
155 private unsafe static bool CheckForAvailableMemory(out ulong availPageFile, out ulong totalAddressSpaceFree)
156 {
158 mEMORYSTATUSEX.dwLength = (uint)sizeof(Interop.Kernel32.MEMORYSTATUSEX);
159 if (Interop.Kernel32.GlobalMemoryStatusEx(&mEMORYSTATUSEX) == Interop.BOOL.FALSE)
160 {
161 availPageFile = 0uL;
162 totalAddressSpaceFree = 0uL;
163 return false;
164 }
165 availPageFile = mEMORYSTATUSEX.ullAvailPageFile;
166 totalAddressSpaceFree = mEMORYSTATUSEX.ullAvailVirtual;
167 return true;
168 }
169
170 private unsafe static void CheckForFreeAddressSpace(ulong size, bool shouldThrow)
171 {
172 ulong num2 = (ulong)(LastKnownFreeAddressSpace = (long)MemFreeAfterAddress(null, size));
174 if (num2 < size && shouldThrow)
175 {
177 }
178 }
179
180 private unsafe static ulong MemFreeAfterAddress(void* address, ulong size)
181 {
182 if (size >= s_topOfMemory)
183 {
184 return 0uL;
185 }
186 ulong num = 0uL;
188 UIntPtr dwLength = (UIntPtr)(ulong)sizeof(Interop.Kernel32.MEMORY_BASIC_INFORMATION);
189 while ((ulong)((long)address + (long)size) < s_topOfMemory)
190 {
191 UIntPtr uIntPtr = Interop.Kernel32.VirtualQuery(address, ref lpBuffer, dwLength);
192 if (uIntPtr == UIntPtr.Zero)
193 {
195 }
196 ulong num2 = lpBuffer.RegionSize.ToUInt64();
197 if (lpBuffer.State == 65536)
198 {
199 if (num2 >= size)
200 {
201 return num2;
202 }
203 num = Math.Max(num, num2);
204 }
205 address = (void*)((ulong)address + num2);
206 }
207 return num;
208 }
209
210 private unsafe static void GrowPageFileIfNecessaryAndPossible(UIntPtr numBytes)
211 {
212 void* ptr = Interop.Kernel32.VirtualAlloc(null, numBytes, 4096, 4);
213 if (ptr != null && !Interop.Kernel32.VirtualFree(ptr, UIntPtr.Zero, 32768))
214 {
216 }
217 }
218}
static UIntPtr VirtualQuery(SafeHandle lpAddress, ref MEMORY_BASIC_INFORMATION lpBuffer, UIntPtr dwLength)
static IntPtr VirtualAlloc(SafeHandle lpAddress, UIntPtr dwSize, int flAllocationType, int flProtect)
static void GetSystemInfo(out SYSTEM_INFO lpSystemInfo)
static unsafe bool VirtualFree(void *lpAddress, UIntPtr dwSize, int dwFreeType)
static unsafe BOOL GlobalMemoryStatusEx(MEMORYSTATUSEX *lpBuffer)
static int TickCount
static void SuppressFinalize(object obj)
Definition GC.cs:202
static ulong GetSegmentSize()
static void Collect(int generation)
Definition GC.cs:119
Definition GC.cs:8
static Exception GetExceptionForLastWin32Error(string path="")
static double Ceiling(double a)
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static unsafe void CheckForFreeAddressSpace(ulong size, bool shouldThrow)
static unsafe void GrowPageFileIfNecessaryAndPossible(UIntPtr numBytes)
static unsafe bool CheckForAvailableMemory(out ulong availPageFile, out ulong totalAddressSpaceFree)
static unsafe ulong MemFreeAfterAddress(void *address, ulong size)
static long AddMemoryFailPointReservation(long size)
static void AddToLastKnownFreeAddressSpace(long addend)
MemoryFailPoint(int sizeInMegabytes)
static long s_hiddenLastTimeCheckingAddressSpace
static readonly ulong s_topOfMemory
static readonly ulong s_GCSegmentSize
static string InsufficientMemory_MemFailPoint
Definition SR.cs:1366
static string InsufficientMemory_MemFailPoint_TooBig
Definition SR.cs:1368
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string InsufficientMemory_MemFailPoint_VAFrag
Definition SR.cs:1370
Definition SR.cs:7
static int Add(ref int location1, int value)
static bool Read(ref bool location)
Definition Volatile.cs:67
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
static readonly UIntPtr Zero
Definition UIntPtr.cs:19