Fcntl F_nocache Option Not Working Properly



I am trying to use the fcntl F_NOCACHE option to disable OS caching of disk IO, but it appears that it does not work as expected under C++.

I have a simple test program that creates and writes a 200 MB file. On a Mac Mini this takes about 1.81 seconds for 110.4 MB/sec. I close the file.

I then open the file for reading, using the default options. The 200 MB file is read in 0.13 seconds for 1489.5 MB/sec. As expected, most of the file was still in memory. I close the file.

Then I open the file again, this time adding a fctl with the F_NOCACHE command set to 1. The file reads in 0.04 seconds for 5,655.79 MB/sec ... obviously coming from cache.

What am I doing incorrectly? I am using "int" arguments to fcntl just to be sure the word lengths are proper.

int fcntl_cmd = F_NOCACHE;
int fcntl_arg = 1;
errnum = fcntl(fh, fcntl_cmd, fcntl_arg);
if (errnum == -1) { <handle error>}

I have the complete example C++ source example I could post if it is useful. I am compiling with -Wall -Wconversion -Wformat -Wshorten-64-to-32 to catch possible incorrect casting from different word lengths and sign formats.

If I run the program using dtruss, and then search down the output for the fcntl call I find:

open("test1.dat\0", 0x0, 0x7FFF734D1638) = 3 0 <= opens the file returning file handle 3
fcntl(0x3, 0x30, 0x1) = 0 0 <= fcntl on file handle 3. command 0x30 = 48.
= F_NOCACHE, third argument is 1 (non-zero)
with no error.

So it seems that the proper arguments are being passed to the fcntl call.

The program is behaving as if the F_NOCACHE fctl option is being ignored. No fcntl call generates no error. Within the program, the value of F_NOCACHE is printed, and it is 48, which matches the sys/fntl.h header file.

I am running this on Mac OS X 10.9.5 Mavericks. The results are reproducible. I am using the c++ compiler. I can post the complete 336 line example program.

Any suggestions?

Dave B