MCPcopy Create free account
hub / github.com/apache/arrow / MemoryAdviseWillNeed

Function MemoryAdviseWillNeed

cpp/src/arrow/util/io_util.cc:1496–1559  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1494}
1495
1496Status MemoryAdviseWillNeed(const std::vector<MemoryRegion>& regions) {
1497#ifndef __EMSCRIPTEN__
1498 const auto page_size = static_cast<size_t>(GetPageSize());
1499 DCHECK_GT(page_size, 0);
1500 const size_t page_mask = ~(page_size - 1);
1501 DCHECK_EQ(page_mask & page_size, page_size);
1502
1503 auto align_region = [=](const MemoryRegion& region) -> MemoryRegion {
1504 const auto addr = reinterpret_cast<uintptr_t>(region.addr);
1505 const auto aligned_addr = addr & page_mask;
1506 DCHECK_LT(addr - aligned_addr, page_size);
1507 return {reinterpret_cast<void*>(aligned_addr),
1508 region.size + static_cast<size_t>(addr - aligned_addr)};
1509 };
1510
1511# ifdef _WIN32
1512 // PrefetchVirtualMemory() is available on Windows 8 or later
1513 struct PrefetchEntry { // Like WIN32_MEMORY_RANGE_ENTRY
1514 void* VirtualAddress;
1515 size_t NumberOfBytes;
1516
1517 PrefetchEntry(const MemoryRegion& region) // NOLINT runtime/explicit
1518 : VirtualAddress(region.addr), NumberOfBytes(region.size) {}
1519 };
1520 using PrefetchVirtualMemoryFunc = BOOL (*)(HANDLE, ULONG_PTR, PrefetchEntry*, ULONG);
1521 static const auto prefetch_virtual_memory = reinterpret_cast<PrefetchVirtualMemoryFunc>(
1522 GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "PrefetchVirtualMemory"));
1523 if (prefetch_virtual_memory != nullptr) {
1524 std::vector<PrefetchEntry> entries;
1525 entries.reserve(regions.size());
1526 for (const auto& region : regions) {
1527 if (region.size != 0) {
1528 entries.emplace_back(align_region(region));
1529 }
1530 }
1531 if (!entries.empty() &&
1532 !prefetch_virtual_memory(GetCurrentProcess(),
1533 static_cast<ULONG_PTR>(entries.size()), entries.data(),
1534 0)) {
1535 return IOErrorFromWinError(GetLastError(), "PrefetchVirtualMemory failed");
1536 }
1537 }
1538 return Status::OK();
1539# elif defined(POSIX_MADV_WILLNEED)
1540 for (const auto& region : regions) {
1541 if (region.size != 0) {
1542 const auto aligned = align_region(region);
1543 int err = posix_madvise(aligned.addr, aligned.size, POSIX_MADV_WILLNEED);
1544 // EBADF can be returned on Linux in the following cases:
1545 // - the kernel version is older than 3.9
1546 // - the kernel was compiled with CONFIG_SWAP disabled (ARROW-9577)
1547 if (err != 0 && err != EBADF) {
1548 return IOErrorFromErrno(err, "posix_madvise failed");
1549 }
1550 }
1551 }
1552 return Status::OK();
1553# else

Callers 4

WillNeedMethod · 0.85
ReadAtMethod · 0.85
WillNeedMethod · 0.85
TESTFunction · 0.85

Calls 9

GetPageSizeFunction · 0.85
IOErrorFromWinErrorFunction · 0.85
IOErrorFromErrnoFunction · 0.85
emplace_backMethod · 0.80
OKFunction · 0.50
reserveMethod · 0.45
sizeMethod · 0.45
emptyMethod · 0.45
dataMethod · 0.45

Tested by 1

TESTFunction · 0.68