| 
					
				 | 
			
			
				@@ -187,12 +187,10 @@ static double ts_to_dbl(gpr_timespec ts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* returns true if the first element in the list */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static bool list_join(grpc_timer *head, grpc_timer *timer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  bool is_first = head->next == head; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void list_join(grpc_timer *head, grpc_timer *timer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   timer->next = head; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   timer->prev = head->prev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   timer->next->prev = timer->prev->next = timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return is_first; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void list_remove(grpc_timer *timer) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -267,8 +265,7 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     is_first_timer = grpc_timer_heap_add(&shard->heap, timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     timer->heap_index = INVALID_HEAP_INDEX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    is_first_timer = list_join(&shard->list, timer) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     grpc_timer_heap_is_empty(&shard->heap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    list_join(&shard->list, timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (grpc_timer_trace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_DEBUG, "  .. add to shard %d with queue_deadline_cap=%" PRIdPTR 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -428,15 +425,7 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_atm now, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    gpr_atm *next, grpc_error *error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   size_t n = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* fetch from a thread-local first: this avoids contention on a globally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     mutable cacheline in the common case */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_atm min_timer = gpr_tls_get(&g_last_seen_min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (now < min_timer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (next != NULL) *next = GPR_MIN(*next, min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  min_timer = gpr_atm_no_barrier_load(&g_shared_mutables.min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_atm min_timer = gpr_atm_no_barrier_load(&g_shared_mutables.min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_tls_set(&g_last_seen_min_timer, min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (now < min_timer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (next != NULL) *next = GPR_MIN(*next, min_timer); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -499,10 +488,28 @@ bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // prelude 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(now.clock_type == g_clock_type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_atm now_atm = timespec_to_atm_round_down(now); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* fetch from a thread-local first: this avoids contention on a globally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     mutable cacheline in the common case */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_atm min_timer = gpr_tls_get(&g_last_seen_min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (now_atm < min_timer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (next != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      *next = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          atm_to_timespec(GPR_MIN(timespec_to_atm_round_up(*next), min_timer)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (grpc_timer_check_trace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_DEBUG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "TIMER CHECK SKIP: now_atm=%" PRId64 " min_timer=%" PRId64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              now_atm, min_timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_error *shutdown_error = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           ? GRPC_ERROR_NONE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // tracing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (grpc_timer_check_trace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char *next_str; 
			 |