26 #include <type_traits>
36 namespace iomgr_engine {
44 return heap.is_empty()
47 heap.Top()->deadline);
60 shard.queue_deadline_cap =
63 shard.shard_queue_index =
i;
64 shard.list.next = shard.list.prev = &shard.list;
66 shard_queue_[
i] = &shard;
78 void ListRemove(Timer*
timer) {
86 temp = shard_queue_[first_shard_queue_index];
87 shard_queue_[first_shard_queue_index] =
88 shard_queue_[first_shard_queue_index + 1];
89 shard_queue_[first_shard_queue_index + 1] =
temp;
90 shard_queue_[first_shard_queue_index]->shard_queue_index =
91 first_shard_queue_index;
92 shard_queue_[first_shard_queue_index + 1]->shard_queue_index =
93 first_shard_queue_index + 1;
97 while (shard->shard_queue_index > 0 &&
99 shard_queue_[shard->shard_queue_index - 1]->min_deadline) {
102 while (shard->shard_queue_index <
num_shards_ - 1 &&
103 shard->min_deadline >
104 shard_queue_[shard->shard_queue_index + 1]->min_deadline) {
111 bool is_first_timer =
false;
117 timer->hash_table_next =
nullptr;
122 timer->pending =
true;
124 if (deadline <=
now) {
128 shard->stats.AddSample((deadline -
now).millis() / 1000.0);
130 if (deadline < shard->queue_deadline_cap) {
131 is_first_timer = shard->heap.Add(
timer);
134 ListJoin(&shard->list,
timer);
149 if (is_first_timer) {
151 if (deadline < shard->min_deadline) {
153 shard->min_deadline = deadline;
155 if (shard->shard_queue_index == 0 && deadline < old_min_deadline) {
157 std::memory_order_relaxed);
168 if (
timer->pending) {
169 timer->pending =
false;
173 shard->heap.Remove(
timer);
188 double deadline_delta =
194 queue_deadline_cap =
std::max(
now, queue_deadline_cap) +
199 auto timer_deadline =
203 if (timer_deadline < queue_deadline_cap) {
208 return !
heap.is_empty();
216 if (
heap.is_empty()) {
217 if (
now < queue_deadline_cap)
return nullptr;
218 if (!RefillHeap(
now))
return nullptr;
221 auto timer_deadline =
224 if (timer_deadline >
now)
return nullptr;
225 timer->pending =
false;
233 std::vector<experimental::EventEngine::Closure*>*
out) {
238 *new_min_deadline = ComputeMinDeadline();
247 std::vector<experimental::EventEngine::Closure*>
done;
255 while (shard_queue_[0]->min_deadline <
now ||
257 shard_queue_[0]->min_deadline ==
now)) {
263 shard_queue_[0]->PopTimers(
now, &new_min_deadline, &
done);
270 shard_queue_[0]->min_deadline = new_min_deadline;
279 shard_queue_[0]->min_deadline.milliseconds_after_process_epoch(),
280 std::memory_order_relaxed);
297 if (
next !=
nullptr) {
300 return std::vector<experimental::EventEngine::Closure*>();
304 std::vector<experimental::EventEngine::Closure*>
run =