Merge branch 'patch-1' of https://github.com/joaomlneto/fio
[fio.git] / workqueue.h
... / ...
CommitLineData
1#ifndef FIO_RATE_H
2#define FIO_RATE_H
3
4#include <inttypes.h>
5#include <pthread.h>
6
7#include "flist.h"
8#include "lib/types.h"
9
10struct sk_out;
11struct thread_data;
12
13struct workqueue_work {
14 struct flist_head list;
15};
16
17struct submit_worker {
18 pthread_t thread;
19 pthread_mutex_t lock;
20 pthread_cond_t cond;
21 struct flist_head work_list;
22 unsigned int flags;
23 unsigned int index;
24 uint64_t seq;
25 struct workqueue *wq;
26 void *priv;
27 struct sk_out *sk_out;
28};
29
30typedef int (workqueue_work_fn)(struct submit_worker *, struct workqueue_work *);
31typedef bool (workqueue_pre_sleep_flush_fn)(struct submit_worker *);
32typedef void (workqueue_pre_sleep_fn)(struct submit_worker *);
33typedef int (workqueue_alloc_worker_fn)(struct submit_worker *);
34typedef void (workqueue_free_worker_fn)(struct submit_worker *);
35typedef int (workqueue_init_worker_fn)(struct submit_worker *);
36typedef void (workqueue_exit_worker_fn)(struct submit_worker *, unsigned int *);
37typedef void (workqueue_update_acct_fn)(struct submit_worker *);
38
39struct workqueue_ops {
40 workqueue_work_fn *fn;
41 workqueue_pre_sleep_flush_fn *pre_sleep_flush_fn;
42 workqueue_pre_sleep_fn *pre_sleep_fn;
43
44 workqueue_update_acct_fn *update_acct_fn;
45
46 workqueue_alloc_worker_fn *alloc_worker_fn;
47 workqueue_free_worker_fn *free_worker_fn;
48
49 workqueue_init_worker_fn *init_worker_fn;
50 workqueue_exit_worker_fn *exit_worker_fn;
51
52 unsigned int nice;
53};
54
55struct workqueue {
56 unsigned int max_workers;
57
58 struct thread_data *td;
59 struct workqueue_ops ops;
60
61 uint64_t work_seq;
62 struct submit_worker *workers;
63 unsigned int next_free_worker;
64
65 pthread_cond_t flush_cond;
66 pthread_mutex_t flush_lock;
67 pthread_mutex_t stat_lock;
68 volatile int wake_idle;
69};
70
71int workqueue_init(struct thread_data *td, struct workqueue *wq, struct workqueue_ops *ops, unsigned int max_workers, struct sk_out *sk_out);
72void workqueue_exit(struct workqueue *wq);
73
74void workqueue_enqueue(struct workqueue *wq, struct workqueue_work *work);
75void workqueue_flush(struct workqueue *wq);
76
77static inline bool workqueue_pre_sleep_check(struct submit_worker *sw)
78{
79 struct workqueue *wq = sw->wq;
80
81 if (!wq->ops.pre_sleep_flush_fn)
82 return false;
83
84 return wq->ops.pre_sleep_flush_fn(sw);
85}
86
87static inline void workqueue_pre_sleep(struct submit_worker *sw)
88{
89 struct workqueue *wq = sw->wq;
90
91 if (wq->ops.pre_sleep_fn)
92 wq->ops.pre_sleep_fn(sw);
93}
94
95static inline int workqueue_init_worker(struct submit_worker *sw)
96{
97 struct workqueue *wq = sw->wq;
98
99 if (!wq->ops.init_worker_fn)
100 return 0;
101
102 return wq->ops.init_worker_fn(sw);
103}
104
105static inline void workqueue_exit_worker(struct submit_worker *sw,
106 unsigned int *sum_cnt)
107{
108 struct workqueue *wq = sw->wq;
109 unsigned int tmp = 1;
110
111 if (!wq->ops.exit_worker_fn)
112 return;
113
114 if (!sum_cnt)
115 sum_cnt = &tmp;
116
117 wq->ops.exit_worker_fn(sw, sum_cnt);
118}
119#endif