2 * Basic workqueue like code, that sets up a thread and allows async
3 * processing of some sort. Could be extended to allow for multiple
4 * worker threads. But right now fio associates one of this per IO
5 * thread, so should be enough to have just a single thread doing the
15 #include "../smalloc.h"
19 static void tp_flush_work(struct flist_head *list)
23 while (!flist_empty(list)) {
24 work = flist_entry(list->next, struct tp_work, list);
25 flist_del(&work->list);
30 static void *tp_thread(void *data)
32 struct tp_data *tdat = data;
33 struct flist_head work_list;
35 INIT_FLIST_HEAD(&work_list);
38 pthread_mutex_lock(&tdat->lock);
40 if (!tdat->thread_exit && flist_empty(&tdat->work))
41 pthread_cond_wait(&tdat->cv, &tdat->lock);
43 if (!flist_empty(&tdat->work))
44 flist_splice_tail_init(&tdat->work, &work_list);
46 pthread_mutex_unlock(&tdat->lock);
48 if (flist_empty(&work_list)) {
49 if (tdat->thread_exit)
54 tp_flush_work(&work_list);
60 void tp_queue_work(struct tp_data *tdat, struct tp_work *work)
64 pthread_mutex_lock(&tdat->lock);
65 flist_add_tail(&work->list, &tdat->work);
66 pthread_mutex_unlock(&tdat->lock);
68 pthread_cond_signal(&tdat->cv);
71 void tp_init(struct tp_data **tdatp)
79 *tdatp = tdat = smalloc(sizeof(*tdat));
80 pthread_mutex_init(&tdat->lock, NULL);
81 INIT_FLIST_HEAD(&tdat->work);
82 pthread_cond_init(&tdat->cv, NULL);
83 pthread_cond_init(&tdat->sleep_cv, NULL);
85 ret = pthread_create(&tdat->thread, NULL, tp_thread, tdat);
87 log_err("fio: failed to create tp thread\n");
90 void tp_exit(struct tp_data **tdatp)
92 struct tp_data *tdat = *tdatp;
98 pthread_mutex_lock(&tdat->lock);
99 tdat->thread_exit = 1;
100 pthread_mutex_unlock(&tdat->lock);
102 pthread_cond_signal(&tdat->cv);
104 pthread_join(tdat->thread, &ret);