From 415739a051a93e56593cd732c57fd46f661970f4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Nov 2017 14:40:14 -0800 Subject: Use atomic time pair for g_start_time --- src/core/lib/iomgr/exec_ctx.cc | 52 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index 79ce33fa56..c3182dca3a 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -107,27 +107,43 @@ static void exec_ctx_sched(grpc_exec_ctx* exec_ctx, grpc_closure* closure, grpc_closure_list_append(&exec_ctx->closure_list, closure, error); } -static gpr_timespec +typedef struct time_atm_pair { + gpr_atm tv_sec; + gpr_atm tv_nsec; +} time_atm_pair; + +static time_atm_pair g_start_time[GPR_TIMESPAN + 1]; // assumes GPR_TIMESPAN is the // last enum value in // gpr_clock_type - static grpc_millis g_last_start_time_update; -static gpr_mu g_start_time_mu; + +static gpr_timespec timespec_from_time_atm_pair(const time_atm_pair* src, gpr_clock_type clock_type) { + gpr_timespec time; + time.tv_nsec = (int32_t)gpr_atm_no_barrier_load(&src->tv_nsec); + time.tv_sec = (int64_t)gpr_atm_no_barrier_load(&src->tv_sec); + time.clock_type = clock_type; + return time; +} + +static void time_atm_pair_store(time_atm_pair* dst, const gpr_timespec src) { + gpr_atm_no_barrier_store(&dst->tv_sec, src.tv_sec); + gpr_atm_no_barrier_store(&dst->tv_nsec, src.tv_nsec); +} void grpc_exec_ctx_global_init(void) { for (int i = 0; i < GPR_TIMESPAN; i++) { - g_start_time[i] = gpr_now((gpr_clock_type)i); + time_atm_pair_store(&g_start_time[i], gpr_now((gpr_clock_type)i)); } // allows uniform treatment in conversion functions - g_start_time[GPR_TIMESPAN] = gpr_time_0(GPR_TIMESPAN); - gpr_mu_init(&g_start_time_mu); + time_atm_pair_store(&g_start_time[GPR_TIMESPAN], gpr_time_0(GPR_TIMESPAN)); } void grpc_exec_ctx_global_shutdown(void) {} static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) { - ts = gpr_time_sub(ts, g_start_time[ts.clock_type]); + gpr_timespec start_time = timespec_from_time_atm_pair(&g_start_time[ts.clock_type], ts.clock_type); + ts = gpr_time_sub(ts, start_time); double x = GPR_MS_PER_SEC * (double)ts.tv_sec + (double)ts.tv_nsec / GPR_NS_PER_MS; if (x < 0) return 0; @@ -136,7 +152,8 @@ static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) { } static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) { - ts = gpr_time_sub(ts, g_start_time[ts.clock_type]); + gpr_timespec start_time = timespec_from_time_atm_pair(&g_start_time[ts.clock_type], ts.clock_type); + ts = gpr_time_sub(ts, start_time); double x = GPR_MS_PER_SEC * (double)ts.tv_sec + (double)ts.tv_nsec / GPR_NS_PER_MS + (double)(GPR_NS_PER_SEC - 1) / (double)GPR_NS_PER_SEC; @@ -171,7 +188,8 @@ gpr_timespec grpc_millis_to_timespec(grpc_millis millis, if (clock_type == GPR_TIMESPAN) { return gpr_time_from_millis(millis, GPR_TIMESPAN); } - return gpr_time_add(g_start_time[clock_type], + gpr_timespec start_time = timespec_from_time_atm_pair(&g_start_time[clock_type], clock_type); + return gpr_time_add(start_time, gpr_time_from_millis(millis, GPR_TIMESPAN)); } @@ -185,21 +203,17 @@ grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec ts) { void grpc_exec_ctx_maybe_update_start_time(grpc_exec_ctx* exec_ctx) { grpc_millis now = grpc_exec_ctx_now(exec_ctx); - grpc_millis last_start_time_update = gpr_atm_acq_load(&g_last_start_time_update); + grpc_millis last_start_time_update = gpr_atm_no_barrier_load(&g_last_start_time_update); if (now > last_start_time_update && now - last_start_time_update > GRPC_START_TIME_UPDATE_INTERVAL) { + gpr_atm_no_barrier_store(&g_last_start_time_update, now); gpr_timespec real_now = gpr_now(GPR_CLOCK_REALTIME); - gpr_timespec old_now = grpc_millis_to_timespec(now, GPR_CLOCK_REALTIME); - gpr_timespec diff = gpr_time_sub(real_now, old_now); + gpr_timespec real_start_time = gpr_time_sub(real_now, gpr_time_from_millis(now, GPR_TIMESPAN)); + time_atm_pair_store(&g_start_time[GPR_CLOCK_REALTIME], real_start_time); + if (GRPC_TRACER_ON(grpc_timer_check_trace)) { - gpr_log(GPR_DEBUG, "Update start time with diff: %" PRId64 "s %dns", diff.tv_sec, diff.tv_nsec); - } - gpr_mu_lock(&g_start_time_mu); - if (last_start_time_update == gpr_atm_acq_load(&g_last_start_time_update)) { - g_start_time[GPR_CLOCK_REALTIME] = gpr_time_add(g_start_time[GPR_CLOCK_REALTIME], diff); - g_last_start_time_update = now; + gpr_log(GPR_DEBUG, "Update realtime clock start time: %" PRId64 "s %dns", real_start_time.tv_sec, real_start_time.tv_nsec); } - gpr_mu_unlock(&g_start_time_mu); } } -- cgit v1.2.3