/* * 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. */ // // Docs: https://fburl.com/fbcref_baton // #pragma once #include <assert.h> #include <errno.h> #include <stdint.h> #include <atomic> #include <thread> #include <folly/Likely.h> #include <folly/detail/AsyncTrace.h> #include <folly/detail/Futex.h> #include <folly/detail/MemoryIdler.h> #include <folly/portability/Asm.h> #include <folly/synchronization/AtomicUtil.h> #include <folly/synchronization/WaitOptions.h> #include <folly/synchronization/detail/Spin.h> namespace folly { /// A Baton allows a thread to block once and be awoken. Captures a /// single handoff, and during its lifecycle (from construction/reset /// to destruction/reset) a baton must either be post()ed and wait()ed /// exactly once each, or not at all. /// /// Baton includes no internal padding, and is only 4 bytes in size. /// Any alignment or padding to avoid false sharing is up to the user. /// /// This is basically a stripped-down semaphore that supports only a /// single call to sem_post and a single call to sem_wait. /// /// The non-blocking version (MayBlock == false) provides more speed /// by using only load acquire and store release operations in the /// critical path, at the cost of disallowing blocking. /// /// The current posix semaphore sem_t isn't too bad, but this provides /// a bit more speed, inlining, smaller size, a guarantee that /// the implementation won't change, and compatibility with /// DeterministicSchedule. A much more restrictive lifecycle allows for adding /// a bunch of assertions that can help to catch race conditions ahead of time. /// /// Baton post with MayBlock == false is async-signal-safe. /// When MayBlock == true, Baton post is async-signal-safe if /// Futex wake is so. /// /// @refcode folly/docs/examples/folly/synchronization/Baton.cpp /// template <bool MayBlock = true, template <typename> class Atom = std::atomic> class Baton { … }; } // namespace folly