Go to the documentation of this file.
25 #include "absl/strings/str_cat.h"
43 #define INVALID_HEAP_INDEX 0xffffffffu
45 #define ADD_DEADLINE_SCALE 0.33
46 #define MIN_QUEUE_WINDOW_DURATION 0.01
47 #define MAX_QUEUE_WINDOW_DURATION 1.0
91 #define NUM_HASH_BUCKETS 1009
113 while (
p !=
nullptr &&
p != t) {
114 p =
p->hash_table_next;
127 while (
p !=
nullptr &&
p != t) {
128 p =
p->hash_table_next;
134 "** Duplicate timer (%p) being added. Closure: (%p), created at: "
135 "(%s:%d), scheduled at: (%s:%d) **",
136 t,
c,
c->file_created,
c->line_created,
c->file_initiated,
149 bool removed =
false;
157 while (
p->hash_table_next !=
nullptr &&
p->hash_table_next != t) {
158 p =
p->hash_table_next;
161 if (
p->hash_table_next == t) {
162 p->hash_table_next = t->hash_table_next;
171 "** Removing timer (%p) that is not added to hash table. Closure "
172 "(%p), created at: (%s:%d), scheduled at: (%s:%d) **",
173 t,
c,
c->file_created,
c->line_created,
c->file_initiated,
178 t->hash_table_next =
nullptr;
189 "** gpr_timer_cancel() called on a non-pending timer (%p) which "
190 "is in the hash table. Closure: (%p), created at: (%s:%d), "
191 "scheduled at: (%s:%d) **",
192 t,
c,
c->file_created,
c->line_created,
c->file_initiated,
198 #define INIT_TIMER_HASH_TABLE() init_timer_ht()
199 #define DESTROY_TIMER_HASH_TABLE() destroy_timer_ht()
200 #define ADD_TO_HASH_TABLE(t) add_to_ht((t))
201 #define REMOVE_FROM_HASH_TABLE(t) remove_from_ht((t))
202 #define VALIDATE_NON_PENDING_TIMER(t) validate_non_pending_timer((t))
206 #define INIT_TIMER_HASH_TABLE()
207 #define DESTROY_TIMER_HASH_TABLE()
208 #define ADD_TO_HASH_TABLE(t)
209 #define REMOVE_FROM_HASH_TABLE(t)
210 #define VALIDATE_NON_PENDING_TIMER(t)
257 g_last_seen_min_timer = 0;
312 first_shard_queue_index;
314 first_shard_queue_index + 1;
334 int is_first_timer = 0;
340 timer->hash_table_next =
nullptr;
344 gpr_log(
GPR_INFO,
"TIMER %p: SET %" PRId64
" now %" PRId64
" call %p[%p]",
351 timer->pending =
false;
355 "Attempt to create timer before initialization"));
360 timer->pending =
true;
362 if (deadline <=
now) {
363 timer->pending =
false;
371 (deadline -
now).millis() / 1000.0);
375 if (deadline < shard->queue_deadline_cap) {
383 " .. add to shard %d with queue_deadline_cap=%" PRId64
384 " => is_first_timer=%s",
387 is_first_timer ?
"true" :
"false");
402 if (is_first_timer) {
408 if (deadline < shard->min_deadline) {
435 g_last_seen_min_timer = 0;
448 timer->pending ?
"true" :
"false");
451 if (
timer->pending) {
456 timer->pending =
false;
475 double computed_deadline_delta =
478 double deadline_delta =
495 auto timer_deadline =
499 if (timer_deadline < shard->queue_deadline_cap) {
502 timer_deadline.milliseconds_after_process_epoch());
523 if (now < shard->queue_deadline_cap)
return nullptr;
527 auto timer_deadline =
532 " .. check top timer deadline=%" PRId64
" now=%" PRId64,
533 timer_deadline.milliseconds_after_process_epoch(),
534 now.milliseconds_after_process_epoch());
536 if (timer_deadline >
now)
return nullptr;
539 (
now - timer_deadline).millis());
541 timer->pending =
false;
603 GPR_INFO,
" .. shard[%d]->min_deadline = %" PRId64,
605 g_shard_queue[0]->min_deadline.milliseconds_after_process_epoch());
624 ", shard[%d]->min_deadline %" PRId64
" --> %" PRId64
627 g_shard_queue[0]->min_deadline.milliseconds_after_process_epoch(),
629 now.milliseconds_after_process_epoch());
676 g_last_seen_min_timer);
679 if (
next !=
nullptr) {
683 gpr_log(
GPR_INFO,
"TIMER CHECK SKIP: now=%" PRId64
" min_timer=%" PRId64,
684 now.milliseconds_after_process_epoch(),
698 if (
next ==
nullptr) {
706 "TIMER CHECK BEGIN: now=%" PRId64
" next=%s tls_min=%" PRId64
707 " glob_min=%" PRId64,
708 now.milliseconds_after_process_epoch(), next_str.c_str(),
714 gpr_log(
GPR_INFO,
"TIMER CHECK BEGIN: now=%" PRId64
" next=%s min=%" PRId64,
715 now.milliseconds_after_process_epoch(), next_str.c_str(),
725 if (
next ==
nullptr) {
GPRAPI unsigned gpr_cpu_num_cores(void)
#define GPR_SPINLOCK_INITIALIZER
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
#define gpr_atm_no_barrier_load(p)
#define gpr_atm_no_barrier_store(p, value)
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
static Duration FromSecondsAsDouble(double seconds)
static grpc_core::Timestamp compute_min_deadline(timer_shard *shard)
void grpc_timer_heap_remove(grpc_timer_heap *heap, grpc_timer *timer)
static void list_remove(grpc_timer *timer)
@ GRPC_TIMERS_NOT_CHECKED
static size_t g_num_shards
#define REMOVE_FROM_HASH_TABLE(t)
void grpc_time_averaged_stats_init(grpc_time_averaged_stats *stats, double init_avg, double regress_weight, double persistence_factor)
GPRAPI void gpr_free(void *ptr)
#define INVALID_HEAP_INDEX
static void init_timer_ht()
static size_t pop_timers(timer_shard *shard, grpc_core::Timestamp now, grpc_core::Timestamp *new_min_deadline, grpc_error_handle error)
OPENSSL_EXPORT pem_password_cb void * u
static timer_shard ** g_shard_queue
static void timer_consume_kick(void)
static void validate_non_pending_timer(grpc_timer *t)
static void timer_init(grpc_timer *timer, grpc_core::Timestamp deadline, grpc_closure *closure)
static void remove_from_ht(grpc_timer *t)
#define GRPC_ERROR_CANCELLED
static GPR_THREAD_LOCAL(int64_t) g_last_seen_min_timer
#define GRPC_TRACE_FLAG_ENABLED(f)
void grpc_timer_init_unset(grpc_timer *timer)
#define ADD_TO_HASH_TABLE(t)
static void add_to_ht(grpc_timer *t)
GPRAPI void * gpr_zalloc(size_t size)
void grpc_timer_heap_destroy(grpc_timer_heap *heap)
GPRAPI void gpr_mu_destroy(gpr_mu *mu)
static void timer_cancel(grpc_timer *timer)
static grpc_timer_check_result timer_check(grpc_core::Timestamp *next)
bool grpc_timer_heap_add(grpc_timer_heap *heap, grpc_timer *timer)
uint32_t shard_queue_index
grpc_core::Timestamp min_timer
#define ADD_DEADLINE_SCALE
void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats *stats, double value)
#define MAX_QUEUE_WINDOW_DURATION
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
GPRAPI void gpr_mu_init(gpr_mu *mu)
#define DESTROY_TIMER_HASH_TABLE()
uint64_t milliseconds_after_process_epoch() const
grpc_core::TraceFlag grpc_timer_check_trace(false, "timer_check")
void grpc_kick_poller(void)
double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats *stats)
grpc_core::Timestamp min_timer
#define gpr_spinlock_unlock(lock)
void grpc_timer_heap_init(grpc_timer_heap *heap)
GPRAPI void gpr_mu_lock(gpr_mu *mu)
constexpr size_t HashPointer(T *p, size_t range)
struct shared_mutables GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE)
static grpc_timer * g_timer_ht[NUM_HASH_BUCKETS]
static constexpr Duration Epsilon()
@ GRPC_TIMERS_CHECKED_AND_EMPTY
#define INIT_TIMER_HASH_TABLE()
bool grpc_timer_heap_is_empty(grpc_timer_heap *heap)
static struct shared_mutables g_shared_mutables
#define VALIDATE_NON_PENDING_TIMER(t)
static void timer_list_init()
grpc_core::Timestamp min_deadline
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
static constexpr Timestamp FromMillisecondsAfterProcessEpoch(int64_t millis)
#define gpr_spinlock_trylock(lock)
static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index)
void grpc_timer_heap_pop(grpc_timer_heap *heap)
T Clamp(T val, T min, T max)
#define GRPC_ERROR_REF(err)
grpc_timer * grpc_timer_heap_top(grpc_timer_heap *heap)
static gpr_mu g_hash_mu[NUM_HASH_BUCKETS]
grpc_core::TraceFlag grpc_timer_trace(false, "timer")
struct grpc_timer * hash_table_next
AllocList * next[kMaxLevel]
static bool is_in_ht(grpc_timer *t)
static void destroy_timer_ht()
static void list_join(grpc_timer *head, grpc_timer *timer)
static grpc_timer_check_result run_some_expired_timers(grpc_core::Timestamp now, grpc_core::Timestamp *next, grpc_error_handle error)
static grpc_timer * pop_one(timer_shard *shard, grpc_core::Timestamp now)
grpc_timer_vtable grpc_generic_timer_vtable
#define GRPC_ERROR_UNREF(err)
static void Run(const DebugLocation &location, grpc_closure *closure, grpc_error_handle error)
static void timer_list_shutdown()
#define MIN_QUEUE_WINDOW_DURATION
grpc_core::Timestamp queue_deadline_cap
static void note_deadline_change(timer_shard *shard)
static constexpr Timestamp InfFuture()
grpc_time_averaged_stats stats
static bool refill_heap(timer_shard *shard, grpc_core::Timestamp now)
static timer_shard * g_shards
grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:39