diff options
author | Craig Tiller <ctiller@google.com> | 2015-09-22 12:33:20 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2015-09-22 12:33:20 -0700 |
commit | a82950e68318a6aab6fe894fa39f7fa616c4647b (patch) | |
tree | 7d02bd1e9e1cbae1f14ad4ad1e06d3ae81a96dfe /src/core/iomgr/alarm.c | |
parent | 8af4c337181322cc4fb396199c90f574cfb4163f (diff) |
clang-format all core files
Diffstat (limited to 'src/core/iomgr/alarm.c')
-rw-r--r-- | src/core/iomgr/alarm.c | 390 |
1 files changed, 178 insertions, 212 deletions
diff --git a/src/core/iomgr/alarm.c b/src/core/iomgr/alarm.c index 31de551151..0ba5361606 100644 --- a/src/core/iomgr/alarm.c +++ b/src/core/iomgr/alarm.c @@ -48,8 +48,7 @@ #define MIN_QUEUE_WINDOW_DURATION 0.01 #define MAX_QUEUE_WINDOW_DURATION 1 -typedef struct -{ +typedef struct { gpr_mu mu; grpc_time_averaged_stats stats; /* All and only alarms with deadlines <= this will be in the heap. */ @@ -73,140 +72,127 @@ static shard_type g_shards[NUM_SHARDS]; /* Protected by g_mu */ static shard_type *g_shard_queue[NUM_SHARDS]; -static int run_some_expired_alarms (grpc_exec_ctx * exec_ctx, gpr_timespec now, gpr_timespec * next, int success); +static int run_some_expired_alarms(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next, int success); -static gpr_timespec -compute_min_deadline (shard_type * shard) -{ - return grpc_alarm_heap_is_empty (&shard->heap) ? shard->queue_deadline_cap : grpc_alarm_heap_top (&shard->heap)->deadline; +static gpr_timespec compute_min_deadline(shard_type *shard) { + return grpc_alarm_heap_is_empty(&shard->heap) + ? shard->queue_deadline_cap + : grpc_alarm_heap_top(&shard->heap)->deadline; } -void -grpc_alarm_list_init (gpr_timespec now) -{ +void grpc_alarm_list_init(gpr_timespec now) { gpr_uint32 i; - gpr_mu_init (&g_mu); - gpr_mu_init (&g_checker_mu); + gpr_mu_init(&g_mu); + gpr_mu_init(&g_checker_mu); g_clock_type = now.clock_type; - for (i = 0; i < NUM_SHARDS; i++) - { - shard_type *shard = &g_shards[i]; - gpr_mu_init (&shard->mu); - grpc_time_averaged_stats_init (&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1, 0.5); - shard->queue_deadline_cap = now; - shard->shard_queue_index = i; - grpc_alarm_heap_init (&shard->heap); - shard->list.next = shard->list.prev = &shard->list; - shard->min_deadline = compute_min_deadline (shard); - g_shard_queue[i] = shard; - } + for (i = 0; i < NUM_SHARDS; i++) { + shard_type *shard = &g_shards[i]; + gpr_mu_init(&shard->mu); + grpc_time_averaged_stats_init(&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1, + 0.5); + shard->queue_deadline_cap = now; + shard->shard_queue_index = i; + grpc_alarm_heap_init(&shard->heap); + shard->list.next = shard->list.prev = &shard->list; + shard->min_deadline = compute_min_deadline(shard); + g_shard_queue[i] = shard; + } } -void -grpc_alarm_list_shutdown (grpc_exec_ctx *exec_ctx) -{ +void grpc_alarm_list_shutdown(grpc_exec_ctx *exec_ctx) { int i; - run_some_expired_alarms (exec_ctx, gpr_inf_future (g_clock_type), NULL, 0); - for (i = 0; i < NUM_SHARDS; i++) - { - shard_type *shard = &g_shards[i]; - gpr_mu_destroy (&shard->mu); - grpc_alarm_heap_destroy (&shard->heap); - } - gpr_mu_destroy (&g_mu); - gpr_mu_destroy (&g_checker_mu); + run_some_expired_alarms(exec_ctx, gpr_inf_future(g_clock_type), NULL, 0); + for (i = 0; i < NUM_SHARDS; i++) { + shard_type *shard = &g_shards[i]; + gpr_mu_destroy(&shard->mu); + grpc_alarm_heap_destroy(&shard->heap); + } + gpr_mu_destroy(&g_mu); + gpr_mu_destroy(&g_checker_mu); } /* This is a cheap, but good enough, pointer hash for sharding the tasks: */ -static size_t -shard_idx (const grpc_alarm * info) -{ - size_t x = (size_t) info; +static size_t shard_idx(const grpc_alarm *info) { + size_t x = (size_t)info; return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) & (NUM_SHARDS - 1); } -static double -ts_to_dbl (gpr_timespec ts) -{ - return (double) ts.tv_sec + 1e-9 * ts.tv_nsec; +static double ts_to_dbl(gpr_timespec ts) { + return (double)ts.tv_sec + 1e-9 * ts.tv_nsec; } -static gpr_timespec -dbl_to_ts (double d) -{ +static gpr_timespec dbl_to_ts(double d) { gpr_timespec ts; - ts.tv_sec = (time_t) d; - ts.tv_nsec = (int) (1e9 * (d - (double) ts.tv_sec)); + ts.tv_sec = (time_t)d; + ts.tv_nsec = (int)(1e9 * (d - (double)ts.tv_sec)); ts.clock_type = GPR_TIMESPAN; return ts; } -static void -list_join (grpc_alarm * head, grpc_alarm * alarm) -{ +static void list_join(grpc_alarm *head, grpc_alarm *alarm) { alarm->next = head; alarm->prev = head->prev; alarm->next->prev = alarm->prev->next = alarm; } -static void -list_remove (grpc_alarm * alarm) -{ +static void list_remove(grpc_alarm *alarm) { alarm->next->prev = alarm->prev; alarm->prev->next = alarm->next; } -static void -swap_adjacent_shards_in_queue (gpr_uint32 first_shard_queue_index) -{ +static void swap_adjacent_shards_in_queue(gpr_uint32 first_shard_queue_index) { shard_type *temp; temp = g_shard_queue[first_shard_queue_index]; - g_shard_queue[first_shard_queue_index] = g_shard_queue[first_shard_queue_index + 1]; + g_shard_queue[first_shard_queue_index] = + g_shard_queue[first_shard_queue_index + 1]; g_shard_queue[first_shard_queue_index + 1] = temp; - g_shard_queue[first_shard_queue_index]->shard_queue_index = first_shard_queue_index; - g_shard_queue[first_shard_queue_index + 1]->shard_queue_index = first_shard_queue_index + 1; + g_shard_queue[first_shard_queue_index]->shard_queue_index = + first_shard_queue_index; + g_shard_queue[first_shard_queue_index + 1]->shard_queue_index = + first_shard_queue_index + 1; } -static void -note_deadline_change (shard_type * shard) -{ - while (shard->shard_queue_index > 0 && gpr_time_cmp (shard->min_deadline, g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) - { - swap_adjacent_shards_in_queue (shard->shard_queue_index - 1); - } - while (shard->shard_queue_index < NUM_SHARDS - 1 && gpr_time_cmp (shard->min_deadline, g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) - { - swap_adjacent_shards_in_queue (shard->shard_queue_index); - } +static void note_deadline_change(shard_type *shard) { + while (shard->shard_queue_index > 0 && + gpr_time_cmp( + shard->min_deadline, + g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) { + swap_adjacent_shards_in_queue(shard->shard_queue_index - 1); + } + while (shard->shard_queue_index < NUM_SHARDS - 1 && + gpr_time_cmp( + shard->min_deadline, + g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) { + swap_adjacent_shards_in_queue(shard->shard_queue_index); + } } -void -grpc_alarm_init (grpc_exec_ctx * exec_ctx, grpc_alarm * alarm, gpr_timespec deadline, grpc_iomgr_cb_func alarm_cb, void *alarm_cb_arg, gpr_timespec now) -{ +void grpc_alarm_init(grpc_exec_ctx *exec_ctx, grpc_alarm *alarm, + gpr_timespec deadline, grpc_iomgr_cb_func alarm_cb, + void *alarm_cb_arg, gpr_timespec now) { int is_first_alarm = 0; - shard_type *shard = &g_shards[shard_idx (alarm)]; - GPR_ASSERT (deadline.clock_type == g_clock_type); - GPR_ASSERT (now.clock_type == g_clock_type); - grpc_closure_init (&alarm->closure, alarm_cb, alarm_cb_arg); + shard_type *shard = &g_shards[shard_idx(alarm)]; + GPR_ASSERT(deadline.clock_type == g_clock_type); + GPR_ASSERT(now.clock_type == g_clock_type); + grpc_closure_init(&alarm->closure, alarm_cb, alarm_cb_arg); alarm->deadline = deadline; alarm->triggered = 0; /* TODO(ctiller): check deadline expired */ - gpr_mu_lock (&shard->mu); - grpc_time_averaged_stats_add_sample (&shard->stats, ts_to_dbl (gpr_time_sub (deadline, now))); - if (gpr_time_cmp (deadline, shard->queue_deadline_cap) < 0) - { - is_first_alarm = grpc_alarm_heap_add (&shard->heap, alarm); - } - else - { - alarm->heap_index = INVALID_HEAP_INDEX; - list_join (&shard->list, alarm); - } - gpr_mu_unlock (&shard->mu); + gpr_mu_lock(&shard->mu); + grpc_time_averaged_stats_add_sample(&shard->stats, + ts_to_dbl(gpr_time_sub(deadline, now))); + if (gpr_time_cmp(deadline, shard->queue_deadline_cap) < 0) { + is_first_alarm = grpc_alarm_heap_add(&shard->heap, alarm); + } else { + alarm->heap_index = INVALID_HEAP_INDEX; + list_join(&shard->list, alarm); + } + gpr_mu_unlock(&shard->mu); /* Deadline may have decreased, we need to adjust the master queue. Note that there is a potential racy unlocked region here. There could be a @@ -219,42 +205,34 @@ grpc_alarm_init (grpc_exec_ctx * exec_ctx, grpc_alarm * alarm, gpr_timespec dead trigger the new alarm because the min_deadline hadn't yet been reduced. In that case, the alarm will simply have to wait for the next grpc_alarm_check. */ - if (is_first_alarm) - { - gpr_mu_lock (&g_mu); - if (gpr_time_cmp (deadline, shard->min_deadline) < 0) - { - gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline; - shard->min_deadline = deadline; - note_deadline_change (shard); - if (shard->shard_queue_index == 0 && gpr_time_cmp (deadline, old_min_deadline) < 0) - { - grpc_kick_poller (); - } - } - gpr_mu_unlock (&g_mu); + if (is_first_alarm) { + gpr_mu_lock(&g_mu); + if (gpr_time_cmp(deadline, shard->min_deadline) < 0) { + gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline; + shard->min_deadline = deadline; + note_deadline_change(shard); + if (shard->shard_queue_index == 0 && + gpr_time_cmp(deadline, old_min_deadline) < 0) { + grpc_kick_poller(); + } } + gpr_mu_unlock(&g_mu); + } } -void -grpc_alarm_cancel (grpc_exec_ctx * exec_ctx, grpc_alarm * alarm) -{ - shard_type *shard = &g_shards[shard_idx (alarm)]; - gpr_mu_lock (&shard->mu); - if (!alarm->triggered) - { - grpc_exec_ctx_enqueue (exec_ctx, &alarm->closure, 0); - alarm->triggered = 1; - if (alarm->heap_index == INVALID_HEAP_INDEX) - { - list_remove (alarm); - } - else - { - grpc_alarm_heap_remove (&shard->heap, alarm); - } +void grpc_alarm_cancel(grpc_exec_ctx *exec_ctx, grpc_alarm *alarm) { + shard_type *shard = &g_shards[shard_idx(alarm)]; + gpr_mu_lock(&shard->mu); + if (!alarm->triggered) { + grpc_exec_ctx_enqueue(exec_ctx, &alarm->closure, 0); + alarm->triggered = 1; + if (alarm->heap_index == INVALID_HEAP_INDEX) { + list_remove(alarm); + } else { + grpc_alarm_heap_remove(&shard->heap, alarm); } - gpr_mu_unlock (&shard->mu); + } + gpr_mu_unlock(&shard->mu); } /* This is called when the queue is empty and "now" has reached the @@ -262,126 +240,114 @@ grpc_alarm_cancel (grpc_exec_ctx * exec_ctx, grpc_alarm * alarm) for alarms that fall at or under it. Returns true if the queue is no longer empty. REQUIRES: shard->mu locked */ -static int -refill_queue (shard_type * shard, gpr_timespec now) -{ +static int refill_queue(shard_type *shard, gpr_timespec now) { /* Compute the new queue window width and bound by the limits: */ - double computed_deadline_delta = grpc_time_averaged_stats_update_average (&shard->stats) * ADD_DEADLINE_SCALE; - double deadline_delta = GPR_CLAMP (computed_deadline_delta, MIN_QUEUE_WINDOW_DURATION, - MAX_QUEUE_WINDOW_DURATION); + double computed_deadline_delta = + grpc_time_averaged_stats_update_average(&shard->stats) * + ADD_DEADLINE_SCALE; + double deadline_delta = + GPR_CLAMP(computed_deadline_delta, MIN_QUEUE_WINDOW_DURATION, + MAX_QUEUE_WINDOW_DURATION); grpc_alarm *alarm, *next; /* Compute the new cap and put all alarms under it into the queue: */ - shard->queue_deadline_cap = gpr_time_add (gpr_time_max (now, shard->queue_deadline_cap), dbl_to_ts (deadline_delta)); - for (alarm = shard->list.next; alarm != &shard->list; alarm = next) - { - next = alarm->next; - - if (gpr_time_cmp (alarm->deadline, shard->queue_deadline_cap) < 0) - { - list_remove (alarm); - grpc_alarm_heap_add (&shard->heap, alarm); - } + shard->queue_deadline_cap = gpr_time_add( + gpr_time_max(now, shard->queue_deadline_cap), dbl_to_ts(deadline_delta)); + for (alarm = shard->list.next; alarm != &shard->list; alarm = next) { + next = alarm->next; + + if (gpr_time_cmp(alarm->deadline, shard->queue_deadline_cap) < 0) { + list_remove(alarm); + grpc_alarm_heap_add(&shard->heap, alarm); } - return !grpc_alarm_heap_is_empty (&shard->heap); + } + return !grpc_alarm_heap_is_empty(&shard->heap); } /* This pops the next non-cancelled alarm with deadline <= now from the queue, or returns NULL if there isn't one. REQUIRES: shard->mu locked */ -static grpc_alarm * -pop_one (shard_type * shard, gpr_timespec now) -{ +static grpc_alarm *pop_one(shard_type *shard, gpr_timespec now) { grpc_alarm *alarm; - for (;;) - { - if (grpc_alarm_heap_is_empty (&shard->heap)) - { - if (gpr_time_cmp (now, shard->queue_deadline_cap) < 0) - return NULL; - if (!refill_queue (shard, now)) - return NULL; - } - alarm = grpc_alarm_heap_top (&shard->heap); - if (gpr_time_cmp (alarm->deadline, now) > 0) - return NULL; - alarm->triggered = 1; - grpc_alarm_heap_pop (&shard->heap); - return alarm; + for (;;) { + if (grpc_alarm_heap_is_empty(&shard->heap)) { + if (gpr_time_cmp(now, shard->queue_deadline_cap) < 0) return NULL; + if (!refill_queue(shard, now)) return NULL; } + alarm = grpc_alarm_heap_top(&shard->heap); + if (gpr_time_cmp(alarm->deadline, now) > 0) return NULL; + alarm->triggered = 1; + grpc_alarm_heap_pop(&shard->heap); + return alarm; + } } /* REQUIRES: shard->mu unlocked */ -static size_t -pop_alarms (grpc_exec_ctx * exec_ctx, shard_type * shard, gpr_timespec now, gpr_timespec * new_min_deadline, int success) -{ +static size_t pop_alarms(grpc_exec_ctx *exec_ctx, shard_type *shard, + gpr_timespec now, gpr_timespec *new_min_deadline, + int success) { size_t n = 0; grpc_alarm *alarm; - gpr_mu_lock (&shard->mu); - while ((alarm = pop_one (shard, now))) - { - grpc_exec_ctx_enqueue (exec_ctx, &alarm->closure, success); - n++; - } - *new_min_deadline = compute_min_deadline (shard); - gpr_mu_unlock (&shard->mu); + gpr_mu_lock(&shard->mu); + while ((alarm = pop_one(shard, now))) { + grpc_exec_ctx_enqueue(exec_ctx, &alarm->closure, success); + n++; + } + *new_min_deadline = compute_min_deadline(shard); + gpr_mu_unlock(&shard->mu); return n; } -static int -run_some_expired_alarms (grpc_exec_ctx * exec_ctx, gpr_timespec now, gpr_timespec * next, int success) -{ +static int run_some_expired_alarms(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next, int success) { size_t n = 0; /* TODO(ctiller): verify that there are any alarms (atomically) here */ - if (gpr_mu_trylock (&g_checker_mu)) - { - gpr_mu_lock (&g_mu); - - while (gpr_time_cmp (g_shard_queue[0]->min_deadline, now) < 0) - { - gpr_timespec new_min_deadline; - - /* For efficiency, we pop as many available alarms as we can from the - shard. This may violate perfect alarm deadline ordering, but that - shouldn't be a big deal because we don't make ordering guarantees. */ - n += pop_alarms (exec_ctx, g_shard_queue[0], now, &new_min_deadline, success); - - /* An grpc_alarm_init() on the shard could intervene here, adding a new - alarm that is earlier than new_min_deadline. However, - grpc_alarm_init() will block on the master_lock before it can call - set_min_deadline, so this one will complete first and then the AddAlarm - will reduce the min_deadline (perhaps unnecessarily). */ - g_shard_queue[0]->min_deadline = new_min_deadline; - note_deadline_change (g_shard_queue[0]); - } - - if (next) - { - *next = gpr_time_min (*next, g_shard_queue[0]->min_deadline); - } - - gpr_mu_unlock (&g_mu); - gpr_mu_unlock (&g_checker_mu); + if (gpr_mu_trylock(&g_checker_mu)) { + gpr_mu_lock(&g_mu); + + while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) { + gpr_timespec new_min_deadline; + + /* For efficiency, we pop as many available alarms as we can from the + shard. This may violate perfect alarm deadline ordering, but that + shouldn't be a big deal because we don't make ordering guarantees. */ + n += pop_alarms(exec_ctx, g_shard_queue[0], now, &new_min_deadline, + success); + + /* An grpc_alarm_init() on the shard could intervene here, adding a new + alarm that is earlier than new_min_deadline. However, + grpc_alarm_init() will block on the master_lock before it can call + set_min_deadline, so this one will complete first and then the AddAlarm + will reduce the min_deadline (perhaps unnecessarily). */ + g_shard_queue[0]->min_deadline = new_min_deadline; + note_deadline_change(g_shard_queue[0]); } - return (int) n; + if (next) { + *next = gpr_time_min(*next, g_shard_queue[0]->min_deadline); + } + + gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_checker_mu); + } + + return (int)n; } -int -grpc_alarm_check (grpc_exec_ctx * exec_ctx, gpr_timespec now, gpr_timespec * next) -{ - GPR_ASSERT (now.clock_type == g_clock_type); - return run_some_expired_alarms (exec_ctx, now, next, gpr_time_cmp (now, gpr_inf_future (now.clock_type)) != 0); +int grpc_alarm_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next) { + GPR_ASSERT(now.clock_type == g_clock_type); + return run_some_expired_alarms( + exec_ctx, now, next, + gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0); } -gpr_timespec -grpc_alarm_list_next_timeout (void) -{ +gpr_timespec grpc_alarm_list_next_timeout(void) { gpr_timespec out; - gpr_mu_lock (&g_mu); + gpr_mu_lock(&g_mu); out = g_shard_queue[0]->min_deadline; - gpr_mu_unlock (&g_mu); + gpr_mu_unlock(&g_mu); return out; } |