diff --git a/extension/data_loader/mman.h b/extension/data_loader/mman.h index fb6fe4fd39b..a7a335961c8 100644 --- a/extension/data_loader/mman.h +++ b/extension/data_loader/mman.h @@ -17,6 +17,7 @@ #ifndef _WIN32 +#include #include #include @@ -53,6 +54,24 @@ ET_INLINE void madvise_pages_willneed_sequential(void* addr, size_t len) { ::madvise(addr, len, MADV_SEQUENTIAL); } +/** + * On Apple platforms, schedule kernel read-ahead on the file descriptor itself + * via fcntl(F_RDADVISE). This is more aggressive than madvise for cold starts: + * it brings pages into the unified buffer cache so first-touch faults are + * serviced from RAM instead of storage. No-op on non-Apple POSIX platforms. + */ +ET_INLINE void fcntl_rdadvise_apple(int fd, size_t file_size) { +#if defined(__APPLE__) + struct radvisory advice; + advice.ra_offset = 0; + advice.ra_count = static_cast(file_size); + ::fcntl(fd, F_RDADVISE, &advice); +#else + (void)fd; + (void)file_size; +#endif +} + #else #define NOMINMAX @@ -99,4 +118,12 @@ ET_INLINE void madvise_pages_willneed_sequential(void* addr, size_t len) { (void)len; } +/** + * No-op on Windows: F_RDADVISE is an Apple-specific fcntl command. + */ +ET_INLINE void fcntl_rdadvise_apple(int fd, size_t file_size) { + (void)fd; + (void)file_size; +} + #endif diff --git a/extension/data_loader/mmap_data_loader.cpp b/extension/data_loader/mmap_data_loader.cpp index b07c8dd7d62..dc9e1a615bf 100644 --- a/extension/data_loader/mmap_data_loader.cpp +++ b/extension/data_loader/mmap_data_loader.cpp @@ -251,6 +251,7 @@ Result MmapDataLoader::load( if (mlock_config_ == MlockConfig::UseMadvise) { madvise_pages_willneed_sequential(pages, map_size); + fcntl_rdadvise_apple(fd_, file_size_); } // The requested data is at an offset into the mapped pages.