From 0d5ce2797eb695aee7e019e25323251ef6ffc277 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 25 Feb 2020 08:48:42 -0800 Subject: Export of internal Abseil changes -- 20405fc394419d434d3ea09b2e62e4edcb282421 by Christian Blichmann : Include `status` subdirectory in main `CMakeLists.txt` PiperOrigin-RevId: 297125966 -- 101087af9689612bdda679ee0869e5cde4472244 by Matt Kulukundis : Fix typo PiperOrigin-RevId: 296991360 -- 55ff5bc6970d46214c0459d3a7a23973c7dc69b9 by Andy Getzendanner : Extract logging's ErrnoSaver to absl::base_internal and use it in a couple other places. PiperOrigin-RevId: 296969168 -- b7cd7550297d53766576f751436617200c65831b by Abseil Team : Internal change PiperOrigin-RevId: 296951474 -- 8c04c73fc53f9a09c3e2400812b931157f35fe07 by Andy Soffer : Auto-generate list of files in the DLL, and add new build targets to the DLL. PiperOrigin-RevId: 296932061 -- 2f77829e196094f1addefd8ac2ac9e398c5b6100 by Andy Soffer : Fix bug introduced by DLL where we couldn't build shared libraries on non-windows platforms. Fixes #623 PiperOrigin-RevId: 296919347 -- b768163dbbff0c561b9dff0218a699e5e4fd33f3 by Abseil Team : typo: microprosessor PiperOrigin-RevId: 296904933 -- b185da0dac44c91855373f0723df9242cbfb3db3 by Matthew Brown : Internal cleanup PiperOrigin-RevId: 296509711 GitOrigin-RevId: 20405fc394419d434d3ea09b2e62e4edcb282421 Change-Id: I55c8eba6f353ceb337455ae144ab743ea21edbef --- absl/base/BUILD.bazel | 24 +++++++++++++++++++ absl/base/CMakeLists.txt | 25 +++++++++++++++++++ absl/base/attributes.h | 2 +- absl/base/internal/errno_saver.h | 43 +++++++++++++++++++++++++++++++++ absl/base/internal/errno_saver_test.cc | 44 ++++++++++++++++++++++++++++++++++ absl/base/internal/spinlock_linux.inc | 5 ++-- absl/base/internal/spinlock_posix.inc | 6 ++--- 7 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 absl/base/internal/errno_saver.h create mode 100644 absl/base/internal/errno_saver_test.cc (limited to 'absl/base') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index c6948a2..bae7942 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -40,6 +40,17 @@ cc_library( ], ) +cc_library( + name = "errno_saver", + hdrs = ["internal/errno_saver.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [":config"], +) + cc_library( name = "log_severity", srcs = ["log_severity.cc"], @@ -87,6 +98,7 @@ cc_library( deps = [ ":base_internal", ":core_headers", + ":errno_saver", ], ) @@ -287,6 +299,18 @@ cc_test( ], ) +cc_test( + name = "errno_saver_test", + size = "small", + srcs = ["internal/errno_saver_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":errno_saver", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "exception_testing", testonly = 1, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index c21571b..14c52ea 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -28,6 +28,17 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} ) +absl_cc_library( + NAME + errno_saver + HDRS + "internal/errno_saver.h" + DEPS + absl::config + COPTS + ${ABSL_DEFAULT_COPTS} +) + absl_cc_library( NAME log_severity @@ -73,6 +84,7 @@ absl_cc_library( DEPS absl::base_internal absl::core_headers + absl::errno_saver ) absl_cc_library( @@ -305,6 +317,19 @@ absl_cc_test( gtest_main ) +absl_cc_test( + NAME + errno_saver_test + SRCS + "internal/errno_saver_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::errno_saver + gmock + gtest_main +) + absl_cc_test( NAME throw_delegate_test diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 8f77db7..ff13862 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -575,7 +575,7 @@ // When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the // natural alignment of structure members not annotated is preserved. Aligned // member accesses are faster than non-aligned member accesses even if the -// targeted microprosessor supports non-aligned accesses. +// targeted microprocessor supports non-aligned accesses. #if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) #else diff --git a/absl/base/internal/errno_saver.h b/absl/base/internal/errno_saver.h new file mode 100644 index 0000000..251de51 --- /dev/null +++ b/absl/base/internal/errno_saver.h @@ -0,0 +1,43 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ +#define ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ + +#include + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { + +// `ErrnoSaver` captures the value of `errno` upon construction and restores it +// upon deletion. It is used in low-level code and must be super fast. Do not +// add instrumentation, even in debug modes. +class ErrnoSaver { + public: + ErrnoSaver() : saved_errno_(errno) {} + ~ErrnoSaver() { errno = saved_errno_; } + int operator()() const { return saved_errno_; } + + private: + const int saved_errno_; +}; + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ diff --git a/absl/base/internal/errno_saver_test.cc b/absl/base/internal/errno_saver_test.cc new file mode 100644 index 0000000..b845e2d --- /dev/null +++ b/absl/base/internal/errno_saver_test.cc @@ -0,0 +1,44 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/internal/errno_saver.h" + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace { +using ::testing::Eq; + +struct ErrnoPrinter { + int no; +}; +std::ostream &operator<<(std::ostream &os, ErrnoPrinter ep) { + return os << strerror(ep.no) << " [" << ep.no << "]"; +} +bool operator==(ErrnoPrinter one, ErrnoPrinter two) { return one.no == two.no; } + +TEST(ErrnoSaverTest, Works) { + errno = EDOM; + { + absl::base_internal::ErrnoSaver errno_saver; + EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{EDOM})); + errno = ERANGE; + EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{ERANGE})); + EXPECT_THAT(ErrnoPrinter{errno_saver()}, Eq(ErrnoPrinter{EDOM})); + } + EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{EDOM})); +} +} // namespace diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index 28e29d1..323edd6 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -19,12 +19,12 @@ #include #include -#include #include #include #include #include "absl/base/attributes.h" +#include "absl/base/internal/errno_saver.h" // The SpinLock lockword is `std::atomic`. Here we assert that // `std::atomic` is bitwise equivalent of the `int` expected @@ -51,12 +51,11 @@ extern "C" { ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode) { - int save_errno = errno; + absl::base_internal::ErrnoSaver errno_saver; struct timespec tm; tm.tv_sec = 0; tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); - errno = save_errno; } ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w, diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index f025b5f..fcd21b1 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -15,10 +15,11 @@ // This file is a Posix-specific part of spinlock_wait.cc #include + #include #include -#include +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/scheduling_mode.h" #include "absl/base/port.h" @@ -27,7 +28,7 @@ extern "C" { ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( std::atomic* /* lock_word */, uint32_t /* value */, int loop, absl::base_internal::SchedulingMode /* mode */) { - int save_errno = errno; + absl::base_internal::ErrnoSaver errno_saver; if (loop == 0) { } else if (loop == 1) { sched_yield(); @@ -37,7 +38,6 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); nanosleep(&tm, nullptr); } - errno = save_errno; } ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( -- cgit v1.2.3