aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/lib/iomgr/timer_generic.cc16
-rw-r--r--src/core/lib/iomgr/timer_heap.cc4
-rw-r--r--src/core/lib/iomgr/timer_heap.h6
-rw-r--r--src/core/lib/iomgr/timer_manager.cc8
-rw-r--r--src/core/lib/iomgr/timer_manager.h4
5 files changed, 20 insertions, 18 deletions
diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc
index aba5539199..6a925add80 100644
--- a/src/core/lib/iomgr/timer_generic.cc
+++ b/src/core/lib/iomgr/timer_generic.cc
@@ -48,22 +48,22 @@ grpc_core::TraceFlag grpc_timer_trace(false, "timer");
grpc_core::TraceFlag grpc_timer_check_trace(false, "timer_check");
/* A "timer shard". Contains a 'heap' and a 'list' of timers. All timers with
- * deadlines earlier than 'queue_deadline" cap are maintained in the heap and
+ * deadlines earlier than 'queue_deadline_cap' are maintained in the heap and
* others are maintained in the list (unordered). This helps to keep the number
* of elements in the heap low.
*
* The 'queue_deadline_cap' gets recomputed periodically based on the timer
* stats maintained in 'stats' and the relevant timers are then moved from the
- * 'list' to 'heap'
+ * 'list' to 'heap'.
*/
typedef struct {
gpr_mu mu;
grpc_time_averaged_stats stats;
- /* All and only timers with deadlines <= this will be in the heap. */
+ /* All and only timers with deadlines < this will be in the heap. */
grpc_millis queue_deadline_cap;
- /* The deadline of the next timer due in this shard */
+ /* The deadline of the next timer due in this shard. */
grpc_millis min_deadline;
- /* Index of this timer_shard in the g_shard_queue */
+ /* Index of this timer_shard in the g_shard_queue. */
uint32_t shard_queue_index;
/* This holds all timers with deadlines < queue_deadline_cap. Timers in this
list have the top bit of their deadline set to 0. */
@@ -85,7 +85,7 @@ static timer_shard** g_shard_queue;
#ifndef NDEBUG
-/* == Hash table for duplicate timer detection == */
+/* == DEBUG ONLY: hash table for duplicate timer detection == */
#define NUM_HASH_BUCKETS 1009 /* Prime number close to 1000 */
@@ -177,7 +177,7 @@ static void remove_from_ht(grpc_timer* t) {
t->hash_table_next = nullptr;
}
-/* If a timer is added to a timer shard (either heap or a list), it cannot
+/* If a timer is added to a timer shard (either heap or a list), it must
* be pending. A timer is added to hash table only-if it is added to the
* timer shard.
* Therefore, if timer->pending is false, it cannot be in hash table */
@@ -489,7 +489,7 @@ static void timer_cancel(grpc_timer* timer) {
'queue_deadline_cap') into into shard->heap.
Returns 'true' if shard->heap has atleast ONE element
REQUIRES: shard->mu locked */
-static int refill_heap(timer_shard* shard, grpc_millis now) {
+static bool refill_heap(timer_shard* shard, grpc_millis now) {
/* Compute the new queue window width and bound by the limits: */
double computed_deadline_delta =
grpc_time_averaged_stats_update_average(&shard->stats) *
diff --git a/src/core/lib/iomgr/timer_heap.cc b/src/core/lib/iomgr/timer_heap.cc
index 0c17d607eb..2c6a599149 100644
--- a/src/core/lib/iomgr/timer_heap.cc
+++ b/src/core/lib/iomgr/timer_heap.cc
@@ -95,7 +95,7 @@ void grpc_timer_heap_init(grpc_timer_heap* heap) {
void grpc_timer_heap_destroy(grpc_timer_heap* heap) { gpr_free(heap->timers); }
-int grpc_timer_heap_add(grpc_timer_heap* heap, grpc_timer* timer) {
+bool grpc_timer_heap_add(grpc_timer_heap* heap, grpc_timer* timer) {
if (heap->timer_count == heap->timer_capacity) {
heap->timer_capacity =
GPR_MAX(heap->timer_capacity + 1, heap->timer_capacity * 3 / 2);
@@ -122,7 +122,7 @@ void grpc_timer_heap_remove(grpc_timer_heap* heap, grpc_timer* timer) {
note_changed_priority(heap, heap->timers[i]);
}
-int grpc_timer_heap_is_empty(grpc_timer_heap* heap) {
+bool grpc_timer_heap_is_empty(grpc_timer_heap* heap) {
return heap->timer_count == 0;
}
diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h
index 503365d4cd..7b983e7133 100644
--- a/src/core/lib/iomgr/timer_heap.h
+++ b/src/core/lib/iomgr/timer_heap.h
@@ -29,8 +29,8 @@ typedef struct {
uint32_t timer_capacity;
} grpc_timer_heap;
-/* return 1 if the new timer is the first timer in the heap */
-int grpc_timer_heap_add(grpc_timer_heap* heap, grpc_timer* timer);
+/* return true if the new timer is the first timer in the heap */
+bool grpc_timer_heap_add(grpc_timer_heap* heap, grpc_timer* timer);
void grpc_timer_heap_init(grpc_timer_heap* heap);
void grpc_timer_heap_destroy(grpc_timer_heap* heap);
@@ -39,6 +39,6 @@ void grpc_timer_heap_remove(grpc_timer_heap* heap, grpc_timer* timer);
grpc_timer* grpc_timer_heap_top(grpc_timer_heap* heap);
void grpc_timer_heap_pop(grpc_timer_heap* heap);
-int grpc_timer_heap_is_empty(grpc_timer_heap* heap);
+bool grpc_timer_heap_is_empty(grpc_timer_heap* heap);
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H */
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index e272d228f8..54f19a9259 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -100,8 +100,7 @@ static void start_timer_thread_and_unlock(void) {
void grpc_timer_manager_tick() {
grpc_core::ExecCtx exec_ctx;
- grpc_millis next = GRPC_MILLIS_INF_FUTURE;
- grpc_timer_check(&next);
+ grpc_timer_check(nullptr);
}
static void run_some_timers() {
@@ -110,9 +109,12 @@ static void run_some_timers() {
// remove a waiter from the pool, and start another thread if necessary
--g_waiter_count;
if (g_waiter_count == 0 && g_threaded) {
+ // The number of timer threads is always increasing until all the threads
+ // are stopped. In rare cases, if a large number of timers fire
+ // simultaneously, we may end up using a large number of threads.
start_timer_thread_and_unlock();
} else {
- // if there's no thread waiting with a timeout, kick an existing
+ // if there's no thread waiting with a timeout, kick an existing untimed
// waiter so that the next deadline is not missed
if (!g_has_timed_waiter) {
if (grpc_timer_check_trace.enabled()) {
diff --git a/src/core/lib/iomgr/timer_manager.h b/src/core/lib/iomgr/timer_manager.h
index 3c4cdda2c8..00dcdc461b 100644
--- a/src/core/lib/iomgr/timer_manager.h
+++ b/src/core/lib/iomgr/timer_manager.h
@@ -23,8 +23,8 @@
#include <stdbool.h>
-/* Timer Manager tries to keep one thread waiting for the next timeout at all
- times */
+/* Timer Manager tries to keep only one thread waiting for the next timeout at
+ all times, and thus effectively preventing the thundering herd problem. */
void grpc_timer_manager_init(void);
void grpc_timer_manager_shutdown(void);