Merge pull request #18059 from soheilhy/worktree-cpp-atomic

Introduce more helper methods in gprpp/atomic.h
pull/18098/head
Soheil Hassas Yeganeh 6 years ago committed by GitHub
commit 2bb92f6a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      BUILD
  2. 2
      build.yaml
  3. 4
      gRPC-C++.podspec
  4. 4
      gRPC-Core.podspec
  5. 2
      grpc.gemspec
  6. 2
      package.xml
  7. 6
      src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
  8. 78
      src/core/lib/gprpp/atomic.h
  9. 57
      src/core/lib/gprpp/atomic_with_atm.h
  10. 35
      src/core/lib/gprpp/atomic_with_std.h
  11. 15
      src/core/lib/gprpp/ref_counted.h
  12. 10
      src/core/lib/surface/lame_client.cc
  13. 2
      tools/doxygen/Doxyfile.c++.internal
  14. 2
      tools/doxygen/Doxyfile.core.internal
  15. 4
      tools/run_tests/generated/sources_and_headers.json

@ -618,10 +618,6 @@ grpc_cc_library(
grpc_cc_library(
name = "atomic",
hdrs = [
"src/core/lib/gprpp/atomic_with_atm.h",
"src/core/lib/gprpp/atomic_with_std.h",
],
language = "c++",
public_hdrs = [
"src/core/lib/gprpp/atomic.h",
@ -677,6 +673,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = ["src/core/lib/gprpp/ref_counted.h"],
deps = [
"atomic",
"debug_location",
"gpr_base",
"grpc_trace",

@ -192,8 +192,6 @@ filegroups:
- src/core/lib/gpr/useful.h
- src/core/lib/gprpp/abstract.h
- src/core/lib/gprpp/atomic.h
- src/core/lib/gprpp/atomic_with_atm.h
- src/core/lib/gprpp/atomic_with_std.h
- src/core/lib/gprpp/fork.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/memory.h

@ -251,8 +251,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
@ -567,8 +565,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',

@ -206,8 +206,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
@ -875,8 +873,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',

@ -100,8 +100,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/useful.h )
s.files += %w( src/core/lib/gprpp/abstract.h )
s.files += %w( src/core/lib/gprpp/atomic.h )
s.files += %w( src/core/lib/gprpp/atomic_with_atm.h )
s.files += %w( src/core/lib/gprpp/atomic_with_std.h )
s.files += %w( src/core/lib/gprpp/fork.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/memory.h )

@ -105,8 +105,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/useful.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/abstract.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_atm.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_std.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/fork.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />

@ -342,8 +342,8 @@ bool MaybeAddServerLoadReportingFilter(const grpc_channel_args& args) {
// time if we build with the filter target.
struct ServerLoadReportingFilterStaticRegistrar {
ServerLoadReportingFilterStaticRegistrar() {
static std::atomic_bool registered{false};
if (registered) return;
static grpc_core::Atomic<bool> registered{false};
if (registered.Load(grpc_core::MemoryOrder::ACQUIRE)) return;
RegisterChannelFilter<ServerLoadReportingChannelData,
ServerLoadReportingCallData>(
"server_load_reporting", GRPC_SERVER_CHANNEL, INT_MAX,
@ -356,7 +356,7 @@ struct ServerLoadReportingFilterStaticRegistrar {
::grpc::load_reporter::MeasureEndBytesReceived();
::grpc::load_reporter::MeasureEndLatencyMs();
::grpc::load_reporter::MeasureOtherCallMetric();
registered = true;
registered.Store(true, grpc_core::MemoryOrder::RELEASE);
}
} server_load_reporting_filter_static_registrar;

@ -21,10 +21,78 @@
#include <grpc/support/port_platform.h>
#ifdef GPR_HAS_CXX11_ATOMIC
#include "src/core/lib/gprpp/atomic_with_std.h"
#else
#include "src/core/lib/gprpp/atomic_with_atm.h"
#endif
#include <atomic>
namespace grpc_core {
enum class MemoryOrder {
RELAXED = std::memory_order_relaxed,
CONSUME = std::memory_order_consume,
ACQUIRE = std::memory_order_acquire,
RELEASE = std::memory_order_release,
ACQ_REL = std::memory_order_acq_rel,
SEQ_CST = std::memory_order_seq_cst
};
template <typename T>
class Atomic {
public:
explicit Atomic(T val = T()) : storage_(val) {}
T Load(MemoryOrder order) const {
return storage_.load(static_cast<std::memory_order>(order));
}
void Store(T val, MemoryOrder order) {
storage_.store(val, static_cast<std::memory_order>(order));
}
bool CompareExchangeWeak(T* expected, T desired, MemoryOrder success,
MemoryOrder failure) {
return GPR_ATM_INC_CAS_THEN(
storage_.compare_exchange_weak(*expected, desired, success, failure));
}
bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success,
MemoryOrder failure) {
return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak(
*expected, desired, static_cast<std::memory_order>(success),
static_cast<std::memory_order>(failure)));
}
template <typename Arg>
T FetchAdd(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) {
return GPR_ATM_INC_ADD_THEN(storage_.fetch_add(
static_cast<Arg>(arg), static_cast<std::memory_order>(order)));
}
template <typename Arg>
T FetchSub(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) {
return GPR_ATM_INC_ADD_THEN(storage_.fetch_sub(
static_cast<Arg>(arg), static_cast<std::memory_order>(order)));
}
// Atomically increment a counter only if the counter value is not zero.
// Returns true if increment took place; false if counter is zero.
bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQ_REL) {
T count = storage_.load(static_cast<std::memory_order>(load_order));
do {
// If zero, we are done (without an increment). If not, we must do a CAS
// to maintain the contract: do not increment the counter if it is already
// zero
if (count == 0) {
return false;
}
} while (!storage_.AtomicCompareExchangeWeak(
&count, count + 1, static_cast<std::memory_order>(MemoryOrder::ACQ_REL),
static_cast<std::memory_order>(load_order)));
return true;
}
private:
std::atomic<T> storage_;
};
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_H */

@ -1,57 +0,0 @@
/*
*
* Copyright 2017 gRPC 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
*
* http://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 GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
#include <grpc/support/port_platform.h>
#include <grpc/support/atm.h>
namespace grpc_core {
enum MemoryOrderRelaxed { memory_order_relaxed };
template <class T>
class atomic;
template <>
class atomic<bool> {
public:
atomic() { gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(false)); }
explicit atomic(bool x) {
gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(x));
}
bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed,
MemoryOrderRelaxed) {
if (!gpr_atm_no_barrier_cas(&x_, static_cast<gpr_atm>(expected),
static_cast<gpr_atm>(update))) {
expected = gpr_atm_no_barrier_load(&x_) != 0;
return false;
}
return true;
}
private:
gpr_atm x_;
};
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H */

@ -1,35 +0,0 @@
/*
*
* Copyright 2017 gRPC 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
*
* http://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 GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
#include <grpc/support/port_platform.h>
#include <atomic>
namespace grpc_core {
template <class T>
using atomic = std::atomic<T>;
typedef std::memory_order memory_order;
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H */

@ -31,6 +31,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -88,9 +89,7 @@ class RefCount {
}
// Increases the ref-count by `n`.
void Ref(Value n = 1) {
GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed));
}
void Ref(Value n = 1) { value_.FetchAdd(n, MemoryOrder::RELAXED); }
void Ref(const DebugLocation& location, const char* reason, Value n = 1) {
#ifndef NDEBUG
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
@ -106,8 +105,7 @@ class RefCount {
// Similar to Ref() with an assert on the ref-count being non-zero.
void RefNonZero() {
#ifndef NDEBUG
const Value prior =
GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed));
const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED);
assert(prior > 0);
#else
Ref();
@ -127,8 +125,7 @@ class RefCount {
// Decrements the ref-count and returns true if the ref-count reaches 0.
bool Unref() {
const Value prior =
GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel));
const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL);
GPR_DEBUG_ASSERT(prior > 0);
return prior == 1;
}
@ -145,12 +142,12 @@ class RefCount {
}
private:
Value get() const { return value_.load(std::memory_order_relaxed); }
Value get() const { return value_.Load(MemoryOrder::RELAXED); }
#ifndef NDEBUG
TraceFlag* trace_flag_;
#endif
std::atomic<Value> value_;
Atomic<Value> value_;
};
// A base class for reference-counted objects.

