Created
June 11, 2014 16:55
-
-
Save DmitryOlshansky/5e32057e047425480f0e to your computer and use it in GitHub Desktop.
Play with Windows MM-functions for potential use in concurrent GC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import core.sys.windows.windows, core.stdc.stdlib, | |
std.stdio, std.datetime; | |
//pragma(mangle, "_QueryWorkingSet@12") | |
extern(Windows) BOOL QueryWorkingSet(HANDLE hProcess,PVOID pv,DWORD cb); | |
void main() | |
{ | |
// map 512mb, obviously 32bit sucks, as I couldn't map more | |
uint SIZE = 2^^29; | |
auto mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, | |
null, PAGE_READWRITE | SEC_COMMIT, 0, SIZE, null); | |
assert(mapping != INVALID_HANDLE_VALUE); | |
void* heap = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, | |
0, 0, SIZE); | |
assert(heap); | |
//use the memory | |
for(size_t n = 0; n<SIZE; n += 4096) | |
{ | |
ubyte* p = cast(ubyte*)heap+n; | |
p[0] = 0xFF; | |
p[1] = 0xFF; | |
} | |
//"start collection" must stop threads here | |
//re-map as primary r-w view for GC ("stash" it) | |
void* heap2 = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, | |
0, 0, SIZE); | |
assert(heap2); | |
int code = UnmapViewOfFile(heap); | |
assert(code); | |
//remap as CoW for the app at the _same_ address | |
void* heap3 = MapViewOfFileEx(mapping, FILE_MAP_COPY, | |
0, 0, SIZE, heap); | |
assert(heap3 == heap); | |
//may unpause here | |
//do some changes, spoil 1 of 4 pages | |
for(size_t n = 0; n<SIZE; n += 4*4096) | |
{ | |
ubyte* p = cast(ubyte*)heap+n; //CoW view | |
ubyte* p2 = cast(ubyte*)heap2+n; //GC's original | |
assert(p[0] == 0xFF); | |
assert(p[1] == 0xFF); | |
p[0] = 0x1F; | |
assert(p2[0] == 0xFF); | |
} | |
MEMORY_BASIC_INFORMATION mem; | |
//this is "mark ended" phase time to collect, again pause | |
StopWatch sw; | |
size_t regions = 0; | |
sw.start(); | |
//version(VirtQ) | |
{ //walk the page ranges | |
for(size_t off = 0; off < SIZE;) | |
{ | |
size_t written = VirtualQuery(heap+off, &mem, mem.sizeof); | |
assert(written); | |
size_t size = mem.RegionSize; | |
regions++; | |
off += size; | |
//writefln("%08x:%08x (%d bytes)- flags %x", mem.BaseAddress, | |
// mem.BaseAddress+size, size, mem.AllocationProtect); | |
} | |
} | |
sw.stop(); | |
writefln("Checking pages (%d regions) took %d usec", | |
regions, sw.peek.usecs); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment