Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How reliable is page write-tracking in Windows given processor caches

Does ::GetWriteWatch always give an up to date list of modified pages? Or is it possible, because of processor caches, that some pages are still considered unmodified because cached writes have not been flushed to main memory?


Consider the following snippet of C++ code:

auto ptr = ::VirtualAlloc(NULL, 8192, MEM_COMMIT | MEM_RESERVE, MEM_WRITE_WATCH);
auto num = new (ptr) int{};
::ResetWriteWatch(ptr, 8192);

// ... calculations that involve writing to 'num' ...

::GetWriteWatch(/* ... */);

This should reserve and commit two pages of virtual memory, modify the first page, and finally request all modified pages.

Is it guaranteed that the first page is listed as modified by the call to ::GetWriteWatch?

like image 564
Maarten Bamelis Avatar asked Jun 27 '19 15:06

Maarten Bamelis


2 Answers

The blunt answer is assumed Yes .

While the documentation doesn't give an explicit guarentee, it can be assumed since it is dealing with MMU and CPU and low level memory management. This works as the rest of API: see creating guard pages etc. Taken together, all these guard and protect features of the API wouldn't be half as usefull as they actual are if you couldn't count on them being precise down to the instruction causing the fault. That being said, how this is actually accomplished by OS/CPU/MMU/TLB/CACHE is somewhat in the dark to me- will update if I figure it out.

In your example, I would be more worried about the compiler/optimizer playing some trick on you- so perhaps take a look at the generated assembly and see where the actual write is.

like image 76
darune Avatar answered Oct 09 '22 08:10

darune


It's no coincidence that a write watch operates at page granularity. That's because this handled at CPU level, via the Page Table for the MMU. I can't find an authoritative source, but I understand that this works via the read-only page attribute. A watched page is read-only, but the soft page fault when writing is handled by adding the watched page to the modified list.

As such, stale data in processor caches are irrelevant. This is handled at MMU level, and the MMU is closely coupled to caches anyway.

I'd be more worried about race conditions, because those appear at C++ level. A write to the watched page could happen from another thread even as GetWriteWatch is running.

like image 7
MSalters Avatar answered Oct 09 '22 06:10

MSalters