From c17a113eea230c21a1a8f4c4c086721ff59130da Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Tue, 19 Jul 2016 14:38:12 -0700 Subject: [PATCH] Make the mprotect variant of asymmetricHeavyBarrier work when mlock fails Summary: [Folly] Make the `mprotect` variant of `asymmetricHeavyBarrier` work when `mlock` fails. Reviewed By: djwatson Differential Revision: D3585948 fbshipit-source-id: c3a46884434b7f9da9caa9cf203573f9e3ce7444 --- folly/experimental/AsymmetricMemoryBarrier.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/folly/experimental/AsymmetricMemoryBarrier.cpp b/folly/experimental/AsymmetricMemoryBarrier.cpp index 31c34cb7..c5a5d2b8 100644 --- a/folly/experimental/AsymmetricMemoryBarrier.cpp +++ b/folly/experimental/AsymmetricMemoryBarrier.cpp @@ -42,16 +42,18 @@ struct DummyPageCreator { auto ptr = mmap(nullptr, 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); checkUnixError(reinterpret_cast(ptr), "mmap"); - // Lock the memory so it can't get paged out. If it gets paged out, changing - // its protection won't accomplish anything. + // Optimistically try to lock the page so it stays resident. Could make + // the heavy barrier faster. auto r = mlock(ptr, 1); - checkUnixError(r, "mlock"); + if (r != 0) { + // Do nothing. + } return ptr; } }; -// Make sure dummy page is always initialized before shutdown +// Make sure dummy page is always initialized before shutdown. DummyPageCreator dummyPageCreator; void mprotectMembarrier() { @@ -63,9 +65,17 @@ void mprotectMembarrier() { std::lock_guard lg(*mprotectMutex); int r = 0; + + // We want to downgrade the page while it is resident. To do that, it must + // first be upgraded and forced to be resident. r = mprotect(dummyPage, 1, PROT_READ | PROT_WRITE); checkUnixError(r, "mprotect"); + // Force the page to be resident. If it is already resident, almost no-op. + *static_cast(dummyPage) = 0; + + // Downgrade the page. Forces a memory barrier in every core running any + // of the process's threads. On a sane platform. r = mprotect(dummyPage, 1, PROT_READ); checkUnixError(r, "mprotect"); } -- 2.34.1