Skip to content

Instantly share code, notes, and snippets.

@DmitryOlshansky
Created June 11, 2014 16:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmitryOlshansky/5e32057e047425480f0e to your computer and use it in GitHub Desktop.
Save DmitryOlshansky/5e32057e047425480f0e to your computer and use it in GitHub Desktop.
Play with Windows MM-functions for potential use in concurrent GC
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