From: Andrii Grynenko Date: Thu, 14 Apr 2016 04:30:45 +0000 (-0700) Subject: Fix GuardPageAllocator to do mprotect lazily X-Git-Tag: 2016.07.26~354 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a6692f12f127e17f97fedfd17ff2c7116f34eb51;p=folly.git Fix GuardPageAllocator to do mprotect lazily Summary:Currently GuargPageAllocator mmap's a memory block enough for 100 fiber stacks and then protects a bottom page for each stack. If FiberManager is used to process a single task, protecting 100 stacks doesn't make much sense, but is costly. This change makes sure we protect a bottom page of every stack the first time given stack is requested. Reviewed By: alikhtarov Differential Revision: D3139944 fb-gh-sync-id: d9d724eaa0e65a227eac1d09a33018e6cb098aae fbshipit-source-id: d9d724eaa0e65a227eac1d09a33018e6cb098aae --- diff --git a/folly/experimental/fibers/GuardPageAllocator.cpp b/folly/experimental/fibers/GuardPageAllocator.cpp index 0a732ae1..f4ff2015 100644 --- a/folly/experimental/fibers/GuardPageAllocator.cpp +++ b/folly/experimental/fibers/GuardPageAllocator.cpp @@ -64,8 +64,7 @@ class StackCache { /* Protect the bottommost page of every stack allocation */ for (size_t i = 0; i < kNumGuarded; ++i) { auto allocBegin = storage_ + allocSize_ * i; - freeList_.push_back(allocBegin); - PCHECK(0 == ::mprotect(allocBegin, pagesize(), PROT_NONE)); + freeList_.emplace_back(allocBegin, /* protected= */ false); } } @@ -79,7 +78,10 @@ class StackCache { return nullptr; } - auto p = freeList_.back(); + auto p = freeList_.back().first; + if (!freeList_.back().second) { + PCHECK(0 == ::mprotect(p, pagesize(), PROT_NONE)); + } freeList_.pop_back(); /* We allocate minimum number of pages required, plus a guard page. @@ -112,7 +114,7 @@ class StackCache { assert(as == allocSize_); assert((p - storage_) % allocSize_ == 0); - freeList_.push_back(p); + freeList_.emplace_back(p, /* protected= */ true); return true; } @@ -127,9 +129,9 @@ class StackCache { size_t allocSize_{0}; /** - * LIFO free list + * LIFO free list. Each pair contains stack pointer and protected flag. */ - std::vector freeList_; + std::vector> freeList_; static size_t pagesize() { static const size_t pagesize = sysconf(_SC_PAGESIZE); diff --git a/folly/experimental/fibers/test/FibersTest.cpp b/folly/experimental/fibers/test/FibersTest.cpp index f2c5ba97..4fe93645 100644 --- a/folly/experimental/fibers/test/FibersTest.cpp +++ b/folly/experimental/fibers/test/FibersTest.cpp @@ -1628,6 +1628,15 @@ BENCHMARK(FiberManagerBasicFiveAwaits, iters) { runBenchmark(5, iters); } +BENCHMARK(FiberManagerCreateDestroy, iters) { + for (size_t i = 0; i < iters; ++i) { + folly::EventBase evb; + auto& fm = folly::fibers::getFiberManager(evb); + fm.addTask([]() {}); + evb.loop(); + } +} + BENCHMARK(FiberManagerAllocateDeallocatePattern, iters) { static const size_t kNumAllocations = 10000;