Merge branch 'master' into gfio
Conflicts:
eta.c
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/Makefile b/Makefile
index 5d4e3e7..ea8c851 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CC = gcc
+CC ?= gcc
DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
$(DEBUGFLAGS)
diff --git a/backend.c b/backend.c
index dcc6fba..f20857a 100644
--- a/backend.c
+++ b/backend.c
@@ -1631,7 +1631,7 @@
setup_disk_util();
- disk_thread_mutex = fio_mutex_init(0);
+ disk_thread_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL);
if (ret) {
@@ -1672,10 +1672,10 @@
setup_log(&agg_io_log[DDIR_WRITE], 0, IO_LOG_TYPE_BW);
}
- startup_mutex = fio_mutex_init(0);
+ startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
if (startup_mutex == NULL)
return 1;
- writeout_mutex = fio_mutex_init(1);
+ writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
if (writeout_mutex == NULL)
return 1;
diff --git a/cgroup.c b/cgroup.c
index ea6bbd6..86d4d5e 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -182,7 +182,7 @@
static void fio_init cgroup_init(void)
{
- lock = fio_mutex_init(1);
+ lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
}
static void fio_exit cgroup_exit(void)
diff --git a/diskutil.c b/diskutil.c
index 32616b7..a3a5b4d 100644
--- a/diskutil.c
+++ b/diskutil.c
@@ -132,13 +132,18 @@
struct flist_head *entry;
struct disk_util *du;
+ fio_mutex_down(disk_util_mutex);
+
flist_for_each(entry, &disk_list) {
du = flist_entry(entry, struct disk_util, list);
- if (major == du->major && minor == du->minor)
+ if (major == du->major && minor == du->minor) {
+ fio_mutex_up(disk_util_mutex);
return du;
+ }
}
+ fio_mutex_up(disk_util_mutex);
return NULL;
}
@@ -285,7 +290,7 @@
du->minor = mindev;
INIT_FLIST_HEAD(&du->slavelist);
INIT_FLIST_HEAD(&du->slaves);
- du->lock = fio_mutex_init(1);
+ du->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
du->users = 0;
fio_mutex_down(disk_util_mutex);
@@ -308,8 +313,9 @@
get_io_ticks(du, &du->last_dus);
flist_add_tail(&du->list, &disk_list);
- find_add_disk_slaves(td, path, du);
fio_mutex_up(disk_util_mutex);
+
+ find_add_disk_slaves(td, path, du);
return du;
}
@@ -618,5 +624,5 @@
void setup_disk_util(void)
{
- disk_util_mutex = fio_mutex_init(1);
+ disk_util_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
}
diff --git a/eta.c b/eta.c
index 34afe0c..e1050b5 100644
--- a/eta.c
+++ b/eta.c
@@ -285,14 +285,18 @@
|| td->runstate == TD_FSYNCING
|| td->runstate == TD_PRE_READING) {
je->nr_running++;
- je->t_rate[0] += td->o.rate[0];
- je->t_rate[1] += td->o.rate[1];
- je->m_rate[0] += td->o.ratemin[0];
- je->m_rate[1] += td->o.ratemin[1];
- je->t_iops[0] += td->o.rate_iops[0];
- je->t_iops[1] += td->o.rate_iops[1];
- je->m_iops[0] += td->o.rate_iops_min[0];
- je->m_iops[1] += td->o.rate_iops_min[1];
+ if (td_read(td)) {
+ je->t_rate[0] += td->o.rate[DDIR_READ];
+ je->t_iops[0] += td->o.rate_iops[DDIR_READ];
+ je->m_rate[0] += td->o.ratemin[DDIR_READ];
+ je->m_iops[0] += td->o.rate_iops_min[DDIR_READ];
+ }
+ if (td_write(td)) {
+ je->t_rate[1] += td->o.rate[DDIR_WRITE];
+ je->t_iops[1] += td->o.rate_iops[DDIR_WRITE];
+ je->m_rate[1] += td->o.ratemin[DDIR_WRITE];
+ je->m_iops[1] += td->o.rate_iops_min[DDIR_WRITE];
+ }
je->files_open += td->nr_open_files;
} else if (td->runstate == TD_RAMP) {
je->nr_running++;
diff --git a/file.h b/file.h
index 51df839..68f9a6e 100644
--- a/file.h
+++ b/file.h
@@ -147,6 +147,7 @@
struct thread_data;
extern void close_files(struct thread_data *);
extern void close_and_free_files(struct thread_data *);
+extern unsigned long long get_start_offset(struct thread_data *);
extern int __must_check setup_files(struct thread_data *);
extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_file *);
extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
diff --git a/filehash.c b/filehash.c
index 1bb1eb2..392464e 100644
--- a/filehash.c
+++ b/filehash.c
@@ -107,5 +107,5 @@
for (i = 0; i < HASH_BUCKETS; i++)
INIT_FLIST_HEAD(&file_hash[i]);
- hash_lock = fio_mutex_init(1);
+ hash_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
}
diff --git a/filesetup.c b/filesetup.c
index 76e142a..9c486be 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -657,6 +657,12 @@
return ret;
}
+unsigned long long get_start_offset(struct thread_data *td)
+{
+ return td->o.start_offset +
+ (td->thread_number - 1) * td->o.offset_increment;
+}
+
/*
* Open the files and setup files sizes, creating files if necessary.
*/
@@ -718,8 +724,7 @@
extend_size = total_size = 0;
need_extend = 0;
for_each_file(td, f, i) {
- f->file_offset = td->o.start_offset +
- (td->thread_number - 1) * td->o.offset_increment;
+ f->file_offset = get_start_offset(td);
if (!td->o.file_size_low) {
/*
@@ -1006,7 +1011,7 @@
f->lock = fio_mutex_rw_init();
break;
case FILE_LOCK_EXCLUSIVE:
- f->lock = fio_mutex_init(1);
+ f->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
break;
default:
log_err("fio: unknown lock mode: %d\n", td->o.file_lock_mode);
diff --git a/flow.c b/flow.c
index bf5eeec..2993f4e 100644
--- a/flow.c
+++ b/flow.c
@@ -92,7 +92,7 @@
void flow_init(void)
{
- flow_lock = fio_mutex_init(1);
+ flow_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
flow_list = smalloc(sizeof(*flow_list));
INIT_FLIST_HEAD(flow_list);
}
diff --git a/gettime.c b/gettime.c
index e8f5ab5..5b49287 100644
--- a/gettime.c
+++ b/gettime.c
@@ -304,7 +304,7 @@
pthread_attr_t attr;
int ret;
- mutex = fio_mutex_init(0);
+ mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
if (!mutex)
return 1;
diff --git a/init.c b/init.c
index 4f42a5c..2b581fb 100644
--- a/init.c
+++ b/init.c
@@ -810,7 +810,7 @@
f->real_file_size = -1ULL;
}
- td->mutex = fio_mutex_init(0);
+ td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
td->ts.clat_percentiles = td->o.clat_percentiles;
if (td->o.overwrite_plist)
diff --git a/io_u.c b/io_u.c
index 7e05ff9..28a86f7 100644
--- a/io_u.c
+++ b/io_u.c
@@ -256,7 +256,7 @@
{
assert(ddir_rw(ddir));
- if (f->last_pos >= f->io_size && td->o.time_based)
+ if (f->last_pos >= f->io_size + get_start_offset(td) && td->o.time_based)
f->last_pos = f->last_pos - f->io_size;
if (f->last_pos < f->real_file_size) {
@@ -377,7 +377,7 @@
{
struct fio_file *f = io_u->file;
- return io_u->offset + buflen <= f->io_size + td->o.start_offset;
+ return io_u->offset + buflen <= f->io_size + get_start_offset(td);
}
static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
diff --git a/mutex.h b/mutex.h
index 5938e95..6fdf7c6 100644
--- a/mutex.h
+++ b/mutex.h
@@ -10,6 +10,11 @@
int waiters;
};
+enum {
+ FIO_MUTEX_LOCKED = 0,
+ FIO_MUTEX_UNLOCKED = 1,
+};
+
extern struct fio_mutex *fio_mutex_init(int);
extern void fio_mutex_remove(struct fio_mutex *);
extern void fio_mutex_down(struct fio_mutex *);
diff --git a/os/windows/posix.c b/os/windows/posix.c
index 41bcb2d..bfffe77 100755
--- a/os/windows/posix.c
+++ b/os/windows/posix.c
@@ -20,6 +20,9 @@
#include "../os-windows.h"
+extern unsigned long mtime_since_now(struct timeval *);
+extern void fio_gettime(struct timeval *, void *);
+
long sysconf(int name)
{
long long val = -1;
@@ -95,8 +98,8 @@
int gettimeofday(struct timeval *restrict tp, void *restrict tzp)
{
FILETIME fileTime;
- unsigned long long unix_time, windows_time;
- const time_t MILLISECONDS_BETWEEN_1601_AND_1970 = 11644473600000;
+ uint64_t unix_time, windows_time;
+ const uint64_t MILLISECONDS_BETWEEN_1601_AND_1970 = 11644473600000;
/* Ignore the timezone parameter */
(void)tzp;
@@ -107,7 +110,7 @@
* Its precision is 100 ns but accuracy is only one clock tick, or normally around 15 ms.
*/
GetSystemTimeAsFileTime(&fileTime);
- windows_time = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
+ windows_time = ((uint64_t)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
/* Divide by 10,000 to convert to ms and subtract the time between 1601 and 1970 */
unix_time = (((windows_time)/10000) - MILLISECONDS_BETWEEN_1601_AND_1970);
/* unix_time is now the number of milliseconds since 1970 (the Unix epoch) */
@@ -264,7 +267,7 @@
tp->tv_sec = counts.QuadPart / freq.QuadPart;
/* Get the difference between the number of ns stored
* in 'tv_sec' and that stored in 'counts' */
- unsigned long long t = tp->tv_sec * freq.QuadPart;
+ uint64_t t = tp->tv_sec * freq.QuadPart;
t = counts.QuadPart - t;
/* 't' now contains the number of cycles since the last second.
* We want the number of nanoseconds, so multiply out by 1,000,000,000
@@ -321,17 +324,17 @@
i = strlen(path) - 1;
- while (name[i] != '\\' && name[i] != '/' && i >= 0)
+ while (path[i] != '\\' && path[i] != '/' && i >= 0)
i--;
- strcpy(name, path + i);
+ strncpy(name, path + i + 1, MAX_PATH);
return name;
}
int posix_fallocate(int fd, off_t offset, off_t len)
{
- const int BUFFER_SIZE = 64*1024*1024;
+ const int BUFFER_SIZE = 64 * 1024 * 1024;
int rc = 0;
char *buf;
unsigned int write_len;
@@ -348,7 +351,9 @@
memset(buf, 0, BUFFER_SIZE);
- if (lseek(fd, offset, SEEK_SET) == -1)
+ int64_t prev_pos = _telli64(fd);
+
+ if (_lseeki64(fd, offset, SEEK_SET) == -1)
return errno;
while (bytes_remaining > 0) {
@@ -367,17 +372,18 @@
}
free(buf);
+ _lseeki64(fd, prev_pos, SEEK_SET);
return rc;
}
int ftruncate(int fildes, off_t length)
{
BOOL bSuccess;
- int old_pos = tell(fildes);
- lseek(fildes, length, SEEK_SET);
+ int64_t prev_pos = _telli64(fildes);
+ _lseeki64(fildes, length, SEEK_SET);
HANDLE hFile = (HANDLE)_get_osfhandle(fildes);
bSuccess = SetEndOfFile(hFile);
- lseek(fildes, old_pos, SEEK_SET);
+ _lseeki64(fildes, prev_pos, SEEK_SET);
return !bSuccess;
}
@@ -459,7 +465,7 @@
int getrusage(int who, struct rusage *r_usage)
{
- const time_t SECONDS_BETWEEN_1601_AND_1970 = 11644473600;
+ const uint64_t SECONDS_BETWEEN_1601_AND_1970 = 11644473600;
FILETIME cTime, eTime, kTime, uTime;
time_t time;
@@ -467,14 +473,14 @@
HANDLE hProcess = GetCurrentProcess();
GetProcessTimes(hProcess, &cTime, &eTime, &kTime, &uTime);
- time = ((unsigned long long)uTime.dwHighDateTime << 32) + uTime.dwLowDateTime;
+ time = ((uint64_t)uTime.dwHighDateTime << 32) + uTime.dwLowDateTime;
/* Divide by 10,000,000 to get the number of seconds and move the epoch from
* 1601 to 1970 */
time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
r_usage->ru_utime.tv_sec = time;
/* getrusage() doesn't care about anything other than seconds, so set tv_usec to 0 */
r_usage->ru_utime.tv_usec = 0;
- time = ((unsigned long long)kTime.dwHighDateTime << 32) + kTime.dwLowDateTime;
+ time = ((uint64_t)kTime.dwHighDateTime << 32) + kTime.dwLowDateTime;
/* Divide by 10,000,000 to get the number of seconds and move the epoch from
* 1601 to 1970 */
time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
@@ -505,17 +511,17 @@
ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
off_t offset)
{
- long pos = tell(fildes);
- ssize_t len = write(fildes, buf, nbyte);
- lseek(fildes, pos, SEEK_SET);
+ int64_t pos = _telli64(fildes);
+ ssize_t len = _write(fildes, buf, nbyte);
+ _lseeki64(fildes, pos, SEEK_SET);
return len;
}
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
{
- long pos = tell(fildes);
+ int64_t pos = _telli64(fildes);
ssize_t len = read(fildes, buf, nbyte);
- lseek(fildes, pos, SEEK_SET);
+ _lseeki64(fildes, pos, SEEK_SET);
return len;
}
@@ -631,9 +637,30 @@
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
- log_err("%s is not implemented\n", __func__);
- errno = ENOSYS;
- return -1;
+ struct timeval tv;
+ DWORD ms_remaining;
+ DWORD ms_total = (rqtp->tv_sec * 1000) + (rqtp->tv_nsec / 1000000.0);
+
+ if (ms_total == 0)
+ ms_total = 1;
+
+ ms_remaining = ms_total;
+
+ /* Since Sleep() can sleep for less than the requested time, add a loop to
+ ensure we only return after the requested length of time has elapsed */
+ do {
+ fio_gettime(&tv, NULL);
+ Sleep(ms_remaining);
+ ms_remaining = ms_total - mtime_since_now(&tv);
+ } while (ms_remaining > 0 && ms_remaining < ms_total);
+
+ /* this implementation will never sleep for less than the requested time */
+ if (rmtp != NULL) {
+ rmtp->tv_sec = 0;
+ rmtp->tv_nsec = 0;
+ }
+
+ return 0;
}
DIR *opendir(const char *dirname)
diff --git a/smalloc.c b/smalloc.c
index 5ba2004..d0b6f1e 100644
--- a/smalloc.c
+++ b/smalloc.c
@@ -206,7 +206,7 @@
pool->map = ptr;
pool->bitmap = (void *) ptr + (pool->nr_blocks * SMALLOC_BPL);
- pool->lock = fio_mutex_init(1);
+ pool->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
if (!pool->lock)
goto out_fail;