@ -25,10 +25,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
@ -43,7 +42,7 @@ struct CallData {
grpc_call_combiner* call_combiner;
grpc_linked_mdelem status;
grpc_linked_mdelem details;
grpc_core::atomic<bool> filled_metadata;
grpc_core::Atomic<bool> filled_metadata;
};
struct ChannelData {
@ -54,9 +53,8 @@ struct ChannelData {
static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) {
CallData* calld = static_cast<CallData*>(elem->call_data);
bool expected = false;
if (!calld->filled_metadata.compare_exchange_strong(
expected, true, grpc_core::memory_order_relaxed,
grpc_core::memory_order_relaxed)) {
if (!calld->filled_metadata.CompareExchangeStrong(
&expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) {
return;
}
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);

@ -1068,8 +1068,6 @@ src/core/lib/gpr/tmpfile.h \
src/core/lib/gpr/useful.h \
src/core/lib/gprpp/abstract.h \
src/core/lib/gprpp/atomic.h \
src/core/lib/gprpp/atomic_with_atm.h \
src/core/lib/gprpp/atomic_with_std.h \
src/core/lib/gprpp/debug_location.h \
src/core/lib/gprpp/fork.h \
src/core/lib/gprpp/inlined_vector.h \

@ -1157,8 +1157,6 @@ src/core/lib/gpr/wrap_memcpy.cc \
src/core/lib/gprpp/README.md \
src/core/lib/gprpp/abstract.h \
src/core/lib/gprpp/atomic.h \
src/core/lib/gprpp/atomic_with_atm.h \
src/core/lib/gprpp/atomic_with_std.h \
src/core/lib/gprpp/debug_location.h \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/fork.h \

@ -9288,8 +9288,6 @@
"src/core/lib/gpr/useful.h",
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/atomic_with_atm.h",
"src/core/lib/gprpp/atomic_with_std.h",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
@ -9336,8 +9334,6 @@
"src/core/lib/gpr/useful.h",
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/atomic_with_atm.h",
"src/core/lib/gprpp/atomic_with_std.h",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",

Loading…
Cancel
Save