|
|
|
@ -66,22 +66,6 @@ GPR_TLS_DECL(g_this_thread_state); |
|
|
|
|
|
|
|
|
|
static void executor_thread(void *arg); |
|
|
|
|
|
|
|
|
|
void grpc_executor_init() { |
|
|
|
|
g_max_threads = GPR_MAX(1, 2 * gpr_cpu_num_cores()); |
|
|
|
|
gpr_atm_no_barrier_store(&g_cur_threads, 1); |
|
|
|
|
gpr_tls_init(&g_this_thread_state); |
|
|
|
|
g_thread_state = gpr_zalloc(sizeof(thread_state) * g_max_threads); |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_init(&g_thread_state[i].mu); |
|
|
|
|
gpr_cv_init(&g_thread_state[i].cv); |
|
|
|
|
g_thread_state[i].elems = (grpc_closure_list)GRPC_CLOSURE_LIST_INIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_thd_options opt = gpr_thd_options_default(); |
|
|
|
|
gpr_thd_options_set_joinable(&opt); |
|
|
|
|
gpr_thd_new(&g_thread_state[0].id, executor_thread, &g_thread_state[0], &opt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static size_t run_closures(grpc_exec_ctx *exec_ctx, grpc_closure_list list) { |
|
|
|
|
size_t n = 0; |
|
|
|
|
|
|
|
|
@ -100,24 +84,57 @@ static size_t run_closures(grpc_exec_ctx *exec_ctx, grpc_closure_list list) { |
|
|
|
|
return n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) { |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_lock(&g_thread_state[i].mu); |
|
|
|
|
g_thread_state[i].shutdown = true; |
|
|
|
|
gpr_cv_signal(&g_thread_state[i].cv); |
|
|
|
|
gpr_mu_unlock(&g_thread_state[i].mu); |
|
|
|
|
} |
|
|
|
|
for (gpr_atm i = 0; i < g_cur_threads; i++) { |
|
|
|
|
gpr_thd_join(g_thread_state[i].id); |
|
|
|
|
bool grpc_executor_is_threaded() { |
|
|
|
|
return gpr_atm_no_barrier_load(&g_cur_threads) > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_executor_set_threading(grpc_exec_ctx *exec_ctx, bool threading) { |
|
|
|
|
gpr_atm cur_threads = gpr_atm_no_barrier_load(&g_cur_threads); |
|
|
|
|
if (threading) { |
|
|
|
|
if (cur_threads > 0) return; |
|
|
|
|
g_max_threads = GPR_MAX(1, 2 * gpr_cpu_num_cores()); |
|
|
|
|
gpr_atm_no_barrier_store(&g_cur_threads, 1); |
|
|
|
|
gpr_tls_init(&g_this_thread_state); |
|
|
|
|
g_thread_state = gpr_zalloc(sizeof(thread_state) * g_max_threads); |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_init(&g_thread_state[i].mu); |
|
|
|
|
gpr_cv_init(&g_thread_state[i].cv); |
|
|
|
|
g_thread_state[i].elems = (grpc_closure_list)GRPC_CLOSURE_LIST_INIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_thd_options opt = gpr_thd_options_default(); |
|
|
|
|
gpr_thd_options_set_joinable(&opt); |
|
|
|
|
gpr_thd_new(&g_thread_state[0].id, executor_thread, &g_thread_state[0], |
|
|
|
|
&opt); |
|
|
|
|
} else { |
|
|
|
|
if (cur_threads == 0) return; |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_lock(&g_thread_state[i].mu); |
|
|
|
|
g_thread_state[i].shutdown = true; |
|
|
|
|
gpr_cv_signal(&g_thread_state[i].cv); |
|
|
|
|
gpr_mu_unlock(&g_thread_state[i].mu); |
|
|
|
|
} |
|
|
|
|
for (gpr_atm i = 0; i < g_cur_threads; i++) { |
|
|
|
|
gpr_thd_join(g_thread_state[i].id); |
|
|
|
|
} |
|
|
|
|
gpr_atm_no_barrier_store(&g_cur_threads, 0); |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_destroy(&g_thread_state[i].mu); |
|
|
|
|
gpr_cv_destroy(&g_thread_state[i].cv); |
|
|
|
|
run_closures(exec_ctx, g_thread_state[i].elems); |
|
|
|
|
} |
|
|
|
|
gpr_free(g_thread_state); |
|
|
|
|
gpr_tls_destroy(&g_this_thread_state); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_executor_init(grpc_exec_ctx *exec_ctx) { |
|
|
|
|
gpr_atm_no_barrier_store(&g_cur_threads, 0); |
|
|
|
|
for (size_t i = 0; i < g_max_threads; i++) { |
|
|
|
|
gpr_mu_destroy(&g_thread_state[i].mu); |
|
|
|
|
gpr_cv_destroy(&g_thread_state[i].cv); |
|
|
|
|
run_closures(exec_ctx, g_thread_state[i].elems); |
|
|
|
|
} |
|
|
|
|
gpr_free(g_thread_state); |
|
|
|
|
gpr_tls_destroy(&g_this_thread_state); |
|
|
|
|
grpc_executor_set_threading(exec_ctx, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) { |
|
|
|
|
grpc_executor_set_threading(exec_ctx, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void executor_thread(void *arg) { |
|
|
|
|