spinlock_wait.h
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
00016 #define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
00017 
00018 // Operations to make atomic transitions on a word, and to allow
00019 // waiting for those transitions to become possible.
00020 
00021 #include <stdint.h>
00022 #include <atomic>
00023 
00024 #include "absl/base/internal/scheduling_mode.h"
00025 
00026 namespace absl {
00027 namespace base_internal {
00028 
00029 // SpinLockWait() waits until it can perform one of several transitions from
00030 // "from" to "to".  It returns when it performs a transition where done==true.
00031 struct SpinLockWaitTransition {
00032   uint32_t from;
00033   uint32_t to;
00034   bool done;
00035 };
00036 
00037 // Wait until *w can transition from trans[i].from to trans[i].to for some i
00038 // satisfying 0<=i<n && trans[i].done, atomically make the transition,
00039 // then return the old value of *w.   Make any other atomic transitions
00040 // where !trans[i].done, but continue waiting.
00041 uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n,
00042                       const SpinLockWaitTransition trans[],
00043                       SchedulingMode scheduling_mode);
00044 
00045 // If possible, wake some thread that has called SpinLockDelay(w, ...). If
00046 // "all" is true, wake all such threads.  This call is a hint, and on some
00047 // systems it may be a no-op; threads calling SpinLockDelay() will always wake
00048 // eventually even if SpinLockWake() is never called.
00049 void SpinLockWake(std::atomic<uint32_t> *w, bool all);
00050 
00051 // Wait for an appropriate spin delay on iteration "loop" of a
00052 // spin loop on location *w, whose previously observed value was "value".
00053 // SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
00054 // or may wait for a delay that can be truncated by a call to SpinLockWake(w).
00055 // In all cases, it must return in bounded time even if SpinLockWake() is not
00056 // called.
00057 void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop,
00058                    base_internal::SchedulingMode scheduling_mode);
00059 
00060 // Helper used by AbslInternalSpinLockDelay.
00061 // Returns a suggested delay in nanoseconds for iteration number "loop".
00062 int SpinLockSuggestedDelayNS(int loop);
00063 
00064 }  // namespace base_internal
00065 }  // namespace absl
00066 
00067 // In some build configurations we pass --detect-odr-violations to the
00068 // gold linker.  This causes it to flag weak symbol overrides as ODR
00069 // violations.  Because ODR only applies to C++ and not C,
00070 // --detect-odr-violations ignores symbols not mangled with C++ names.
00071 // By changing our extension points to be extern "C", we dodge this
00072 // check.
00073 extern "C" {
00074 void AbslInternalSpinLockWake(std::atomic<uint32_t> *w, bool all);
00075 void AbslInternalSpinLockDelay(
00076     std::atomic<uint32_t> *w, uint32_t value, int loop,
00077     absl::base_internal::SchedulingMode scheduling_mode);
00078 }
00079 
00080 inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w,
00081                                               bool all) {
00082   AbslInternalSpinLockWake(w, all);
00083 }
00084 
00085 inline void absl::base_internal::SpinLockDelay(
00086     std::atomic<uint32_t> *w, uint32_t value, int loop,
00087     absl::base_internal::SchedulingMode scheduling_mode) {
00088   AbslInternalSpinLockDelay(w, value, loop, scheduling_mode);
00089 }
00090 
00091 #endif  // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15