Refine neighbourhood reassignment

pull/10932/head
Craig Tiller 8 years ago
parent ba550da853
commit e00d7335de
  1. 48
      src/core/lib/iomgr/ev_epoll1_linux.c

@ -117,6 +117,7 @@ typedef struct pollset_neighbourhood {
struct grpc_pollset { struct grpc_pollset {
gpr_mu mu; gpr_mu mu;
pollset_neighbourhood *neighbourhood; pollset_neighbourhood *neighbourhood;
bool reassigning_neighbourhood;
grpc_pollset_worker *root_worker; grpc_pollset_worker *root_worker;
bool kicked_without_poller; bool kicked_without_poller;
bool seen_inactive; bool seen_inactive;
@ -394,20 +395,33 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
*mu = &pollset->mu; *mu = &pollset->mu;
pollset->neighbourhood = &g_neighbourhoods[choose_neighbourhood()]; pollset->neighbourhood = &g_neighbourhoods[choose_neighbourhood()];
pollset->seen_inactive = true; pollset->seen_inactive = true;
pollset->next = pollset->prev = pollset;
} }
static void pollset_destroy(grpc_pollset *pollset) { static void pollset_destroy(grpc_pollset *pollset) {
gpr_mu_lock(&pollset->mu);
if (!pollset->seen_inactive) { if (!pollset->seen_inactive) {
gpr_mu_lock(&pollset->neighbourhood->mu); pollset_neighbourhood *neighbourhood = pollset->neighbourhood;
pollset->prev->next = pollset->next; gpr_mu_unlock(&pollset->mu);
pollset->next->prev = pollset->prev; retry_lock_neighbourhood:
if (pollset == pollset->neighbourhood->active_root) { gpr_mu_lock(&neighbourhood->mu);
pollset->neighbourhood->active_root = gpr_mu_lock(&pollset->mu);
pollset->next == pollset ? NULL : pollset->next; if (!pollset->seen_inactive) {
if (pollset->neighbourhood != neighbourhood) {
gpr_mu_unlock(&neighbourhood->mu);
neighbourhood = pollset->neighbourhood;
gpr_mu_unlock(&pollset->mu);
goto retry_lock_neighbourhood;
}
pollset->prev->next = pollset->next;
pollset->next->prev = pollset->prev;
if (pollset == pollset->neighbourhood->active_root) {
pollset->neighbourhood->active_root =
pollset->next == pollset ? NULL : pollset->next;
}
} }
gpr_mu_unlock(&pollset->neighbourhood->mu); gpr_mu_unlock(&pollset->neighbourhood->mu);
} }
gpr_mu_unlock(&pollset->mu);
gpr_mu_destroy(&pollset->mu); gpr_mu_destroy(&pollset->mu);
} }
@ -543,8 +557,13 @@ static bool begin_worker(grpc_pollset *pollset, grpc_pollset_worker *worker,
if (pollset->seen_inactive) { if (pollset->seen_inactive) {
// pollset has been observed to be inactive, we need to move back to the // pollset has been observed to be inactive, we need to move back to the
// active list // active list
pollset_neighbourhood *neighbourhood = pollset->neighbourhood = bool is_reassigning = false;
&g_neighbourhoods[choose_neighbourhood()]; if (!pollset->reassigning_neighbourhood) {
is_reassigning = true;
pollset->reassigning_neighbourhood = true;
pollset->neighbourhood = &g_neighbourhoods[choose_neighbourhood()];
}
pollset_neighbourhood *neighbourhood = pollset->neighbourhood;
gpr_mu_unlock(&pollset->mu); gpr_mu_unlock(&pollset->mu);
// pollset unlocked: state may change (even worker->kick_state) // pollset unlocked: state may change (even worker->kick_state)
retry_lock_neighbourhood: retry_lock_neighbourhood:
@ -569,6 +588,10 @@ static bool begin_worker(grpc_pollset *pollset, grpc_pollset_worker *worker,
pollset->next->prev = pollset->prev->next = pollset; pollset->next->prev = pollset->prev->next = pollset;
} }
} }
if (is_reassigning) {
GPR_ASSERT(pollset->reassigning_neighbourhood);
pollset->reassigning_neighbourhood = false;
}
gpr_mu_unlock(&neighbourhood->mu); gpr_mu_unlock(&neighbourhood->mu);
} }
worker_insert(pollset, worker); worker_insert(pollset, worker);
@ -629,14 +652,11 @@ static bool check_neighbourhood_for_available_poller(
if (!found_worker) { if (!found_worker) {
inspect->seen_inactive = true; inspect->seen_inactive = true;
if (inspect == neighbourhood->active_root) { if (inspect == neighbourhood->active_root) {
if (inspect->next == neighbourhood->active_root) { neighbourhood->active_root = inspect->next == inspect ? NULL : inspect->next;
neighbourhood->active_root = NULL;
} else {
neighbourhood->active_root = inspect->next;
}
} }
inspect->next->prev = inspect->prev; inspect->next->prev = inspect->prev;
inspect->prev->next = inspect->next; inspect->prev->next = inspect->next;
inspect->next = inspect->prev = NULL;
} }
gpr_mu_unlock(&inspect->mu); gpr_mu_unlock(&inspect->mu);
} while (!found_worker); } while (!found_worker);

Loading…
Cancel
Save