Windows call buffer without copying

In the Ring Buffer Wikipedia entry , there is an example code showing hacks for UNIX , in which the neighboring virtual memory with a piece of memory is mapped in the same phbysical memory, thereby implementing a ring buffer without the need for memcpy , etc. I was wondering if there is a way to do something like this on Windows ?

Thanks Fraser

+6
c windows memory circular-buffer
source share
2 answers

I really did not follow all the details of the example on Wikipedia. With this in mind, you map memory in Windows using CreateFileMapping and MapViewOfFile , however MapViewOfFile does not allow you to specify a base address for mapping. MapViewOfFileEx can be used to specify a base address, so perhaps you can use a similar method.

I can’t say if this really works:

// determine valid buffer size SYSTEM_INFO info; GetSystemInfo(&info); // note that the base address must be a multiple of the allocation granularity DWORD bufferSize=info.dwAllocationGranularity; HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, bufferSize*2, L"Mapping"); BYTE *pBuf = (BYTE*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize); MapViewOfFileEx(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize, pBuf+bufferSize); 
+9
source share

Oh hey, this is a topic that has been of great concern to me lately. I need optimized ring buffer poses on Windows, mainly because of its random access interface, but I never knew how to implement it. Now the code suggested by @ 1800 INFORMATION sometimes works, sometimes it’s not, but the idea is great anyway.

The fact is that MapViewOfFileEx sometimes fails with ERROR_INVALID_ADDRESS, which means that it cannot match the view with pBuf+bufferSize . This is because the called MapViewOfFile call selects a free address space of length bufferSize (starting with pBuf ), but this does not guarantee that this address space must be bufferSize*2 long. And why do we need bufferSize*2 virtual memory? Because our ring buffer needs to be wrapped. This is what the second mapping is required for. When a read or write pointer leaves the first view, it enters the second view (because it is contiguous in memory), but in fact it starts with the same display.

 UINT_PTR addr; HANDLE hMapFile; LPVOID address, address2; hMapFile = CreateFileMapping ( // create a mapping backed by a pagefile INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, bufferSize*2, "Local\\mapping" ); if(hMapFile == NULL) FAIL(CreateFileMapping); address = MapViewOfFile ( // find a free bufferSize*2 address space hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize*2 ); if(address==NULL) FAIL(MapViewOfFile); UnmapViewOfFile(address); // found it. hopefully it'll remain free while we map to it addr = ((UINT_PTR)address); address = MapViewOfFileEx ( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize, (LPVOID)addr ); addr = ((UINT_PTR)address) + bufferSize; address2 = MapViewOfFileEx ( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize, (LPVOID)addr); if(address2==NULL) FAIL(MapViewOfFileEx); // when you're done with your ring buffer, call UnmapViewOfFile for // address and address2 and CloseHandle(hMapFile) 
+5
source share

All Articles