Use atomic time pair for g_start_time
diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc
index 79ce33f..c3182dc 100644
--- a/src/core/lib/iomgr/exec_ctx.cc
+++ b/src/core/lib/iomgr/exec_ctx.cc
@@ -107,27 +107,43 @@
   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_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 @@
   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 @@
 
 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_log(GPR_DEBUG, "Update realtime clock start time: %" PRId64 "s %dns", real_start_time.tv_sec, real_start_time.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_mu_unlock(&g_start_time_mu);
   }
 }