コード例 #1
0
	void MemoryMappedFile::PrefetchRange( Range<const char*> memoryRange ) const {
#	if( WIN8_MEMORY_MAPPED_FILE_AVAILABLE )
		WIN32_MEMORY_RANGE_ENTRY	ranges[] = { { const_cast<char*>( memoryRange.first ), memoryRange.GetSize() } };

		PrefetchVirtualMemory( GetCurrentProcess(), _countof( ranges ), ranges, 0 );
#	else
		for( auto temp( memoryRange.Begin() ); temp < memoryRange.End(); temp += PrefetchStride ) {
		//	TODO: Is it possible to use prefetch instructions to avoid polluting the processor caches?
			register int readTarget = *reinterpret_cast<const int*>(temp);
		}
#	endif
	}
コード例 #2
0
ファイル: mmap.cpp プロジェクト: rockeet/nark-db
void*
mmap_load(const char* fname, size_t* fsize, bool writable, bool populate) {
#ifdef _MSC_VER
	LARGE_INTEGER lsize;
	HANDLE hFile = CreateFileA(fname
		, GENERIC_READ |(writable ? GENERIC_WRITE : 0)
		, FILE_SHARE_DELETE | FILE_SHARE_READ | (writable ? FILE_SHARE_WRITE : 0)
		, NULL // lpSecurityAttributes
		, writable ? OPEN_ALWAYS : OPEN_EXISTING
		, FILE_ATTRIBUTE_NORMAL
		, NULL // hTemplateFile 
		);
	if (INVALID_HANDLE_VALUE == hFile) {
		DWORD err = GetLastError();
		THROW_STD(logic_error, "CreateFile(fname=%s).Err=%d(%X)"
			, fname, err, err);
	}
	if (writable) {
	//	bool isNewFile = GetLastError() != ERROR_ALREADY_EXISTS;
		bool isNewFile = GetLastError() == 0;
		if (isNewFile) {
			SetFilePointer(hFile, 8*1024, NULL, SEEK_SET);
			SetEndOfFile(hFile);
			SetFilePointer(hFile, 0, NULL, SEEK_SET);
		}
	}
	if (!GetFileSizeEx(hFile, &lsize)) {
		DWORD err = GetLastError();
		CloseHandle(hFile);
		THROW_STD(logic_error, "GetFileSizeEx(fname=%s).Err=%d(%X)"
			, fname, err, err);
	}
	if (lsize.QuadPart > size_t(-1)) {
		CloseHandle(hFile);
		THROW_STD(logic_error, "fname=%s fsize=%I64u(%I64X) too large"
			, fname, lsize.QuadPart, lsize.QuadPart);
	}
	*fsize = size_t(lsize.QuadPart);
	DWORD flProtect = writable ? PAGE_READWRITE : PAGE_READONLY;
	HANDLE hMmap = CreateFileMapping(hFile, NULL, flProtect, 0, 0, NULL);
	if (NULL == hMmap) {
		DWORD err = GetLastError();
		CloseHandle(hFile);
		THROW_STD(runtime_error, "CreateFileMapping(fname=%s).Err=%d(0x%X)"
			, fname, err, err);
	}
	DWORD desiredAccess = (writable ? FILE_MAP_WRITE : 0) | FILE_MAP_READ;
	void* base = MapViewOfFile(hMmap, desiredAccess, 0, 0, 0);
	if (NULL == base) {
		DWORD err = GetLastError();
		::CloseHandle(hMmap);
		::CloseHandle(hFile);
		THROW_STD(runtime_error, "MapViewOfFile(fname=%s).Err=%d(0x%X)"
			, fname, err, err);
	}
	if (populate) {
		WIN32_MEMORY_RANGE_ENTRY vm;
		vm.VirtualAddress = base;
		vm.NumberOfBytes  = *fsize;
		PrefetchVirtualMemory(GetCurrentProcess(), 1, &vm, 0);
	}
	::CloseHandle(hMmap); // close before UnmapViewOfFile is OK
	::CloseHandle(hFile);
#else
	int openFlags = writable ? O_RDWR : O_RDONLY;
	int fd = ::open(fname, openFlags);
	if (fd < 0) {
		int err = errno;
		THROW_STD(logic_error, "open(fname=%s, %s) = %d(%X): %s"
			, fname, writable ? "O_RDWR" : "O_RDONLY"
			, err, err, strerror(err));
	}
	struct stat st;
	if (::fstat(fd, &st) < 0) {
		THROW_STD(logic_error, "stat(fname=%s) = %s", fname, strerror(errno));
	}
	*fsize = st.st_size;
	int flProtect = (writable ? PROT_WRITE : 0) | PROT_READ;
	int flags = MAP_SHARED | (populate ? MAP_POPULATE : 0);
	void* base = ::mmap(NULL, st.st_size, flProtect, flags, fd, 0);
	if (MAP_FAILED == base) {
		::close(fd);
		THROW_STD(logic_error, "mmap(fname=%s, %s SHARED, size=%lld) = %s"
			, fname, writable ? "READWRITE" : "READ"
			, (long long)st.st_size, strerror(errno));
	}
	::close(fd);
#endif
	return base;
}