configure: attempt to link against tcmalloc by default if available
[fio.git] / gettime-thread.c
... / ...
CommitLineData
1#include <sys/time.h>
2#include <time.h>
3
4#include "fio.h"
5#include "smalloc.h"
6
7struct timespec *fio_ts = NULL;
8int fio_gtod_offload = 0;
9static pthread_t gtod_thread;
10static os_cpu_mask_t fio_gtod_cpumask;
11
12void fio_gtod_init(void)
13{
14 if (fio_ts)
15 return;
16
17 fio_ts = smalloc(sizeof(*fio_ts));
18}
19
20static void fio_gtod_update(void)
21{
22 if (fio_ts) {
23 struct timeval __tv;
24
25 gettimeofday(&__tv, NULL);
26 fio_ts->tv_sec = __tv.tv_sec;
27 write_barrier();
28 fio_ts->tv_nsec = __tv.tv_usec * 1000;
29 write_barrier();
30 }
31}
32
33struct gtod_cpu_data {
34 struct fio_sem *sem;
35 unsigned int cpu;
36};
37
38static void *gtod_thread_main(void *data)
39{
40 struct fio_sem *sem = data;
41 int ret;
42
43 ret = fio_setaffinity(gettid(), fio_gtod_cpumask);
44
45 fio_sem_up(sem);
46
47 if (ret == -1) {
48 log_err("gtod: setaffinity failed\n");
49 return NULL;
50 }
51
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{
68 struct fio_sem *sem;
69 pthread_attr_t attr;
70 int ret;
71
72 sem = fio_sem_init(FIO_SEM_LOCKED);
73 if (!sem)
74 return 1;
75
76 pthread_attr_init(&attr);
77 pthread_attr_setstacksize(&attr, 2 * PTHREAD_STACK_MIN);
78 ret = pthread_create(&gtod_thread, &attr, gtod_thread_main, sem);
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) {
87 log_err("Can't detach gtod thread: %s\n", strerror(ret));
88 goto err;
89 }
90
91 dprint(FD_MUTEX, "wait on startup_sem\n");
92 fio_sem_down(sem);
93 dprint(FD_MUTEX, "done waiting on startup_sem\n");
94err:
95 fio_sem_remove(sem);
96 return ret;
97}
98
99void fio_gtod_set_cpu(unsigned int cpu)
100{
101#ifdef FIO_HAVE_CPU_AFFINITY
102 fio_cpu_set(&fio_gtod_cpumask, cpu);
103#endif
104}