fix some bugs in MapHeap that were breaking libsnes savestates
This commit is contained in:
parent
baf7a7973b
commit
0bcdeee1e7
|
@ -142,13 +142,15 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
private Bin GetBinForEndPageEnsureAllocated(int page, Bin start)
|
private Bin GetBinForEndPageEnsureAllocated(int page, Bin start)
|
||||||
{
|
{
|
||||||
Bin curr = start;
|
Bin curr = start;
|
||||||
while (curr != null && curr.StartPage + curr.PageCount < page)
|
while (curr != null)
|
||||||
{
|
{
|
||||||
if (curr.Free)
|
if (curr.Free)
|
||||||
return null;
|
return null;
|
||||||
|
if (curr.EndPage >= page)
|
||||||
|
return curr;
|
||||||
curr = curr.Next;
|
curr = curr.Next;
|
||||||
}
|
}
|
||||||
return curr;
|
return curr; // ran off the end
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Map(ulong size, MemoryBlock.Protection prot)
|
public ulong Map(ulong size, MemoryBlock.Protection prot)
|
||||||
|
@ -184,6 +186,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
Memory.Protect(ret, totalSize, prot);
|
Memory.Protect(ret, totalSize, prot);
|
||||||
Used += totalSize;
|
Used += totalSize;
|
||||||
Console.WriteLine($"Allocated {totalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
Console.WriteLine($"Allocated {totalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
||||||
|
//EnsureUsedInternal();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +238,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
Used += newTotalSize;
|
Used += newTotalSize;
|
||||||
Used -= oldTotalSize;
|
Used -= oldTotalSize;
|
||||||
Console.WriteLine($"Reallocated from {oldTotalSize} bytes to {newTotalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
Console.WriteLine($"Reallocated from {oldTotalSize} bytes to {newTotalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
||||||
|
//EnsureUsedInternal();
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
// could not increase in place, so move
|
// could not increase in place, so move
|
||||||
|
@ -260,6 +264,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
ss.CopyTo(ds);
|
ss.CopyTo(ds);
|
||||||
Memory.Protect(ret, oldSize, oldStartBin.Protection);
|
Memory.Protect(ret, oldSize, oldStartBin.Protection);
|
||||||
UnmapPagesInternal(oldStartPage, oldNumPages, oldStartBin);
|
UnmapPagesInternal(oldStartPage, oldNumPages, oldStartBin);
|
||||||
|
//EnsureUsedInternal();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -272,6 +277,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
// shrink in place
|
// shrink in place
|
||||||
var s = GetBinForStartPage(newEndPage);
|
var s = GetBinForStartPage(newEndPage);
|
||||||
UnmapPagesInternal(newEndPage, oldEndPage - newEndPage, s);
|
UnmapPagesInternal(newEndPage, oldEndPage - newEndPage, s);
|
||||||
|
//EnsureUsedInternal();
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -309,12 +315,12 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
|
|
||||||
var endPage = startPage + numPages;
|
var endPage = startPage + numPages;
|
||||||
Bin freeBin = startBin;
|
Bin freeBin = startBin;
|
||||||
if (!freeBin.Free && freeBin.StartPage != startPage)
|
if (freeBin.StartPage != startPage)
|
||||||
{
|
{
|
||||||
freeBin.Cleave(startPage - freeBin.StartPage);
|
freeBin.Cleave(startPage - freeBin.StartPage);
|
||||||
freeBin = freeBin.Next;
|
freeBin = freeBin.Next;
|
||||||
freeBin.Free = true;
|
|
||||||
}
|
}
|
||||||
|
freeBin.Free = true;
|
||||||
MemoryBlock.Protection lastEaten = MemoryBlock.Protection.None;
|
MemoryBlock.Protection lastEaten = MemoryBlock.Protection.None;
|
||||||
while (freeBin.EndPage < endPage)
|
while (freeBin.EndPage < endPage)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +328,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
lastEaten = freeBin.Next.Protection;
|
lastEaten = freeBin.Next.Protection;
|
||||||
freeBin.Next = freeBin.Next.Next;
|
freeBin.Next = freeBin.Next.Next;
|
||||||
}
|
}
|
||||||
if (freeBin.Cleave(freeBin.EndPage - endPage))
|
if (freeBin.Cleave(endPage - freeBin.StartPage))
|
||||||
{
|
{
|
||||||
freeBin.Next.Protection = lastEaten;
|
freeBin.Next.Protection = lastEaten;
|
||||||
}
|
}
|
||||||
|
@ -331,6 +337,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
var totalSize = ((ulong)numPages) << WaterboxUtils.PageShift;
|
var totalSize = ((ulong)numPages) << WaterboxUtils.PageShift;
|
||||||
Used -= totalSize;
|
Used -= totalSize;
|
||||||
Console.WriteLine($"Freed {totalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
Console.WriteLine($"Freed {totalSize} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
||||||
|
//EnsureUsedInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -342,6 +349,25 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ulong CalcUsedInternal()
|
||||||
|
{
|
||||||
|
ulong ret = 0;
|
||||||
|
var bin = _root;
|
||||||
|
while (bin != null)
|
||||||
|
{
|
||||||
|
if (!bin.Free)
|
||||||
|
ret += (ulong)bin.PageCount << WaterboxUtils.PageShift;
|
||||||
|
bin = bin.Next;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureUsedInternal()
|
||||||
|
{
|
||||||
|
if (Used != CalcUsedInternal())
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
public void SaveStateBinary(BinaryWriter bw)
|
public void SaveStateBinary(BinaryWriter bw)
|
||||||
{
|
{
|
||||||
bw.Write(Name);
|
bw.Write(Name);
|
||||||
|
@ -413,5 +439,43 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
||||||
|
|
||||||
_root = scratch.Next;
|
_root = scratch.Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StressTest()
|
||||||
|
{
|
||||||
|
var allocs = new Dictionary<ulong, ulong>();
|
||||||
|
var mmo = new MapHeap(0x36a00000000, 256 * 1024 * 1024, "ballsacks");
|
||||||
|
var rnd = new Random(12512);
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; i++)
|
||||||
|
{
|
||||||
|
ulong siz = (ulong)(rnd.Next(256 * 1024) + 384 * 1024);
|
||||||
|
siz = siz / 4096 * 4096;
|
||||||
|
var ptr = mmo.Map(siz, Waterbox.MemoryBlock.Protection.RW);
|
||||||
|
allocs.Add(ptr, siz);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
int idx = rnd.Next(allocs.Count);
|
||||||
|
var elt = allocs.ElementAt(idx);
|
||||||
|
mmo.Unmap(elt.Key, elt.Value);
|
||||||
|
allocs.Remove(elt.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; i++)
|
||||||
|
{
|
||||||
|
ulong siz = (ulong)(rnd.Next(256 * 1024) + 384 * 1024);
|
||||||
|
siz = siz / 4096 * 4096;
|
||||||
|
var ptr = mmo.Map(siz, Waterbox.MemoryBlock.Protection.RW);
|
||||||
|
allocs.Add(ptr, siz);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
int idx = rnd.Next(allocs.Count);
|
||||||
|
var elt = allocs.ElementAt(idx);
|
||||||
|
mmo.Unmap(elt.Key, elt.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue