aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ncteisen <ncteisen@gmail.com>2018-06-05 08:26:34 -0700
committerGravatar ncteisen <ncteisen@gmail.com>2018-06-05 22:35:17 -0700
commita8717043515fd1fdb661cb684fb952109a547660 (patch)
treeadc4b5f7bcdf5ca0c378493765c18cb14e91f987
parentec482847b29e4efb07e1eb23fc0fed1ea4a5aebc (diff)
Make operations atomic
-rw-r--r--src/core/lib/channel/channelz.cc28
-rw-r--r--src/core/lib/channel/channelz.h27
2 files changed, 43 insertions, 12 deletions
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 5c3dc97e69..9e153a3f4f 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -93,8 +93,6 @@ Channel::Channel(grpc_channel* channel, size_t channel_tracer_max_nodes)
trace_.Init(channel_tracer_max_nodes);
target_ = grpc_channel_get_target(channel_);
channel_uuid_ = ChannelzRegistry::Register(this);
- last_call_started_timestamp_ =
- grpc_millis_to_timespec(ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME);
}
Channel::~Channel() {
@@ -103,10 +101,28 @@ Channel::~Channel() {
ChannelzRegistry::Unregister(channel_uuid_);
}
+Channel::AtomicTimespec::AtomicTimespec() {
+ gpr_atm_no_barrier_store(&tv_sec_, (gpr_atm)0);
+ gpr_atm_no_barrier_store(&tv_nsec_, (gpr_atm)0);
+}
+
+void Channel::AtomicTimespec::Update(gpr_timespec ts) {
+ gpr_atm_no_barrier_store(&tv_sec_, (gpr_atm)ts.tv_sec);
+ gpr_atm_no_barrier_store(&tv_nsec_, (gpr_atm)ts.tv_nsec);
+}
+
+gpr_timespec Channel::AtomicTimespec::Get() {
+ gpr_timespec out;
+ out.clock_type = GPR_CLOCK_REALTIME;
+ out.tv_sec = static_cast<int64_t>(gpr_atm_no_barrier_load(&tv_sec_));
+ out.tv_nsec = static_cast<int32_t>(gpr_atm_no_barrier_load(&tv_nsec_));
+ return out;
+}
+
void Channel::CallStarted() {
- calls_started_++;
- last_call_started_timestamp_ =
- grpc_millis_to_timespec(ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME);
+ gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1);
+ last_call_started_timestamp_.Update(
+ grpc_millis_to_timespec(ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME));
}
grpc_connectivity_state Channel::GetConnectivityState() {
@@ -181,7 +197,7 @@ char* Channel::RenderJSON() {
calls_failed_ ? calls_failed_ : -1);
json_iterator = grpc_json_create_child(
json_iterator, json, "lastCallStartedTimestamp",
- fmt_time(last_call_started_timestamp_), GRPC_JSON_STRING, true);
+ fmt_time(last_call_started_timestamp_.Get()), GRPC_JSON_STRING, true);
// render and return the over json object
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 5cfafc9e14..684402e08f 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -39,8 +39,12 @@ class Channel : public RefCounted<Channel> {
~Channel();
void CallStarted();
- void CallFailed() { calls_failed_++; }
- void CallSucceeded() { calls_succeeded_++; }
+ void CallFailed() {
+ gpr_atm_no_barrier_fetch_add(&calls_failed_, (gpr_atm(1)));
+ }
+ void CallSucceeded() {
+ gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1)));
+ }
char* RenderJSON();
@@ -54,13 +58,24 @@ class Channel : public RefCounted<Channel> {
intptr_t channel_uuid() { return channel_uuid_; }
private:
+ class AtomicTimespec {
+ public:
+ AtomicTimespec();
+ void Update(gpr_timespec ts);
+ gpr_timespec Get();
+
+ private:
+ gpr_atm tv_sec_;
+ gpr_atm tv_nsec_;
+ };
+
bool channel_destroyed_ = false;
grpc_channel* channel_;
const char* target_;
- int64_t calls_started_ = 0;
- int64_t calls_succeeded_ = 0;
- int64_t calls_failed_ = 0;
- gpr_timespec last_call_started_timestamp_;
+ gpr_atm calls_started_ = 0;
+ gpr_atm calls_succeeded_ = 0;
+ gpr_atm calls_failed_ = 0;
+ AtomicTimespec last_call_started_timestamp_;
intptr_t channel_uuid_;
ManualConstructor<ChannelTrace> trace_;