diff --git a/BUILD b/BUILD index 1991c867432..c78a991e271 100644 --- a/BUILD +++ b/BUILD @@ -366,6 +366,10 @@ grpc_cc_library( "src/core/lib/support/backoff.h", "src/core/lib/support/block_annotate.h", "src/core/lib/support/env.h", + "src/core/lib/support/memory.h" + "src/core/lib/support/atomic.h" + "src/core/lib/support/atomic_with_atm.h" + "src/core/lib/support/atomic_with_std.h" "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", "src/core/lib/support/spinlock.h", @@ -537,7 +541,7 @@ grpc_cc_library( "src/core/lib/surface/completion_queue.c", "src/core/lib/surface/completion_queue_factory.c", "src/core/lib/surface/event_string.c", - "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/lame_client.cc", "src/core/lib/surface/metadata_array.c", "src/core/lib/surface/server.c", "src/core/lib/surface/validate_metadata.c", diff --git a/build.yaml b/build.yaml index e26fa16968a..483f950cb79 100644 --- a/build.yaml +++ b/build.yaml @@ -90,6 +90,9 @@ filegroups: - src/core/lib/support/block_annotate.h - src/core/lib/support/env.h - src/core/lib/support/memory.h + - src/core/lib/support/atomic.h + - src/core/lib/support/atomic_with_atm.h + - src/core/lib/support/atomic_with_std.h - src/core/lib/support/mpscq.h - src/core/lib/support/murmur_hash.h - src/core/lib/support/spinlock.h diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 813e08b86e3..bac409e514d 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -290,6 +290,12 @@ #endif #endif /* GPR_NO_AUTODETECT_PLATFORM */ +#if defined(__has_include) +#if __has_include() +#define GRPC_HAS_CXX11_ATOMIC +#endif // __has_include() +#endif // defined(__has_include) + #ifndef GPR_PLATFORM_STRING #warning "GPR_PLATFORM_STRING not auto-detected" #define GPR_PLATFORM_STRING "unknown" diff --git a/src/core/lib/support/atomic.h b/src/core/lib/support/atomic.h new file mode 100644 index 00000000000..7cb495a0202 --- /dev/null +++ b/src/core/lib/support/atomic.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_H +#define GRPC_CORE_LIB_SUPPORT_ATOMIC_H + +#include + +#ifdef GPR_HAS_CXX11_ATOMIC +#include "atomic_with_std.h" +#else +#include "atomic_with_atm.h" +#endif + +#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */ diff --git a/src/core/lib/support/atomic_with_atm.h b/src/core/lib/support/atomic_with_atm.h new file mode 100644 index 00000000000..6ad375736f9 --- /dev/null +++ b/src/core/lib/support/atomic_with_atm.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H +#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H + +#include + +namespace grpc_core { + +enum MemoryOrderRelaxed { memory_order_relaxed }; + +template +class atomic { + public: + static_assert(sizeof(T) <= sizeof(gpr_atm), + "Atomics of size > sizeof(gpr_atm) are not supported"); + atomic() { gpr_atm_no_barrier_store(&x_, static_cast(T())); } + + bool compare_exchange_strong(T& expected, T update, MemoryOrderRelaxed, + MemoryOrderRelaxed) { + if (!gpr_atm_no_barrier_cas(&x_, static_cast(expected), + static_cast(update))) { + expected = static_cast(gpr_atm_no_barrier_load(&x_)); + return false; + } + return true; + } + + private: + gpr_atm x_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */ diff --git a/src/core/lib/support/atomic_with_std.h b/src/core/lib/support/atomic_with_std.h new file mode 100644 index 00000000000..7e9c19efe8a --- /dev/null +++ b/src/core/lib/support/atomic_with_std.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H +#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H + +#include + +namespace grpc_core { + +template +using atomic = std::atomic; + +typedef std::memory_order memory_order; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H */ diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index 4616fc58300..7a64726edb2 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -39,6 +39,8 @@ #include #include +#include "src/core/lib/support/atomic.h" + extern "C" { #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/support/string.h" @@ -56,7 +58,7 @@ namespace { struct CallData { grpc_linked_mdelem status; grpc_linked_mdelem details; - std::atomic filled_metadata; + grpc_core::atomic filled_metadata; }; struct ChannelData { @@ -69,8 +71,8 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, CallData *calld = static_cast(elem->call_data); bool expected = false; if (!calld->filled_metadata.compare_exchange_strong( - expected, true, std::memory_order_relaxed, - std::memory_order_relaxed)) { + expected, true, grpc_core::memory_order_relaxed, + grpc_core::memory_order_relaxed)) { return; } ChannelData *chand = static_cast(elem->channel_data);