Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:31:55

0001 // Copyright 2023 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 
0016 #ifndef ABSL_SYNCHRONIZATION_INTERNAL_WAITER_BASE_H_
0017 #define ABSL_SYNCHRONIZATION_INTERNAL_WAITER_BASE_H_
0018 
0019 #include "absl/base/config.h"
0020 #include "absl/base/internal/thread_identity.h"
0021 #include "absl/synchronization/internal/kernel_timeout.h"
0022 
0023 namespace absl {
0024 ABSL_NAMESPACE_BEGIN
0025 namespace synchronization_internal {
0026 
0027 // `Waiter` is a platform specific semaphore implementation that `PerThreadSem`
0028 // waits on to implement blocking in `absl::Mutex`.  Implementations should
0029 // inherit from `WaiterCrtp` and must implement `Wait()`, `Post()`, and `Poke()`
0030 // as described in `WaiterBase`.  `waiter.h` selects the implementation and uses
0031 // static-dispatch for performance.
0032 class WaiterBase {
0033  public:
0034   WaiterBase() = default;
0035 
0036   // Not copyable or movable
0037   WaiterBase(const WaiterBase&) = delete;
0038   WaiterBase& operator=(const WaiterBase&) = delete;
0039 
0040   // Blocks the calling thread until a matching call to `Post()` or
0041   // `t` has passed. Returns `true` if woken (`Post()` called),
0042   // `false` on timeout.
0043   //
0044   // bool Wait(KernelTimeout t);
0045 
0046   // Restart the caller of `Wait()` as with a normal semaphore.
0047   //
0048   // void Post();
0049 
0050   // If anyone is waiting, wake them up temporarily and cause them to
0051   // call `MaybeBecomeIdle()`. They will then return to waiting for a
0052   // `Post()` or timeout.
0053   //
0054   // void Poke();
0055 
0056   // Returns the name of this implementation. Used only for debugging.
0057   //
0058   // static constexpr char kName[];
0059 
0060   // How many periods to remain idle before releasing resources
0061 #ifndef ABSL_HAVE_THREAD_SANITIZER
0062   static constexpr int kIdlePeriods = 60;
0063 #else
0064   // Memory consumption under ThreadSanitizer is a serious concern,
0065   // so we release resources sooner. The value of 1 leads to 1 to 2 second
0066   // delay before marking a thread as idle.
0067   static constexpr int kIdlePeriods = 1;
0068 #endif
0069 
0070  protected:
0071   static void MaybeBecomeIdle();
0072 };
0073 
0074 template <typename T>
0075 class WaiterCrtp : public WaiterBase {
0076  public:
0077   // Returns the Waiter associated with the identity.
0078   static T* GetWaiter(base_internal::ThreadIdentity* identity) {
0079     static_assert(
0080         sizeof(T) <= sizeof(base_internal::ThreadIdentity::WaiterState),
0081         "Insufficient space for Waiter");
0082     return reinterpret_cast<T*>(identity->waiter_state.data);
0083   }
0084 };
0085 
0086 }  // namespace synchronization_internal
0087 ABSL_NAMESPACE_END
0088 }  // namespace absl
0089 
0090 #endif  // ABSL_SYNCHRONIZATION_INTERNAL_WAITER_BASE_H_