backend: regrow logs for sync IO engines as well
[fio.git] / helper_thread.c
CommitLineData
a39fb9ea
JA
1#include "fio.h"
2#include "smalloc.h"
3#include "helper_thread.h"
4
5static struct helper_data {
6 volatile int exit;
7 volatile int reset;
8 volatile int do_stat;
9 struct sk_out *sk_out;
10 pthread_t thread;
11 pthread_mutex_t lock;
12 pthread_cond_t cond;
13 struct fio_mutex *startup_mutex;
14} *helper_data;
15
16void helper_thread_destroy(void)
17{
18 pthread_cond_destroy(&helper_data->cond);
19 pthread_mutex_destroy(&helper_data->lock);
20 sfree(helper_data);
21}
22
23void helper_reset(void)
24{
25 if (!helper_data)
26 return;
27
28 pthread_mutex_lock(&helper_data->lock);
29
30 if (!helper_data->reset) {
31 helper_data->reset = 1;
32 pthread_cond_signal(&helper_data->cond);
33 }
34
35 pthread_mutex_unlock(&helper_data->lock);
36}
37
38void helper_do_stat(void)
39{
40 if (!helper_data)
41 return;
42
43 pthread_mutex_lock(&helper_data->lock);
44 helper_data->do_stat = 1;
45 pthread_cond_signal(&helper_data->cond);
46 pthread_mutex_unlock(&helper_data->lock);
47}
48
49bool helper_should_exit(void)
50{
51 if (!helper_data)
52 return true;
53
54 return helper_data->exit;
55}
56
57void helper_thread_exit(void)
58{
59 void *ret;
60
61 pthread_mutex_lock(&helper_data->lock);
62 helper_data->exit = 1;
63 pthread_cond_signal(&helper_data->cond);
64 pthread_mutex_unlock(&helper_data->lock);
65
66 pthread_join(helper_data->thread, &ret);
67}
68
69static void *helper_thread_main(void *data)
70{
71 struct helper_data *hd = data;
72 unsigned int msec_to_next_event, next_log;
73 struct timeval tv, last_du;
74 int ret = 0;
75
76 sk_out_assign(hd->sk_out);
77
78 gettimeofday(&tv, NULL);
79 memcpy(&last_du, &tv, sizeof(tv));
80
81 fio_mutex_up(hd->startup_mutex);
82
83 msec_to_next_event = DISK_UTIL_MSEC;
84 while (!ret && !hd->exit) {
85 struct timespec ts;
86 struct timeval now;
87 uint64_t since_du;
88
89 timeval_add_msec(&tv, msec_to_next_event);
90 ts.tv_sec = tv.tv_sec;
91 ts.tv_nsec = tv.tv_usec * 1000;
92
93 pthread_mutex_lock(&hd->lock);
94 pthread_cond_timedwait(&hd->cond, &hd->lock, &ts);
95
96 gettimeofday(&now, NULL);
97
98 if (hd->reset) {
99 memcpy(&tv, &now, sizeof(tv));
100 memcpy(&last_du, &now, sizeof(last_du));
101 hd->reset = 0;
102 }
103
104 pthread_mutex_unlock(&hd->lock);
105
106 since_du = mtime_since(&last_du, &now);
107 if (since_du >= DISK_UTIL_MSEC || DISK_UTIL_MSEC - since_du < 10) {
108 ret = update_io_ticks();
109 timeval_add_msec(&last_du, DISK_UTIL_MSEC);
110 msec_to_next_event = DISK_UTIL_MSEC;
111 if (since_du >= DISK_UTIL_MSEC)
112 msec_to_next_event -= (since_du - DISK_UTIL_MSEC);
113 } else {
114 if (since_du >= DISK_UTIL_MSEC)
115 msec_to_next_event = DISK_UTIL_MSEC - (DISK_UTIL_MSEC - since_du);
116 else
117 msec_to_next_event = DISK_UTIL_MSEC;
118 }
119
120 if (hd->do_stat) {
121 hd->do_stat = 0;
122 __show_running_run_stats();
123 }
124
125 next_log = calc_log_samples();
126 if (!next_log)
127 next_log = DISK_UTIL_MSEC;
128
129 msec_to_next_event = min(next_log, msec_to_next_event);
130
131 if (!is_backend)
132 print_thread_status();
133 }
134
135 fio_writeout_logs(false);
136
137 sk_out_drop();
138 return NULL;
139}
140
141int helper_thread_create(struct fio_mutex *startup_mutex, struct sk_out *sk_out)
142{
143 struct helper_data *hd;
144 int ret;
145
146 hd = smalloc(sizeof(*hd));
147
148 setup_disk_util();
149
150 hd->sk_out = sk_out;
151 pthread_cond_init(&hd->cond, NULL);
152 pthread_mutex_init(&hd->lock, NULL);
153 hd->startup_mutex = startup_mutex;
154
155 ret = pthread_create(&hd->thread, NULL, helper_thread_main, hd);
156 if (ret) {
157 log_err("Can't create helper thread: %s\n", strerror(ret));
158 return 1;
159 }
160
161 helper_data = hd;
162
163 dprint(FD_MUTEX, "wait on startup_mutex\n");
164 fio_mutex_down(startup_mutex);
165 dprint(FD_MUTEX, "done waiting on startup_mutex\n");
166 return 0;
167}