|
||||
File indexing completed on 2025-01-30 09:31:55
0001 // Copyright 2017 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 // PerThreadSem is a low-level synchronization primitive controlling the 0017 // runnability of a single thread, used internally by Mutex and CondVar. 0018 // 0019 // This is NOT a general-purpose synchronization mechanism, and should not be 0020 // used directly by applications. Applications should use Mutex and CondVar. 0021 // 0022 // The semantics of PerThreadSem are the same as that of a counting semaphore. 0023 // Each thread maintains an abstract "count" value associated with its identity. 0024 0025 #ifndef ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ 0026 #define ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ 0027 0028 #include <atomic> 0029 0030 #include "absl/base/internal/thread_identity.h" 0031 #include "absl/synchronization/internal/create_thread_identity.h" 0032 #include "absl/synchronization/internal/kernel_timeout.h" 0033 0034 namespace absl { 0035 ABSL_NAMESPACE_BEGIN 0036 0037 class Mutex; 0038 0039 namespace synchronization_internal { 0040 0041 class PerThreadSem { 0042 public: 0043 PerThreadSem() = delete; 0044 PerThreadSem(const PerThreadSem&) = delete; 0045 PerThreadSem& operator=(const PerThreadSem&) = delete; 0046 0047 // Routine invoked periodically (once a second) by a background thread. 0048 // Has no effect on user-visible state. 0049 static void Tick(base_internal::ThreadIdentity* identity); 0050 0051 // --------------------------------------------------------------------------- 0052 // Routines used by autosizing threadpools to detect when threads are 0053 // blocked. Each thread has a counter pointer, initially zero. If non-zero, 0054 // the implementation atomically increments the counter when it blocks on a 0055 // semaphore, a decrements it again when it wakes. This allows a threadpool 0056 // to keep track of how many of its threads are blocked. 0057 // SetThreadBlockedCounter() should be used only by threadpool 0058 // implementations. GetThreadBlockedCounter() should be used by modules that 0059 // block threads; if the pointer returned is non-zero, the location should be 0060 // incremented before the thread blocks, and decremented after it wakes. 0061 static void SetThreadBlockedCounter(std::atomic<int> *counter); 0062 static std::atomic<int> *GetThreadBlockedCounter(); 0063 0064 private: 0065 // Create the PerThreadSem associated with "identity". Initializes count=0. 0066 // REQUIRES: May only be called by ThreadIdentity. 0067 static inline void Init(base_internal::ThreadIdentity* identity); 0068 0069 // Increments "identity"'s count. 0070 static inline void Post(base_internal::ThreadIdentity* identity); 0071 0072 // Waits until either our count > 0 or t has expired. 0073 // If count > 0, decrements count and returns true. Otherwise returns false. 0074 // !t.has_timeout() => Wait(t) will return true. 0075 static inline bool Wait(KernelTimeout t); 0076 0077 // Permitted callers. 0078 friend class PerThreadSemTest; 0079 friend class absl::Mutex; 0080 friend void OneTimeInitThreadIdentity(absl::base_internal::ThreadIdentity*); 0081 }; 0082 0083 } // namespace synchronization_internal 0084 ABSL_NAMESPACE_END 0085 } // namespace absl 0086 0087 // In some build configurations we pass --detect-odr-violations to the 0088 // gold linker. This causes it to flag weak symbol overrides as ODR 0089 // violations. Because ODR only applies to C++ and not C, 0090 // --detect-odr-violations ignores symbols not mangled with C++ names. 0091 // By changing our extension points to be extern "C", we dodge this 0092 // check. 0093 extern "C" { 0094 void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemInit)( 0095 absl::base_internal::ThreadIdentity* identity); 0096 void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)( 0097 absl::base_internal::ThreadIdentity* identity); 0098 bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)( 0099 absl::synchronization_internal::KernelTimeout t); 0100 void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPoke)( 0101 absl::base_internal::ThreadIdentity* identity); 0102 } // extern "C" 0103 0104 void absl::synchronization_internal::PerThreadSem::Init( 0105 absl::base_internal::ThreadIdentity* identity) { 0106 ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemInit)(identity); 0107 } 0108 0109 void absl::synchronization_internal::PerThreadSem::Post( 0110 absl::base_internal::ThreadIdentity* identity) { 0111 ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(identity); 0112 } 0113 0114 bool absl::synchronization_internal::PerThreadSem::Wait( 0115 absl::synchronization_internal::KernelTimeout t) { 0116 return ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(t); 0117 } 0118 0119 #endif // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |