Commit 7ac59d04 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

add fsync time to the fair scheduler closes[t:2170]

git-svn-id: file:///svn/toku/tokudb@15815 c7de825b-a66e-492c-adef-691d508d4ae1
parent 07c509c3
#include <toku_portability.h>
#include <toku_atomic.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
......@@ -82,7 +83,15 @@ again:
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;
}
static int (*t_fsync)(int) = 0;
static uint64_t toku_fsync_count;
static uint64_t toku_fsync_time;
int
toku_set_func_fsync(int (*fsync_function)(int)) {
......@@ -93,9 +102,19 @@ toku_set_func_fsync(int (*fsync_function)(int)) {
int
toku_file_fsync(int fd) {
int r;
uint64_t tstart = get_tnow();
if (t_fsync)
r = t_fsync(fd);
else
r = fsync(fd);
toku_sync_fetch_and_add_uint64(&toku_fsync_count, 1);
toku_sync_fetch_and_add_uint64(&toku_fsync_time, get_tnow() - tstart);
return r;
}
void
toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time) {
*fsync_count = toku_fsync_count;
*fsync_time = toku_fsync_time;
}
......@@ -29,7 +29,8 @@ struct ydb_big_lock {
#if YDB_LOCK_MISS_TIME
int32_t waiters;
toku_pthread_key_t time_key;
uint64_t start_misscount, start_misstime;
uint64_t start_miss_count, start_miss_time;
uint64_t start_fsync_count, start_fsync_time;
#endif
};
static struct ydb_big_lock ydb_big_lock;
......@@ -155,7 +156,8 @@ toku_ydb_lock(void) {
(void) toku_sync_fetch_and_add_int32(&ydb_big_lock.waiters, -1);
}
status.max_requested_sleep = u64max(status.max_requested_sleep, requested_sleep);
toku_cachetable_get_miss_times(NULL, &ydb_big_lock.start_misscount, &ydb_big_lock.start_misstime);
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);
#endif
status.ydb_lock_ctr++;
......@@ -181,16 +183,18 @@ toku_ydb_unlock(void) {
if (waiters == 0) {
theld = 0;
} else {
uint64_t misscount, misstime;
toku_cachetable_get_miss_times(NULL, &misscount, &misstime);
misscount -= ydb_big_lock.start_misscount; // how many cache misses for this operation
misstime -= ydb_big_lock.start_misstime; // how many usec spent waiting for disk read this operation
if (0 && (misscount || misstime))
printf("%d %"PRIu64" %"PRIu64"\n", waiters, misscount, misstime);
if (misscount == 0) {
uint64_t disk_count, disk_time; // number of disk reads + fsyncs and the time waiting on disk reads + fsyncs
toku_cachetable_get_miss_times(NULL, &disk_count, &disk_time);
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
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) {
theld = 0;
} else {
theld = misstime ? misstime : misscount * 20000ULL; // if we decide not to compile in misstime, then backoff to 20 milliseconds per cache miss
theld = disk_time ? disk_time : disk_count * 20000ULL; // if we decide not to compile in miss_time, then backoff to 20 milliseconds per cache miss
if (theld < MAXTHELD) {
status.max_time_ydb_lock_held = u64max(status.max_time_ydb_lock_held, theld);
......
#if !defined(TOKU_ATOMIC_H)
#define TOKU_ATOMIC_H
#define TOKU_INLINE32 inline
static TOKU_INLINE32 int32_t toku_sync_fetch_and_add_int32(int32_t *a, int32_t b) {
return __sync_fetch_and_add(a, b);
}
#if __GNUC__ && __i386__
#define TOKU_INLINE64
// workaround for a gcc 4.1.2 bug on 32 bit platforms.
static uint64_t toku_sync_fetch_and_add_uint64(uint64_t *a, uint64_t b) __attribute__((noinline));
#else
#define TOKU_INLINE64 inline
#endif
static int32_t toku_sync_fetch_and_add_int32(int32_t *a, int32_t b) {
return __sync_fetch_and_add(a, b);
}
static uint64_t toku_sync_fetch_and_add_uint64(uint64_t *a, uint64_t b) {
static TOKU_INLINE64 uint64_t toku_sync_fetch_and_add_uint64(uint64_t *a, uint64_t b) {
return __sync_fetch_and_add(a, b);
}
......
......@@ -121,10 +121,16 @@ void *os_realloc(void*,size_t);
void os_free(void*);
ssize_t toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off);
ssize_t toku_os_write (int fd, const void *buf, size_t len);
// wrapper around fsync
int toku_file_fsync(int fd);
int toku_get_fsync_times(void);
// get the number of fsync calls and the fsync times
void toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time);
// set a new fsync function (for debugging)
int toku_set_func_fsync (int (*fsync_function)(int));
int toku_set_func_malloc (void *(*)(size_t));
int toku_set_func_realloc (void *(*)(void*,size_t));
int toku_set_func_free (void (*)(void*));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment