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