Store schedulers_ and vtables_ in a 2D array

pull/16010/head
Sree Kuchibhotla 6 years ago
parent baaf4512a8
commit 68ad431864
  1. 102
      src/core/lib/iomgr/executor.cc

@ -338,55 +338,46 @@ void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) {
false /* is_short */); false /* is_short */);
} }
static const grpc_closure_scheduler_vtable vtables_[] = { static const grpc_closure_scheduler_vtable
{&default_enqueue_short, &default_enqueue_short, "def-ex-short"}, vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
{&default_enqueue_long, &default_enqueue_long, "def-ex-long"}, {{&default_enqueue_short, &default_enqueue_short, "def-ex-short"},
{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"}, {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}},
{&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}; {{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"},
{&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}};
static grpc_closure_scheduler schedulers_[] = {
{&vtables_[0]}, // Default short static grpc_closure_scheduler
{&vtables_[1]}, // Default long schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
{&vtables_[2]}, // Resolver short {{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]},
{&vtables_[3]} // Resolver long {&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}},
}; {{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]},
{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}};
const char* executor_name(GrpcExecutorType executor_type) {
switch (executor_type) {
case GRPC_DEFAULT_EXECUTOR:
return "default-executor";
case GRPC_RESOLVER_EXECUTOR:
return "resolver-executor";
default:
GPR_UNREACHABLE_CODE(return "unknown");
}
GPR_UNREACHABLE_CODE(return "unknown");
}
// grpc_executor_init() and grpc_executor_shutdown() functions are called in the // grpc_executor_init() and grpc_executor_shutdown() functions are called in the
// the grpc_init() and grpc_shutdown() code paths which are protected by a // the grpc_init() and grpc_shutdown() code paths which are protected by a
// global mutex. So it is okay to assume that these functions are thread-safe // global mutex. So it is okay to assume that these functions are thread-safe
void grpc_executor_init() { void grpc_executor_init() {
EXECUTOR_TRACE0("grpc_executor_init() enter"); EXECUTOR_TRACE0("grpc_executor_init() enter");
for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) {
// Return if grpc_executor_init() already called earlier
if (executors[i] != nullptr) {
// Ideally we should also assert that all executors i.e executor[0] to
// executor[GRPC_NUM_EXECUTORS-1] are != nullptr too.
GPR_ASSERT(i == 0);
break;
}
executors[i] = grpc_core::New<GrpcExecutor>( // Return if grpc_executor_init() is already called earlier
executor_name(static_cast<GrpcExecutorType>(i))); if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) {
executors[i]->Init(); GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr);
return;
} }
executors[GRPC_DEFAULT_EXECUTOR] =
grpc_core::New<GrpcExecutor>("default-executor");
executors[GRPC_RESOLVER_EXECUTOR] =
grpc_core::New<GrpcExecutor>("resolver-executor");
executors[GRPC_DEFAULT_EXECUTOR]->Init();
executors[GRPC_RESOLVER_EXECUTOR]->Init();
EXECUTOR_TRACE0("grpc_executor_init() done"); EXECUTOR_TRACE0("grpc_executor_init() done");
} }
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
GrpcExecutorJobType job_type) { GrpcExecutorJobType job_type) {
return &schedulers_[(executor_type * GRPC_NUM_EXECUTORS) + job_type]; return &schedulers_[executor_type][job_type];
} }
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) { grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
@ -395,32 +386,33 @@ grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
void grpc_executor_shutdown() { void grpc_executor_shutdown() {
EXECUTOR_TRACE0("grpc_executor_shutdown() enter"); EXECUTOR_TRACE0("grpc_executor_shutdown() enter");
for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) {
// Return if grpc_executor_shutdown() is already called earlier // Return if grpc_executor_shutdown() is already called earlier
if (executors[i] == nullptr) { if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) {
// Ideally we should also assert that all executors i.e executor[0] to GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr);
// executor[GRPC_NUM_EXECUTORS-1] are nullptr too. return;
GPR_ASSERT(i == 0);
break;
}
executors[i]->Shutdown();
} }
executors[GRPC_DEFAULT_EXECUTOR]->Shutdown();
executors[GRPC_RESOLVER_EXECUTOR]->Shutdown();
// Delete the executor objects. // Delete the executor objects.
// //
// NOTE: It is important to do this in a separate loop (i.e ONLY after all the // NOTE: It is important to call Shutdown() on all executors first before
// executors are 'Shutdown' first) because it is possible for one executor // calling Delete() because it is possible for one executor (that is not
// (that is not shutdown yet) to call Enqueue() on a different executor which // shutdown yet) to call Enqueue() on a different executor which is already
// is already shutdown. This is legal and in such cases, the Enqueue() // shutdown. This is legal and in such cases, the Enqueue() operation
// operation effectively "fails" and enqueues that closure on the calling // effectively "fails" and enqueues that closure on the calling thread's
// thread's exec_ctx. // exec_ctx.
// //
// By ensuring that all executors are shutdown first, we are also ensuring // By ensuring that all executors are shutdown first, we are also ensuring
// that no thread is active across all executors. // that no thread is active across all executors.
for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) {
grpc_core::Delete<GrpcExecutor>(executors[i]); grpc_core::Delete<GrpcExecutor>(executors[GRPC_DEFAULT_EXECUTOR]);
executors[i] = nullptr; grpc_core::Delete<GrpcExecutor>(executors[GRPC_RESOLVER_EXECUTOR]);
} executors[GRPC_DEFAULT_EXECUTOR] = nullptr;
executors[GRPC_RESOLVER_EXECUTOR] = nullptr;
EXECUTOR_TRACE0("grpc_executor_shutdown() done"); EXECUTOR_TRACE0("grpc_executor_shutdown() done");
} }

Loading…
Cancel
Save