From: Liu Yuan <tailai.ly at taobao.com> Signed-off-by: Liu Yuan <tailai.ly at taobao.com> --- sheep/sheep.c | 3 +++ sheep/work.c | 46 ++++++++++++++++++---------------------------- sheep/work.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/sheep/sheep.c b/sheep/sheep.c index 94b4a9e..b86f8e5 100644 --- a/sheep/sheep.c +++ b/sheep/sheep.c @@ -207,6 +207,9 @@ int main(int argc, char **argv) !sys->recovery_wqueue || !sys->deletion_wqueue) exit(1); + ret = init_signal(); + if (ret) + exit(1); vprintf(SDOG_NOTICE, "sheepdog daemon (version %s) started\n", PACKAGE_VERSION); while (!sys_stat_shutdown() || sys->nr_outstanding_reqs != 0) diff --git a/sheep/work.c b/sheep/work.c index 789272e..5468d4c 100644 --- a/sheep/work.c +++ b/sheep/work.c @@ -24,6 +24,7 @@ #include <sys/types.h> #include <sys/eventfd.h> #include <linux/types.h> +#include <signal.h> #include "list.h" #include "util.h" @@ -32,40 +33,14 @@ #include "event.h" static int efd; -static LIST_HEAD(worker_info_list); - -struct work_queue { - int wq_state; - int nr_active; - struct list_head pending_list; - struct list_head blocked_list; -}; +int total_nr_workers; +LIST_HEAD(worker_info_list); enum wq_state { WQ_BLOCKED = (1U << 0), WQ_DEAD = (1U << 1), }; -struct worker_info { - struct list_head worker_info_siblings; - - int nr_threads; - - pthread_mutex_t finished_lock; - struct list_head finished_list; - - /* wokers sleep on this and signaled by tgtd */ - pthread_cond_t pending_cond; - /* locked by tgtd and workers */ - pthread_mutex_t pending_lock; - /* protected by pending_lock */ - struct work_queue q; - - pthread_mutex_t startup_lock; - - pthread_t worker_thread[0]; -}; - static void work_queue_set_blocked(struct work_queue *q) { q->wq_state |= WQ_BLOCKED; @@ -289,6 +264,7 @@ struct work_queue *init_work_queue(int nr) list_add(&wi->worker_info_siblings, &worker_info_list); + total_nr_workers += nr; return &wi->q; destroy_threads: @@ -308,6 +284,20 @@ destroy_threads: return NULL; } +int init_signal(void) +{ + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = suspend; + /* trace uses this signal to suspend the worker threads */ + if (sigaction(SIGUSR1, &act, NULL) < 0) { + dprintf("%m\n"); + return -1; + } + return 0; +} + #ifdef COMPILE_UNUSED_CODE static void exit_work_queue(struct work_queue *q) { diff --git a/sheep/work.h b/sheep/work.h index 9ef9936..b453b2a 100644 --- a/sheep/work.h +++ b/sheep/work.h @@ -18,7 +18,39 @@ struct work { enum work_attr attr; }; +struct work_queue { + int wq_state; + int nr_active; + struct list_head pending_list; + struct list_head blocked_list; +}; + +struct worker_info { + struct list_head worker_info_siblings; + + int nr_threads; + + pthread_mutex_t finished_lock; + struct list_head finished_list; + + /* wokers sleep on this and signaled by tgtd */ + pthread_cond_t pending_cond; + /* locked by tgtd and workers */ + pthread_mutex_t pending_lock; + /* protected by pending_lock */ + struct work_queue q; + + pthread_mutex_t startup_lock; + + pthread_t worker_thread[0]; +}; + +extern struct list_head worker_info_list; +extern int total_nr_workers; + struct work_queue *init_work_queue(int nr); void queue_work(struct work_queue *q, struct work *work); +int init_signal(void); +void suspend(int); #endif -- 1.7.8.2 |