|
|
|
@ -37,10 +37,13 @@ |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/iomgr/timer.h" |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
#include <grpc/support/string_util.h> |
|
|
|
|
#include <grpc/support/sync.h> |
|
|
|
|
#include <grpc/support/tls.h> |
|
|
|
|
#include <grpc/support/useful.h> |
|
|
|
|
#include "src/core/lib/debug/trace.h" |
|
|
|
|
#include "src/core/lib/iomgr/time_averaged_stats.h" |
|
|
|
|
#include "src/core/lib/iomgr/timer_heap.h" |
|
|
|
|
#include "src/core/lib/support/spinlock.h" |
|
|
|
@ -53,6 +56,9 @@ |
|
|
|
|
#define MIN_QUEUE_WINDOW_DURATION 0.01 |
|
|
|
|
#define MAX_QUEUE_WINDOW_DURATION 1 |
|
|
|
|
|
|
|
|
|
static int grpc_timer_trace = 0; |
|
|
|
|
static int grpc_timer_check_trace = 0; |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
gpr_mu mu; |
|
|
|
|
grpc_time_averaged_stats stats; |
|
|
|
@ -107,6 +113,7 @@ static gpr_timespec dbl_to_ts(double d) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) { |
|
|
|
|
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 + 1.0; |
|
|
|
|
if (x < 0) return 0; |
|
|
|
@ -115,6 +122,7 @@ static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) { |
|
|
|
|
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; |
|
|
|
@ -142,6 +150,8 @@ void grpc_timer_list_init(gpr_timespec now) { |
|
|
|
|
g_shared_mutables.min_timer = timespec_to_atm_round_down(now); |
|
|
|
|
gpr_tls_init(&g_last_seen_min_timer); |
|
|
|
|
gpr_tls_set(&g_last_seen_min_timer, 0); |
|
|
|
|
grpc_register_tracer("timer", &grpc_timer_trace); |
|
|
|
|
grpc_register_tracer("timer_check", &grpc_timer_check_trace); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_SHARDS; i++) { |
|
|
|
|
shard_type *shard = &g_shards[i]; |
|
|
|
@ -221,6 +231,13 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, |
|
|
|
|
timer->closure = closure; |
|
|
|
|
timer->deadline = timespec_to_atm_round_up(deadline); |
|
|
|
|
|
|
|
|
|
if (grpc_timer_trace) { |
|
|
|
|
gpr_log(GPR_DEBUG, "TIMER %p: SET %" PRIdPTR ".%09d now %" PRIdPTR |
|
|
|
|
".%09d [%" PRIdPTR "] call %p[%p]", |
|
|
|
|
timer, deadline.tv_sec, deadline.tv_nsec, now.tv_sec, now.tv_nsec, |
|
|
|
|
timer->deadline, closure, closure->cb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!g_shared_mutables.initialized) { |
|
|
|
|
timer->pending = false; |
|
|
|
|
grpc_closure_sched( |
|
|
|
@ -427,15 +444,41 @@ bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, |
|
|
|
|
gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0 |
|
|
|
|
? GRPC_ERROR_NONE |
|
|
|
|
: GRPC_ERROR_CREATE("Shutting down timer system"); |
|
|
|
|
if (grpc_timer_check_trace) { |
|
|
|
|
char *next_str; |
|
|
|
|
if (next == NULL) { |
|
|
|
|
next_str = gpr_strdup("NULL"); |
|
|
|
|
} else { |
|
|
|
|
gpr_asprintf(&next_str, "%" PRIdPTR ".%09d [%" PRIdPTR "]", next->tv_sec, |
|
|
|
|
next->tv_nsec, timespec_to_atm_round_down(*next)); |
|
|
|
|
} |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"TIMER CHECK BEGIN: now=%" PRIdPTR ".%09d [%" PRIdPTR "] next=%s", |
|
|
|
|
now.tv_sec, now.tv_nsec, now_atm, next_str); |
|
|
|
|
gpr_free(next_str); |
|
|
|
|
} |
|
|
|
|
bool r; |
|
|
|
|
gpr_atm next_atm; |
|
|
|
|
if (next == NULL) { |
|
|
|
|
r = run_some_expired_timers(exec_ctx, now_atm, NULL, shutdown_error); |
|
|
|
|
} else { |
|
|
|
|
gpr_atm next_atm = timespec_to_atm_round_down(*next); |
|
|
|
|
next_atm = timespec_to_atm_round_down(*next); |
|
|
|
|
r = run_some_expired_timers(exec_ctx, now_atm, &next_atm, shutdown_error); |
|
|
|
|
*next = atm_to_timespec(next_atm); |
|
|
|
|
} |
|
|
|
|
return r; |
|
|
|
|
if (grpc_timer_check_trace) { |
|
|
|
|
char *next_str; |
|
|
|
|
if (next == NULL) { |
|
|
|
|
next_str = gpr_strdup("NULL"); |
|
|
|
|
} else { |
|
|
|
|
gpr_asprintf(&next_str, "%" PRIdPTR ".%09d [%" PRIdPTR "]", next->tv_sec, |
|
|
|
|
next->tv_nsec, next_atm); |
|
|
|
|
} |
|
|
|
|
gpr_log(GPR_DEBUG, "TIMER CHECK END: %d timers triggered; next=%s", r, |
|
|
|
|
next_str); |
|
|
|
|
gpr_free(next_str); |
|
|
|
|
} |
|
|
|
|
return r > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* GRPC_TIMER_USE_GENERIC */ |
|
|
|
|