Commit 77e40a06 authored by Egor Pasko's avatar Egor Pasko Committed by Commit Bot

clear_system_cache: Sync dirty pages before ClearCacheForFile(s)

In http://crbug.com/881384#c2 I saw some more evidence that the page cache is
not fully flushed when benchmarking. On Linux/Android calling sync(2) syscall
before evicting individual files should help because the later pagecache
dropping operations become a lot cheaper for the kernel. I could not find good
documentation about sync(2) guarantees on MacOS.

The page cache flushing for individual files is still asynchronous, with no
cheap way to check that it happened. The plan is to sleep for one second after
such operations. Since we would prefer to sleep only once per bulk of
operations, the sleeping will be done on higher levels.

The Windows story is not covered - the operation requires administrator
privileges.

Bug: 811244
Change-Id: Ib71f4f934a0eb4b438bfedbbb50462e07ff64308
Reviewed-on: https://chromium-review.googlesource.com/1211602
Commit-Queue: Egor Pasko <pasko@chromium.org>
Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Reviewed-by: default avatarAlbert J. Wong <ajwong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590266}
parent 3cdeae87
...@@ -39,6 +39,11 @@ bool EvictFileFromSystemCacheWithRetry(const FilePath& file); ...@@ -39,6 +39,11 @@ bool EvictFileFromSystemCacheWithRetry(const FilePath& file);
// success. // success.
bool DieFileDie(const FilePath& file, bool recurse); bool DieFileDie(const FilePath& file, bool recurse);
// Synchronize all the dirty pages from the page cache to disk (on POSIX
// systems). The Windows analogy for this operation is to 'Flush file buffers'.
// Note: This is currently implemented as a no-op on Windows.
void SyncPageCacheToDisk();
// Clear a specific file from the system cache. After this call, trying // Clear a specific file from the system cache. After this call, trying
// to access this file will result in a cold load from the hard drive. // to access this file will result in a cold load from the hard drive.
bool EvictFileFromSystemCache(const FilePath& file); bool EvictFileFromSystemCache(const FilePath& file);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <stddef.h> #include <stddef.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include <string> #include <string>
...@@ -79,6 +80,11 @@ bool DieFileDie(const FilePath& file, bool recurse) { ...@@ -79,6 +80,11 @@ bool DieFileDie(const FilePath& file, bool recurse) {
return DeleteFile(file, recurse); return DeleteFile(file, recurse);
} }
void SyncPageCacheToDisk() {
// On Linux (and Android) the sync(2) call waits for I/O completions.
sync();
}
#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
bool EvictFileFromSystemCache(const FilePath& file) { bool EvictFileFromSystemCache(const FilePath& file) {
// There doesn't seem to be a POSIX way to cool the disk cache. // There doesn't seem to be a POSIX way to cool the disk cache.
......
...@@ -104,6 +104,12 @@ bool DieFileDie(const FilePath& file, bool recurse) { ...@@ -104,6 +104,12 @@ bool DieFileDie(const FilePath& file, bool recurse) {
return false; return false;
} }
void SyncPageCacheToDisk() {
// Approximating this with noop. The proper implementation would require
// administrator privilege:
// https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers
}
bool EvictFileFromSystemCache(const FilePath& file) { bool EvictFileFromSystemCache(const FilePath& file) {
base::win::ScopedHandle file_handle( base::win::ScopedHandle file_handle(
CreateFile(file.value().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CreateFile(file.value().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
......
...@@ -40,6 +40,11 @@ int main(int argc, const char* argv[]) { ...@@ -40,6 +40,11 @@ int main(int argc, const char* argv[]) {
return 1; return 1;
} }
// Synchronously eliminating the dirty pages from pagecache allows to
// minimize adhoc waiting after all of the per-file pagecache dropping is
// done.
base::SyncPageCacheToDisk();
if (base::DirectoryExists(path)) { if (base::DirectoryExists(path)) {
base::FileEnumerator enumerator(path, should_recurse, base::FileEnumerator enumerator(path, should_recurse,
base::FileEnumerator::FILES); base::FileEnumerator::FILES);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment