This patch not only an optimization but also a bug fix because it guarantees
that fio_gettime_offload() never returns an inconsistent timestamp, something
that could happen before. In this context inconsistent means returning the
.tv_sec value from one gettimeofday() call and the .tv_usec value from another
gettimeofday() call.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
#include <time.h>
#include "fio.h"
#include <time.h>
#include "fio.h"
+#include "lib/seqlock.h"
-struct timespec *fio_ts = NULL;
int fio_gtod_offload = 0;
static pthread_t gtod_thread;
static os_cpu_mask_t fio_gtod_cpumask;
int fio_gtod_offload = 0;
static pthread_t gtod_thread;
static os_cpu_mask_t fio_gtod_cpumask;
static void fio_gtod_update(void)
{
static void fio_gtod_update(void)
{
- if (fio_ts) {
- struct timeval __tv;
-
- gettimeofday(&__tv, NULL);
- fio_ts->tv_sec = __tv.tv_sec;
- write_barrier();
- fio_ts->tv_nsec = __tv.tv_usec * 1000;
- write_barrier();
- }
+ struct timeval __tv;
+
+ if (!fio_ts)
+ return;
+
+ gettimeofday(&__tv, NULL);
+
+ write_seqlock_begin(&fio_ts->seqlock);
+ fio_ts->ts.tv_sec = __tv.tv_sec;
+ fio_ts->ts.tv_nsec = __tv.tv_usec * 1000;
+ write_seqlock_end(&fio_ts->seqlock);
#include <sys/time.h>
#include "arch/arch.h"
#include <sys/time.h>
#include "arch/arch.h"
+#include "lib/seqlock.h"
extern int fio_monotonic_clocktest(int debug);
extern void fio_local_clock_init(void);
extern int fio_monotonic_clocktest(int debug);
extern void fio_local_clock_init(void);
-extern struct timespec *fio_ts;
+extern struct fio_ts {
+ struct seqlock seqlock;
+ struct timespec ts;
+} *fio_ts;
static inline int fio_gettime_offload(struct timespec *ts)
{
static inline int fio_gettime_offload(struct timespec *ts)
{
if (!fio_ts)
return 0;
do {
if (!fio_ts)
return 0;
do {
- read_barrier();
- last_sec = ts->tv_sec = fio_ts->tv_sec;
- ts->tv_nsec = fio_ts->tv_nsec;
- } while (fio_ts->tv_sec != last_sec);
+ seq = read_seqlock_begin(&fio_ts->seqlock);
+ *ts = fio_ts->ts;
+ } while (read_seqlock_retry(&fio_ts->seqlock, seq));
#include <stdio.h>
FILE *f_err;
#include <stdio.h>
FILE *f_err;
-struct timespec *fio_ts = NULL;
unsigned long fio_debug = 0;
void __dprint(int type, const char *str, ...)
unsigned long fio_debug = 0;
void __dprint(int type, const char *str, ...)