Как сделать Raw IO на Mac OS X? (то есть эквивалент флага Linux O_DIRECT)

У меня был googling для способа сделать raw (иногда называемый прямым) i/o под mac os. Необработанные очереди ввода/вывода кеша страницы операционной системы, чтобы предоставить приложению более прямой доступ к диску. Это полезно, потому что некоторые из используемой мной файловой структуры неэффективны при использовании замены страницы LRU. Довольно просто реализовать алгоритмы замены страниц, которые нам нужны, но сначала нам нужно отключить буферизацию os x по умолчанию. Мы уже это сделали в Linux, используя флаг O_DIRECT при открытии файлов. Кто-нибудь знает, как отключить буферизацию страницы в mac os?

Приветствия Тим

Ответы

Ответ 1

После того, как я прочитал несколько страниц, я наконец нашел идеальный ответ. Оказывается, mac os на самом деле имеет очень похожий механизм на O_DIRECT, однако он не через открытую функцию через fcntl. В частности, есть опция F_NOCACHE, которая позволяет включать или отключать кеш для определенного файлового дескриптора, который именно то, что я хотел. См. http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/fcntl.2.html для полного прогона других вещей, которые вы можете сделать с Mac-версией fcntl, и объяснением ее точного использования. Надеюсь, этот ответ поможет кому-то другому.


http://lists.apple.com/archives/filesystem-dev/2007/Sep/msg00010.html Это хороший поток, который объясняет, как ведет себя флаг F_NOCACHE в зависимости от вашего номера версии Mac OS.


Итоговый код (в go):

    r1, r2, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(self.file.Fd()), syscall.F_NOCACHE, 1)
    if err != 0 {
        fmt.Printf("Syscall to SYS_FCNTL failed\n\tr1=%v, r2=%v, err=%v\n", r1, r2, err)
        self.Close()
        return false
    }

Ответ 2

Вы можете использовать системный вызов madvise. Вы можете дать подсказкам ядру, что о том, какие страницы нужно сначала очистить, используя MADV_DONTNEED или MADV_WILLNEED. OS X также поддерживает флаг mmap MAP_NOCACHE, который инструктирует ядро ​​сначала отказаться от результирующих страниц.

Ответ 3

Вам нужно использовать open вместо fopen, и я считаю, что у вас действительно есть необработанный доступ, который вы должны прочитать из /dev/rdisk? непосредственно.