|
||||
File indexing completed on 2024-11-15 09:00:52
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 #ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ 0016 #define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ 0017 0018 // Operations to make atomic transitions on a word, and to allow 0019 // waiting for those transitions to become possible. 0020 0021 #include <stdint.h> 0022 #include <atomic> 0023 0024 #include "absl/base/internal/scheduling_mode.h" 0025 0026 namespace absl { 0027 ABSL_NAMESPACE_BEGIN 0028 namespace base_internal { 0029 0030 // SpinLockWait() waits until it can perform one of several transitions from 0031 // "from" to "to". It returns when it performs a transition where done==true. 0032 struct SpinLockWaitTransition { 0033 uint32_t from; 0034 uint32_t to; 0035 bool done; 0036 }; 0037 0038 // Wait until *w can transition from trans[i].from to trans[i].to for some i 0039 // satisfying 0<=i<n && trans[i].done, atomically make the transition, 0040 // then return the old value of *w. Make any other atomic transitions 0041 // where !trans[i].done, but continue waiting. 0042 // 0043 // Wakeups for threads blocked on SpinLockWait do not respect priorities. 0044 uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, 0045 const SpinLockWaitTransition trans[], 0046 SchedulingMode scheduling_mode); 0047 0048 // If possible, wake some thread that has called SpinLockDelay(w, ...). If `all` 0049 // is true, wake all such threads. On some systems, this may be a no-op; on 0050 // those systems, threads calling SpinLockDelay() will always wake eventually 0051 // even if SpinLockWake() is never called. 0052 void SpinLockWake(std::atomic<uint32_t> *w, bool all); 0053 0054 // Wait for an appropriate spin delay on iteration "loop" of a 0055 // spin loop on location *w, whose previously observed value was "value". 0056 // SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick, 0057 // or may wait for a call to SpinLockWake(w). 0058 void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop, 0059 base_internal::SchedulingMode scheduling_mode); 0060 0061 // Helper used by AbslInternalSpinLockDelay. 0062 // Returns a suggested delay in nanoseconds for iteration number "loop". 0063 int SpinLockSuggestedDelayNS(int loop); 0064 0065 } // namespace base_internal 0066 ABSL_NAMESPACE_END 0067 } // namespace absl 0068 0069 // In some build configurations we pass --detect-odr-violations to the 0070 // gold linker. This causes it to flag weak symbol overrides as ODR 0071 // violations. Because ODR only applies to C++ and not C, 0072 // --detect-odr-violations ignores symbols not mangled with C++ names. 0073 // By changing our extension points to be extern "C", we dodge this 0074 // check. 0075 extern "C" { 0076 void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(std::atomic<uint32_t> *w, 0077 bool all); 0078 void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( 0079 std::atomic<uint32_t> *w, uint32_t value, int loop, 0080 absl::base_internal::SchedulingMode scheduling_mode); 0081 } 0082 0083 inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w, 0084 bool all) { 0085 ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(w, all); 0086 } 0087 0088 inline void absl::base_internal::SpinLockDelay( 0089 std::atomic<uint32_t> *w, uint32_t value, int loop, 0090 absl::base_internal::SchedulingMode scheduling_mode) { 0091 ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay) 0092 (w, value, loop, scheduling_mode); 0093 } 0094 0095 #endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |