Commit a6692f12 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot 1

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
parent 7c17b38a
...@@ -64,8 +64,7 @@ class StackCache { ...@@ -64,8 +64,7 @@ class StackCache {
/* Protect the bottommost page of every stack allocation */ /* Protect the bottommost page of every stack allocation */
for (size_t i = 0; i < kNumGuarded; ++i) { for (size_t i = 0; i < kNumGuarded; ++i) {
auto allocBegin = storage_ + allocSize_ * i; auto allocBegin = storage_ + allocSize_ * i;
freeList_.push_back(allocBegin); freeList_.emplace_back(allocBegin, /* protected= */ false);
PCHECK(0 == ::mprotect(allocBegin, pagesize(), PROT_NONE));
} }
} }
...@@ -79,7 +78,10 @@ class StackCache { ...@@ -79,7 +78,10 @@ class StackCache {
return nullptr; 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(); freeList_.pop_back();
/* We allocate minimum number of pages required, plus a guard page. /* We allocate minimum number of pages required, plus a guard page.
...@@ -112,7 +114,7 @@ class StackCache { ...@@ -112,7 +114,7 @@ class StackCache {
assert(as == allocSize_); assert(as == allocSize_);
assert((p - storage_) % allocSize_ == 0); assert((p - storage_) % allocSize_ == 0);
freeList_.push_back(p); freeList_.emplace_back(p, /* protected= */ true);
return true; return true;
} }
...@@ -127,9 +129,9 @@ class StackCache { ...@@ -127,9 +129,9 @@ class StackCache {
size_t allocSize_{0}; size_t allocSize_{0};
/** /**
* LIFO free list * LIFO free list. Each pair contains stack pointer and protected flag.
*/ */
std::vector<unsigned char*> freeList_; std::vector<std::pair<unsigned char*, bool>> freeList_;
static size_t pagesize() { static size_t pagesize() {
static const size_t pagesize = sysconf(_SC_PAGESIZE); static const size_t pagesize = sysconf(_SC_PAGESIZE);
......
...@@ -1628,6 +1628,15 @@ BENCHMARK(FiberManagerBasicFiveAwaits, iters) { ...@@ -1628,6 +1628,15 @@ BENCHMARK(FiberManagerBasicFiveAwaits, iters) {
runBenchmark(5, 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) { BENCHMARK(FiberManagerAllocateDeallocatePattern, iters) {
static const size_t kNumAllocations = 10000; static const size_t kNumAllocations = 10000;
......
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