libiscsi: continue working when meets EINTR or EAGAIN
[fio.git] / gettime-thread.c
CommitLineData
39ab7da2
JA
1#include <sys/time.h>
2#include <time.h>
3
4#include "fio.h"
5#include "smalloc.h"
6
8b6a404c 7struct timespec *fio_ts = NULL;
39ab7da2 8int fio_gtod_offload = 0;
39ab7da2 9static pthread_t gtod_thread;
8a2b393b 10static os_cpu_mask_t fio_gtod_cpumask;
39ab7da2
JA
11
12void fio_gtod_init(void)
13{
8b6a404c 14 if (fio_ts)
79c896a1
JA
15 return;
16
8b6a404c 17 fio_ts = smalloc(sizeof(*fio_ts));
39ab7da2
JA
18}
19
20static void fio_gtod_update(void)
21{
8b6a404c 22 if (fio_ts) {
27325ed5
JA
23 struct timeval __tv;
24
25 gettimeofday(&__tv, NULL);
8b6a404c 26 fio_ts->tv_sec = __tv.tv_sec;
27325ed5 27 write_barrier();
8b6a404c 28 fio_ts->tv_nsec = __tv.tv_usec * 1000;
27325ed5
JA
29 write_barrier();
30 }
39ab7da2
JA
31}
32
79c896a1 33struct gtod_cpu_data {
971caeb1 34 struct fio_sem *sem;
79c896a1
JA
35 unsigned int cpu;
36};
37
39ab7da2
JA
38static void *gtod_thread_main(void *data)
39{
971caeb1 40 struct fio_sem *sem = data;
48d86be5
JA
41 int ret;
42
43 ret = fio_setaffinity(gettid(), fio_gtod_cpumask);
39ab7da2 44
971caeb1 45 fio_sem_up(sem);
39ab7da2 46
48d86be5
JA
47 if (ret == -1) {
48 log_err("gtod: setaffinity failed\n");
49 return NULL;
50 }
51
39ab7da2
JA
52 /*
53 * As long as we have jobs around, update the clock. It would be nice
54 * to have some way of NOT hammering that CPU with gettimeofday(),
55 * but I'm not sure what to use outside of a simple CPU nop to relax
56 * it - we don't want to lose precision.
57 */
58 while (threads) {
59 fio_gtod_update();
60 nop;
61 }
62
63 return NULL;
64}
65
66int fio_start_gtod_thread(void)
67{
971caeb1 68 struct fio_sem *sem;
39ab7da2
JA
69 pthread_attr_t attr;
70 int ret;
71
971caeb1
BVA
72 sem = fio_sem_init(FIO_SEM_LOCKED);
73 if (!sem)
39ab7da2
JA
74 return 1;
75
76 pthread_attr_init(&attr);
45213f1b 77 pthread_attr_setstacksize(&attr, 2 * PTHREAD_STACK_MIN);
971caeb1 78 ret = pthread_create(&gtod_thread, &attr, gtod_thread_main, sem);
39ab7da2
JA
79 pthread_attr_destroy(&attr);
80 if (ret) {
81 log_err("Can't create gtod thread: %s\n", strerror(ret));
82 goto err;
83 }
84
85 ret = pthread_detach(gtod_thread);
86 if (ret) {
bc0fe8b8 87 log_err("Can't detach gtod thread: %s\n", strerror(ret));
39ab7da2
JA
88 goto err;
89 }
90
971caeb1
BVA
91 dprint(FD_MUTEX, "wait on startup_sem\n");
92 fio_sem_down(sem);
93 dprint(FD_MUTEX, "done waiting on startup_sem\n");
39ab7da2 94err:
971caeb1 95 fio_sem_remove(sem);
39ab7da2
JA
96 return ret;
97}
98
79c896a1
JA
99void fio_gtod_set_cpu(unsigned int cpu)
100{
2a2f27b8 101#ifdef FIO_HAVE_CPU_AFFINITY
79c896a1 102 fio_cpu_set(&fio_gtod_cpumask, cpu);
2a2f27b8 103#endif
79c896a1 104}