Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/absl/base/internal/spinlock_linux.inc is written in an unsupported language. File is not indexed.

0001 // Copyright 2018 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 // This file is a Linux-specific part of spinlock_wait.cc
0016 
0017 #include <linux/futex.h>
0018 #include <sys/syscall.h>
0019 #include <unistd.h>
0020 
0021 #include <atomic>
0022 #include <climits>
0023 #include <cstdint>
0024 #include <ctime>
0025 
0026 #include "absl/base/attributes.h"
0027 #include "absl/base/internal/errno_saver.h"
0028 
0029 // The SpinLock lockword is `std::atomic<uint32_t>`. Here we assert that
0030 // `std::atomic<uint32_t>` is bitwise equivalent of the `int` expected
0031 // by SYS_futex. We also assume that reads/writes done to the lockword
0032 // by SYS_futex have rational semantics with regard to the
0033 // std::atomic<> API. C++ provides no guarantees of these assumptions,
0034 // but they are believed to hold in practice.
0035 static_assert(sizeof(std::atomic<uint32_t>) == sizeof(int),
0036               "SpinLock lockword has the wrong size for a futex");
0037 
0038 // Some Android headers are missing these definitions even though they
0039 // support these futex operations.
0040 #ifdef __BIONIC__
0041 #ifndef SYS_futex
0042 #define SYS_futex __NR_futex
0043 #endif
0044 #ifndef FUTEX_PRIVATE_FLAG
0045 #define FUTEX_PRIVATE_FLAG 128
0046 #endif
0047 #endif
0048 
0049 #if defined(__NR_futex_time64) && !defined(SYS_futex_time64)
0050 #define SYS_futex_time64 __NR_futex_time64
0051 #endif
0052 
0053 #if defined(SYS_futex_time64) && !defined(SYS_futex)
0054 #define SYS_futex SYS_futex_time64
0055 #endif
0056 
0057 extern "C" {
0058 
0059 ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
0060     std::atomic<uint32_t> *w, uint32_t value, int,
0061     absl::base_internal::SchedulingMode) {
0062   absl::base_internal::ErrnoSaver errno_saver;
0063   syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, nullptr);
0064 }
0065 
0066 ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(
0067     std::atomic<uint32_t> *w, bool all) {
0068   syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0);
0069 }
0070 
0071 }  // extern "C"