diff --git a/linux/file.c b/linux/file.c index 2f26c3c7878..fcea3b721ca 100644 --- a/linux/file.c +++ b/linux/file.c @@ -166,19 +166,33 @@ toku_os_write (int fd, const void *buf, size_t len) { return 0; } +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// fsync logic: + // t_fsync exists for testing purposes only static int (*t_fsync)(int) = 0; static uint64_t toku_fsync_count; static uint64_t toku_fsync_time; +static uint64_t sched_fsync_count; +static uint64_t sched_fsync_time; + int toku_set_func_fsync(int (*fsync_function)(int)) { t_fsync = fsync_function; return 0; } -int -toku_file_fsync_without_accounting (int fd) { +static uint64_t get_tnow(void) { + struct timeval tv; + int r = gettimeofday(&tv, NULL); assert(r == 0); + return tv.tv_sec * 1000000ULL + tv.tv_usec; +} + +// keep trying if fsync fails because of EINTR +static int +file_fsync_internal (int fd, uint64_t *duration_p) { + uint64_t tstart = get_tnow(); int r = -1; while (r != 0) { if (t_fsync) @@ -191,6 +205,17 @@ toku_file_fsync_without_accounting (int fd) { assert(rr==EINTR); } } + toku_sync_fetch_and_increment_uint64(&toku_fsync_count); + uint64_t duration; + duration = get_tnow() - tstart; + toku_sync_fetch_and_add_uint64(&toku_fsync_time, duration); + if (duration_p) *duration_p = duration; + return r; +} + +int +toku_file_fsync_without_accounting (int fd) { + int r = file_fsync_internal (fd, NULL); return r; } @@ -198,34 +223,34 @@ int toku_fsync_dirfd_without_accounting(DIR *dirp) { int r; int fd = dirfd(dirp); - if (fd<0) { + if (fd < 0) { r = -1; - } - else { + } else { r = toku_file_fsync_without_accounting(fd); } return r; } -static uint64_t get_tnow(void) { - struct timeval tv; - int r = gettimeofday(&tv, NULL); assert(r == 0); - return tv.tv_sec * 1000000ULL + tv.tv_usec; -} - -// keep trying if fsync fails because of EINTR +// include fsync in scheduling accounting int toku_file_fsync(int fd) { - uint64_t tstart = get_tnow(); - int r = toku_file_fsync_without_accounting(fd); - toku_sync_fetch_and_increment_uint64(&toku_fsync_count); - toku_sync_fetch_and_add_uint64(&toku_fsync_time, get_tnow() - tstart); + uint64_t duration; + int r = file_fsync_internal (fd, &duration); + toku_sync_fetch_and_increment_uint64(&sched_fsync_count); + toku_sync_fetch_and_add_uint64(&sched_fsync_time, duration); return r; } +// for real accounting void toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time) { *fsync_count = toku_fsync_count; *fsync_time = toku_fsync_time; } +// for scheduling algorithm only +void +toku_get_fsync_sched(uint64_t *fsync_count, uint64_t *fsync_time) { + *fsync_count = sched_fsync_count; + *fsync_time = sched_fsync_time; +} diff --git a/src/elocks.c b/src/elocks.c index a7c643e8624..a1708b4954a 100644 --- a/src/elocks.c +++ b/src/elocks.c @@ -182,7 +182,7 @@ toku_ydb_lock(void) { } status.max_requested_sleep = u64max(status.max_requested_sleep, requested_sleep); toku_cachetable_get_miss_times(NULL, &ydb_big_lock.start_miss_count, &ydb_big_lock.start_miss_time); - toku_get_fsync_times(&ydb_big_lock.start_fsync_count, &ydb_big_lock.start_fsync_time); + toku_get_fsync_sched(&ydb_big_lock.start_fsync_count, &ydb_big_lock.start_fsync_time); if (new_ydbtime) toku_list_push(&ydb_big_lock.all_ydbtimes, &ydbtime->all_ydbtimes); #endif @@ -215,7 +215,7 @@ toku_ydb_unlock(void) { disk_count = disk_count - ydb_big_lock.start_miss_count; // number of cache misses disk_time = disk_time - ydb_big_lock.start_miss_time; // usec spent waiting for disk reads uint64_t fsync_count, fsync_time; - toku_get_fsync_times(&fsync_count, &fsync_time); // number of fsync operations + toku_get_fsync_sched(&fsync_count, &fsync_time); // number of fsync operations disk_count += fsync_count - ydb_big_lock.start_fsync_count; // time waiting for fsyncs to complete disk_time += fsync_time - ydb_big_lock.start_fsync_time; if (disk_count == 0) { diff --git a/toku_include/toku_portability.h b/toku_include/toku_portability.h index 80d0a48030d..88a9a8eeadb 100644 --- a/toku_include/toku_portability.h +++ b/toku_include/toku_portability.h @@ -142,9 +142,12 @@ int toku_os_write (int fd, const void *buf, size_t len) __attribute__((__visibil int toku_file_fsync_without_accounting(int fd); int toku_file_fsync(int fd); -// get the number of fsync calls and the fsync times +// get the number of fsync calls and the fsync times (total) void toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time); +// get the number of fsync calls and the fsync times for use by scheduler (subset of total) +void toku_get_fsync_sched(uint64_t *fsync_count, uint64_t *fsync_time); + // set a new fsync function (for debugging) int toku_set_func_fsync (int (*fsync_function)(int));