|  | @@ -25,9 +25,6 @@
 | 
	
		
			
				|  |  |  #include "src/core/lib/iomgr/combiner.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/profiling/timers.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#define GRPC_START_TIME_UPDATE_INTERVAL 10000
 | 
	
		
			
				|  |  | -extern "C" grpc_tracer_flag grpc_timer_check_trace;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx* exec_ctx) {
 | 
	
		
			
				|  |  |    if ((exec_ctx->flags & GRPC_EXEC_CTX_FLAG_IS_FINISHED) == 0) {
 | 
	
		
			
				|  |  |      if (exec_ctx->check_ready_to_finish(exec_ctx,
 | 
	
	
		
			
				|  | @@ -107,49 +104,16 @@ static void exec_ctx_sched(grpc_exec_ctx* exec_ctx, grpc_closure* closure,
 | 
	
		
			
				|  |  |    grpc_closure_list_append(&exec_ctx->closure_list, closure, error);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* This time pair is not entirely thread-safe as store/load of tv_sec and
 | 
	
		
			
				|  |  | - * tv_nsec are performed separately. However g_start_time do not need to have
 | 
	
		
			
				|  |  | - * sub-second precision, so it is ok if the value of tv_nsec is off in this
 | 
	
		
			
				|  |  | - * case. */
 | 
	
		
			
				|  |  | -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_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);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +static gpr_timespec g_start_time;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void grpc_exec_ctx_global_init(void) {
 | 
	
		
			
				|  |  | -  for (int i = 0; i < GPR_TIMESPAN; i++) {
 | 
	
		
			
				|  |  | -    time_atm_pair_store(&g_start_time[i], gpr_now((gpr_clock_type)i));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  // allows uniform treatment in conversion functions
 | 
	
		
			
				|  |  | -  time_atm_pair_store(&g_start_time[GPR_TIMESPAN], gpr_time_0(GPR_TIMESPAN));
 | 
	
		
			
				|  |  | +  g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void grpc_exec_ctx_global_shutdown(void) {}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
 | 
	
		
			
				|  |  | -  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);
 | 
	
		
			
				|  |  | +  ts = gpr_time_sub(ts, g_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;
 | 
	
	
		
			
				|  | @@ -158,9 +122,7 @@ static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) {
 | 
	
		
			
				|  |  | -  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);
 | 
	
		
			
				|  |  | +  ts = gpr_time_sub(ts, g_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;
 | 
	
	
		
			
				|  | @@ -195,41 +157,18 @@ gpr_timespec grpc_millis_to_timespec(grpc_millis millis,
 | 
	
		
			
				|  |  |    if (clock_type == GPR_TIMESPAN) {
 | 
	
		
			
				|  |  |      return gpr_time_from_millis(millis, GPR_TIMESPAN);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  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));
 | 
	
		
			
				|  |  | +  return gpr_time_add(gpr_convert_clock_type(g_start_time, clock_type),
 | 
	
		
			
				|  |  | +                      gpr_time_from_millis(millis, GPR_TIMESPAN));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec ts) {
 | 
	
		
			
				|  |  | -  return timespec_to_atm_round_down(ts);
 | 
	
		
			
				|  |  | +  return timespec_to_atm_round_down(
 | 
	
		
			
				|  |  | +      gpr_convert_clock_type(ts, g_start_time.clock_type));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec ts) {
 | 
	
		
			
				|  |  | -  return timespec_to_atm_round_up(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_no_barrier_load(&g_last_start_time_update);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (now > last_start_time_update &&
 | 
	
		
			
				|  |  | -      now - last_start_time_update > GRPC_START_TIME_UPDATE_INTERVAL) {
 | 
	
		
			
				|  |  | -    /* Get the current system time and subtract \a now from it, where \a now is
 | 
	
		
			
				|  |  | -     * the relative time from grpc_init() from monotonic clock. This calibrates
 | 
	
		
			
				|  |  | -     * the time when grpc_exec_ctx_global_init was called based on current
 | 
	
		
			
				|  |  | -     * system clock. */
 | 
	
		
			
				|  |  | -    gpr_atm_no_barrier_store(&g_last_start_time_update, now);
 | 
	
		
			
				|  |  | -    gpr_timespec real_now = gpr_now(GPR_CLOCK_REALTIME);
 | 
	
		
			
				|  |  | -    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 realtime clock start time: %" PRId64 "s %dns",
 | 
	
		
			
				|  |  | -              real_start_time.tv_sec, real_start_time.tv_nsec);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  return timespec_to_atm_round_up(
 | 
	
		
			
				|  |  | +      gpr_convert_clock_type(ts, g_start_time.clock_type));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static const grpc_closure_scheduler_vtable exec_ctx_scheduler_vtable = {
 |