/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <folly/fibers/GuardPageAllocator.h> #ifndef _WIN32 #include <dlfcn.h> #endif #include <csignal> #include <iostream> #include <mutex> #include <glog/logging.h> #include <folly/Singleton.h> #include <folly/SpinLock.h> #include <folly/Synchronized.h> #include <folly/portability/SysMman.h> #include <folly/portability/Unistd.h> namespace folly { namespace fibers { /** * Each stack with a guard page creates two memory mappings. * Since this is a limited resource, we don't want to create too many of these. * * The upper bound on total number of mappings created * is kNumGuarded * kMaxInUse. */ /** * Number of guarded stacks per allocator instance */ constexpr size_t kNumGuarded = …; /** * Maximum number of allocator instances with guarded stacks enabled */ constexpr size_t kMaxInUse = …; /** * A cache for kNumGuarded stacks of a given size * * Thread safe. */ class StackCache { … }; #ifndef _WIN32 namespace { struct sigaction oldSigsegvAction; FOLLY_NOINLINE void FOLLY_FIBERS_STACK_OVERFLOW_DETECTED( int signum, siginfo_t* info, void* ucontext) { … } void sigsegvSignalHandler(int signum, siginfo_t* info, void* ucontext) { … } bool isInJVM() { … } void installSignalHandler() { … } } // namespace #endif /* * RAII Wrapper around a StackCache that calls * CacheManager::giveBack() on destruction. */ class StackCacheEntry { … }; class CacheManager { … }; StackCacheEntry::~StackCacheEntry() { … } GuardPageAllocator::GuardPageAllocator(size_t guardPagesPerStack) : … { … } GuardPageAllocator::~GuardPageAllocator() = default; unsigned char* GuardPageAllocator::allocate(size_t size) { … } void GuardPageAllocator::deallocate(unsigned char* limit, size_t size) { … } } // namespace fibers } // namespace folly