9

I'm writing a benchmark tool in C++ where I want to clear the filesystem memory cache between experiments. I'm aware of the following console commands:

sync
echo 3 > /proc/sys/vm/drop_caches

My question is how can i do this programmatically directly within C++?

Any help is appreciated!

alk
  • 69,737
  • 10
  • 105
  • 255
Christian
  • 447
  • 1
  • 6
  • 10

3 Answers3

15

Something like this should do the trick:

int fd;
char* data = "3";

sync();
fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
write(fd, data, sizeof(char));
close(fd);
Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • 1
    This is a better answer because it includes a sync. Which is important because drop_caches is a *debugging* tool and it does not always get the data on disk before dropping it. – Zan Lynx Jul 25 '11 at 15:54
  • A better answer that what? Both of the answers I see include a `sync`. – James Kanze Jul 25 '11 at 16:12
  • If that's true then this is a bit dangerous - what happens if a process writes a file in the background? Is the data written between sync() and open() just lost? – Malvineous Jun 17 '12 at 12:33
  • 1
    @ZanLynx: drop_caches is non-destructive and will only free clean caches (ones that have not been synced to disk). Thus calling sync() before doesn't make the operation any more safe, but rather increases the number of caches that can be dropped. See: /usr/src/linux/Documentation/sysctl/vm.txt – kalaxy Oct 10 '12 at 22:40
  • @kalaxy: When I used to run -mm kernels in 2008 it was *definitely* not safe. – Zan Lynx Oct 10 '12 at 22:51
  • 1
    If drop_caches is unsafe, your kernel is bugged. No modern kernel will have a problem with this. – Ana Betts Oct 10 '12 at 23:50
  • You don't need `char *data="3";`. You can just use `write(fd, "3", 1);`. (`sizeof(char)` is required to be 1, but it's up to you whether writing `1` or `sizeof(char)` is clearer in that context. If you were going to do anything, maybe do `strlen("3")` or put the string in a `const char data[]` and take the sizeof that.) – Peter Cordes Jul 09 '17 at 08:52
14

Just write to it :

sync();

std::ofstream ofs("/proc/sys/vm/drop_caches");
ofs << "3" << std::endl;
slaphappy
  • 6,894
  • 3
  • 34
  • 59
1

A slightly better way is to sync just the file systems which contains your descriptors using syncfs(). Or even better, simply use fsync().

int fd = open(...);   // Open your files
write(...);           // Your write calls
fsync(fd);            // Sync your file
close(fd);            // Close them

fsync() can fail if your descriptor is invalid. Look for errno if it returns -1.

C--
  • 16,393
  • 6
  • 53
  • 60