#include <grpc/support/port_platform.h>
#include <inttypes.h>
#include <string>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include <grpc/support/alloc.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/spinlock.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/gprpp/time_averaged_stats.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/timer_heap.h"
#define INVALID_HEAP_INDEX …
#define ADD_DEADLINE_SCALE …
#define MIN_QUEUE_WINDOW_DURATION …
#define MAX_QUEUE_WINDOW_DURATION …
grpc_core::TraceFlag grpc_timer_trace(false, "timer");
grpc_core::TraceFlag grpc_timer_check_trace(false, "timer_check");
struct timer_shard { … };
static size_t g_num_shards;
static timer_shard* g_shards;
static timer_shard** g_shard_queue;
#ifndef NDEBUG
#define NUM_HASH_BUCKETS …
static gpr_mu g_hash_mu[NUM_HASH_BUCKETS];
static grpc_timer* g_timer_ht[NUM_HASH_BUCKETS] = …;
static void init_timer_ht() { … }
static void destroy_timer_ht() { … }
static bool is_in_ht(grpc_timer* t) { … }
static void add_to_ht(grpc_timer* t) { … }
static void remove_from_ht(grpc_timer* t) { … }
static void validate_non_pending_timer(grpc_timer* t) { … }
#define INIT_TIMER_HASH_TABLE() …
#define DESTROY_TIMER_HASH_TABLE() …
#define ADD_TO_HASH_TABLE(t) …
#define REMOVE_FROM_HASH_TABLE(t) …
#define VALIDATE_NON_PENDING_TIMER(t) …
#else
#define INIT_TIMER_HASH_TABLE …
#define DESTROY_TIMER_HASH_TABLE …
#define ADD_TO_HASH_TABLE …
#define REMOVE_FROM_HASH_TABLE …
#define VALIDATE_NON_PENDING_TIMER …
#endif
static thread_local int64_t g_last_seen_min_timer;
struct shared_mutables { … } GPR_ALIGN_STRUCT(…);
static struct shared_mutables g_shared_mutables;
static grpc_timer_check_result run_some_expired_timers(
grpc_core::Timestamp now, grpc_core::Timestamp* next,
grpc_error_handle error);
static grpc_core::Timestamp compute_min_deadline(timer_shard* shard) { … }
static void timer_list_init() { … }
static void timer_list_shutdown() { … }
static void list_join(grpc_timer* head, grpc_timer* timer) { … }
static void list_remove(grpc_timer* timer) { … }
static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index) { … }
static void note_deadline_change(timer_shard* shard) { … }
void grpc_timer_init_unset(grpc_timer* timer) { … }
static void timer_init(grpc_timer* timer, grpc_core::Timestamp deadline,
grpc_closure* closure) { … }
static void timer_consume_kick(void) { … }
static void timer_cancel(grpc_timer* timer) { … }
static bool refill_heap(timer_shard* shard, grpc_core::Timestamp now) { … }
static grpc_timer* pop_one(timer_shard* shard, grpc_core::Timestamp now) { … }
static size_t pop_timers(timer_shard* shard, grpc_core::Timestamp now,
grpc_core::Timestamp* new_min_deadline,
grpc_error_handle error) { … }
static grpc_timer_check_result run_some_expired_timers(
grpc_core::Timestamp now, grpc_core::Timestamp* next,
grpc_error_handle error) { … }
static grpc_timer_check_result timer_check(grpc_core::Timestamp* next) { … }
grpc_timer_vtable grpc_generic_timer_vtable = …;