time.c revision 6043c5790f9978814ec25e3ea8f4d574daf6266e
13c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe#include <time.h>
23c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe#include <sys/time.h>
33c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
43c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe#include "fio.h"
53c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
6263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboestatic struct timeval genesis;
7263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe
83c39a379542fd819dbc5cf6daf59380911c39141Jens Axboeunsigned long utime_since(struct timeval *s, struct timeval *e)
93c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
103c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	double sec, usec;
113c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
123c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	sec = e->tv_sec - s->tv_sec;
133c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	usec = e->tv_usec - s->tv_usec;
143c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	if (sec > 0 && usec < 0) {
153c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		sec--;
163c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		usec += 1000000;
173c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	}
183c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
193c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	sec *= (double) 1000000;
203c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
213c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	return sec + usec;
223c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
233c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
243c39a379542fd819dbc5cf6daf59380911c39141Jens Axboestatic unsigned long utime_since_now(struct timeval *s)
253c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
263c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	struct timeval t;
273c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
283c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	gettimeofday(&t, NULL);
293c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	return utime_since(s, &t);
303c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
313c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
323c39a379542fd819dbc5cf6daf59380911c39141Jens Axboeunsigned long mtime_since(struct timeval *s, struct timeval *e)
333c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
343c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	double sec, usec;
353c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
363c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	sec = e->tv_sec - s->tv_sec;
373c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	usec = e->tv_usec - s->tv_usec;
383c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	if (sec > 0 && usec < 0) {
393c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		sec--;
403c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		usec += 1000000;
413c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	}
423c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
433c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	sec *= (double) 1000;
443c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	usec /= (double) 1000;
453c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
463c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	return sec + usec;
473c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
483c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
493c39a379542fd819dbc5cf6daf59380911c39141Jens Axboeunsigned long mtime_since_now(struct timeval *s)
503c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
513c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	struct timeval t;
523c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
533c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	gettimeofday(&t, NULL);
543c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	return mtime_since(s, &t);
553c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
563c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
573c39a379542fd819dbc5cf6daf59380911c39141Jens Axboeunsigned long time_since_now(struct timeval *s)
583c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
593c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	return mtime_since_now(s) / 1000;
603c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
613c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
623c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe/*
633c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe * busy looping version for the last few usec
643c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe */
65b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboevoid __usec_sleep(unsigned int usec)
663c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
673c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	struct timeval start;
683c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
693c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	gettimeofday(&start, NULL);
703c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	while (utime_since_now(&start) < usec)
713c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		nop;
723c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
733c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
743c39a379542fd819dbc5cf6daf59380911c39141Jens Axboevoid usec_sleep(struct thread_data *td, unsigned long usec)
753c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
763c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	struct timespec req, rem;
773c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
783c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	req.tv_sec = usec / 1000000;
793c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	req.tv_nsec = usec * 1000 - req.tv_sec * 1000000;
803c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
813c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	do {
823c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		if (usec < 5000) {
833c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			__usec_sleep(usec);
843c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			break;
853c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		}
863c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
873c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		rem.tv_sec = rem.tv_nsec = 0;
883c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		if (nanosleep(&req, &rem) < 0)
893c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			break;
903c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
913c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		if ((rem.tv_sec + rem.tv_nsec) == 0)
923c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			break;
933c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
943c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		req.tv_nsec = rem.tv_nsec;
953c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		req.tv_sec = rem.tv_sec;
963c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
973c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		usec = rem.tv_sec * 1000000 + rem.tv_nsec / 1000;
983c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	} while (!td->terminate);
993c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
1003c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
1013c39a379542fd819dbc5cf6daf59380911c39141Jens Axboevoid rate_throttle(struct thread_data *td, unsigned long time_spent,
102a00735e66f9ec42549da94eba3170e543b542904Jens Axboe		   unsigned int bytes, int ddir)
1033c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe{
1043c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	unsigned long usec_cycle;
1053c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
1063c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	if (!td->rate)
1073c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		return;
1083c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
109a00735e66f9ec42549da94eba3170e543b542904Jens Axboe	usec_cycle = td->rate_usec_cycle * (bytes / td->min_bs[ddir]);
1103c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
1113c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	if (time_spent < usec_cycle) {
1123c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		unsigned long s = usec_cycle - time_spent;
1133c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
1143c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		td->rate_pending_usleep += s;
1153c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		if (td->rate_pending_usleep >= 100000) {
1163c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			usec_sleep(td, td->rate_pending_usleep);
1173c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe			td->rate_pending_usleep = 0;
1183c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		}
1193c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	} else {
1203c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		long overtime = time_spent - usec_cycle;
1213c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe
1223c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe		td->rate_pending_usleep -= overtime;
1233c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe	}
1243c39a379542fd819dbc5cf6daf59380911c39141Jens Axboe}
125263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe
126263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboeunsigned long mtime_since_genesis(void)
127263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe{
128263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe	return mtime_since_now(&genesis);
129263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe}
130263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe
131263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboevoid time_init(void)
132263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe{
133263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe	gettimeofday(&genesis, NULL);
134263e529f7d90892a610a5b26a519116fe3a675a6Jens Axboe}
1356043c5790f9978814ec25e3ea8f4d574daf6266eJens Axboe
1366043c5790f9978814ec25e3ea8f4d574daf6266eJens Axboevoid fill_start_time(struct timeval *t)
1376043c5790f9978814ec25e3ea8f4d574daf6266eJens Axboe{
1386043c5790f9978814ec25e3ea8f4d574daf6266eJens Axboe	memcpy(t, &genesis, sizeof(genesis));
1396043c5790f9978814ec25e3ea8f4d574daf6266eJens Axboe}
140