Search code examples
c++visual-studiowinapiwindows-7file-mapping

MapViewOfFile and VirtualLock


Will the following code load data from file into system memory so that access to the resulting pointer will never block threads?

auto ptr = VirtualLock(MapViewOfFile(file_map, FILE_MAP_READ, high, low, size), size); // Map file to memory and wait for DMA transfer to finish.
int val0 = reinterpret_cast<int*>(ptr)[0]; // Will not block thread?
int val1 = reinterpret_cast<int*>(ptr)[size-4]; // Will not block thread?

VirtualUnlock(ptr);
UnmapViewOfFile(ptr);

EDIT:

Updated after Dammons answer.

auto ptr = MapViewOfFile(file_map, FILE_MAP_READ, high, low, size);

#pragma optimize("", off)
char dummy;
for(int n = 0; n < size; n += 4096)
    dummy = reinterpret_cast<char*>(ptr)[n];
#pragma optimize("", on)

int val0 = reinterpret_cast<int*>(ptr)[0]; // Will not block thread?
int val1 = reinterpret_cast<int*>(ptr)[size-4]; // Will not block thread?

UnmapViewOfFile(ptr);

Solution

  • If the file's size is less than the ridiculously small maximum working set size (or, if you have modified your working set size accordingly) then in theory yes. If you exceed your maximum working set size, VirtualLock will simply do nothing (that is, fail).

    (In practice, I've seen VirtualLock being rather... liberal... at interpreting what it's supposed to do as opposed to what it actually does, at least under Windows XP -- might be different under more modern versions)

    I've been trying similar things in the past, and I'm now simply touching all pages that I want in RAM with a simple for loop (reading one byte). This leaves no questions open and works, with the sole possible exception that a page might in theory get swapped out again after touched. In practice, this never happens (unless the machine is really really low on RAM, and then it's ok to happen).