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 {
/* 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<unsigned char*> freeList_;
std::vector<std::pair<unsigned char*, bool>> freeList_;
static size_t pagesize() {
static const size_t pagesize = sysconf(_SC_PAGESIZE);
......
......@@ -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;
......
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