From c3c05ff63b4b19e5709f613eb49aa0dd32871c84 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 5 Sep 2012 10:31:49 +0200 Subject: [PATCH] kvm tools: threadpool exit routine Add an exit function for the threadpool which will stop all running threads in the pool. Also clean up the init code a bit. Signed-off-by: Sasha Levin Signed-off-by: Pekka Enberg --- tools/kvm/builtin-run.c | 11 +++++++++- tools/kvm/include/kvm/threadpool.h | 3 ++- tools/kvm/util/threadpool.c | 33 ++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index d0079278add0..5e6daa8ae679 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -1216,7 +1216,12 @@ static int kvm_cmd_run_init(int argc, const char **argv) } } - thread_pool__init(nr_online_cpus); + r = thread_pool__init(kvm); + if (r < 0) { + pr_err("thread_pool__init() failed with error %d\n", r); + goto fail; + } + fail: return r; } @@ -1301,6 +1306,10 @@ static void kvm_cmd_run_exit(int guest_ret) if (r < 0) pr_warning("pci__exit() failed with error %d\n", r); + r = thread_pool__exit(kvm); + if (r < 0) + pr_warning("thread_pool__exit() failed with error %d\n", r); + r = kvm__exit(kvm); if (r < 0) pr_warning("pci__exit() failed with error %d\n", r); diff --git a/tools/kvm/include/kvm/threadpool.h b/tools/kvm/include/kvm/threadpool.h index 768239f94e08..abe46eaaa65f 100644 --- a/tools/kvm/include/kvm/threadpool.h +++ b/tools/kvm/include/kvm/threadpool.h @@ -30,7 +30,8 @@ static inline void thread_pool__init_job(struct thread_pool__job *job, struct kv }; } -int thread_pool__init(unsigned long thread_count); +int thread_pool__init(struct kvm *kvm); +int thread_pool__exit(struct kvm *kvm); void thread_pool__do_job(struct thread_pool__job *job); diff --git a/tools/kvm/util/threadpool.c b/tools/kvm/util/threadpool.c index bafbcd720090..6c7566de9d82 100644 --- a/tools/kvm/util/threadpool.c +++ b/tools/kvm/util/threadpool.c @@ -14,6 +14,7 @@ static LIST_HEAD(head); static pthread_t *threads; static long threadcount; +static bool running; static struct thread_pool__job *thread_pool__job_pop_locked(void) { @@ -76,15 +77,16 @@ static void *thread_pool__threadfunc(void *param) { pthread_cleanup_push(thread_pool__threadfunc_cleanup, NULL); - for (;;) { + while (running) { struct thread_pool__job *curjob; mutex_lock(&job_mutex); - while ((curjob = thread_pool__job_pop_locked()) == NULL) + while (running && (curjob = thread_pool__job_pop_locked()) == NULL) pthread_cond_wait(&job_cond, &job_mutex); mutex_unlock(&job_mutex); - thread_pool__handle_job(curjob); + if (running) + thread_pool__handle_job(curjob); } pthread_cleanup_pop(0); @@ -116,9 +118,12 @@ static int thread_pool__addthread(void) return res; } -int thread_pool__init(unsigned long thread_count) +int thread_pool__init(struct kvm *kvm) { unsigned long i; + unsigned int thread_count = sysconf(_SC_NPROCESSORS_ONLN); + + running = true; for (i = 0; i < thread_count; i++) if (thread_pool__addthread() < 0) @@ -127,6 +132,26 @@ int thread_pool__init(unsigned long thread_count) return i; } +int thread_pool__exit(struct kvm *kvm) +{ + int i; + void *NUL = NULL; + + running = false; + + for (i = 0; i < threadcount; i++) { + mutex_lock(&job_mutex); + pthread_cond_signal(&job_cond); + mutex_unlock(&job_mutex); + } + + for (i = 0; i < threadcount; i++) { + pthread_join(threads[i], NUL); + } + + return 0; +} + void thread_pool__do_job(struct thread_pool__job *job) { struct thread_pool__job *jobinfo = job; -- 2.39.5