Various fixes/updates
authorBruce Cran <bruce@cran.org.uk>
Sat, 8 Jan 2011 18:49:54 +0000 (19:49 +0100)
committerJens Axboe <jaxboe@fusionio.com>
Sat, 8 Jan 2011 18:49:54 +0000 (19:49 +0100)
- Update HOWTO to note that directio and fallocate don't work with ZFS
  on Solaris.

Refactor the Makefile's to add CPPFLAGS and LIBS.
- Add -fno-omit-frame-pointer from Linux Makefile to every platform
- Change undefined $(ALL_CFLAGS) to $(CFLAGS)
- Pass -std=gnu99, without which OS X fails to build.
- Add -D__EXTENSIONS__ on Solaris since some functions we need are
  behind it.

- Pull in <limits.h> in fio.c to get PTHREAD_STACK_MIN.
- NetBSD doesn't define PTHREAD_STACK_MIN so set it to 4k in
   os-netbsd.h

- If we have posix_fallocate don't error out if it fails during mutex
  and malloc operations since it will fail on Solaris with a ZFS
  filesystem. As I understand it these aren't performance-critical
  operations so do they need to be considered critical?

- Remove fio_unused from os-* files since it's defined in fio.h and we
  don't really need it.

- FreeBSD has an idprio command but not the API so don't claim it does.

- OS X doesn't have the timer_* API so emulate it using
  setitimer/sigaction.

- NetBSD and Solaris don't support CLOCK_MONOTONIC in timer_create so
  remove FIO_HAVE_CLOCK_MONOTONIC from their os-* files.

I've noticed that a change I made a while ago to use fmin/fmax could
cause issues on older OSes - I had a CD with NetBSD 5.0.2 and found
they had only been implemented in 5.1 so I'm not sure if I should
revert it.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
21 files changed:
HOWTO
Makefile
Makefile.FreeBSD
Makefile.NetBSD
Makefile.Windows
Makefile.aix
Makefile.mac
Makefile.solaris
compiler/compiler-gcc3.h
compiler/compiler.h
engines/windowsaio.c
filesetup.c
fio.c
mutex.c
os/os-aix.h
os/os-freebsd.h
os/os-mac.h
os/os-netbsd.h
os/os-solaris.h
os/os-windows.h
smalloc.c

diff --git a/HOWTO b/HOWTO
index 35dccfb..e54382b 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -351,7 +351,8 @@ randrepeat=bool     For random IO workloads, seed the generator in a predictable
 fallocate=bool By default, fio will use fallocate() to advise the system
                of the size of the file we are going to write. This can be
                turned off with fallocate=0. May not be available on all
-               supported platforms.
+               supported platforms.  If using ZFS on Solaris this must be
+               set to 0 because ZFS doesn't support it.
 
 fadvise_hint=bool By default, fio will use fadvise() to advise the kernel
                on what IO patterns it is likely to issue. Sometimes you
@@ -555,7 +556,7 @@ iodepth=int This defines how many io units to keep in flight against
                job, can be overridden with a larger value for higher
                concurrency. Note that increasing iodepth beyond 1 will not
                affect synchronous ioengines (except for small degress when
-               verify_async is in use). Even async engines my impose OS
+               verify_async is in use). Even async engines may impose OS
                restrictions causing the desired depth not to be achieved.
                This may happen on Linux when using libaio and not setting
                direct=1, since buffered IO is not async on that OS. Keep an
@@ -585,7 +586,7 @@ iodepth_low=int     The low water mark indicating when to start filling
                the depth drain down to 4 before starting to fill it again.
 
 direct=bool    If value is true, use non-buffered io. This is usually
-               O_DIRECT.
+               O_DIRECT. Note that ZFS on Solaris doesn't support direct io.
 
 buffered=bool  If value is true, use buffered io. This is the opposite
                of the 'direct' option. Defaults to true.
index 04cb60f..d3d6c43 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,43 +1,23 @@
 CC     = gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-OPTFLAGS= -O2 -g $(EXTFLAGS)
-CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -fno-omit-frame-pointer -rdynamic
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
+       $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
+LIBS   = -lpthread -lm -ldl -lrt -laio
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o diskutil.o fifo.o blktrace.o smalloc.o filehash.o helpers.o \
-       cgroup.o profile.o debug.o trim.o
-
-OBJS += lib/rand.o
-OBJS += lib/flist_sort.o
-OBJS += lib/num2str.o
-
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/libaio.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sg.o
-OBJS += engines/splice.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-OBJS += engines/syslet-rw.o
-OBJS += engines/guasi.o
-OBJS += engines/binject.o
-
-OBJS += profiles/tiobench.o
+       
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       diskutil.c fifo.c blktrace.c smalloc.c filehash.c helpers.c \
+       cgroup.c profile.c debug.c trim.c lib/rand.c lib/flist_sort.c \
+       lib/num2str.c $(wildcard crc/*.c) engines/cpu.c engines/libaio.c \
+       engines/mmap.c engines/posixaio.c engines/sg.c engines/splice.c \
+       engines/sync.c engines/null.c engines/net.c engines/syslet-rw.c \
+       engines/guasi.c engines/binject.c profiles/tiobench.c
+       
+OBJS = $(SOURCE:.c=.o)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -51,13 +31,14 @@ prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -ldl -laio -lrt
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
 
 depend:
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) *.c engines/*.c crc/*.c 1> .depend
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
 $(PROGS): depend
 
index c9a1422..91e4089 100644 (file)
@@ -1,39 +1,21 @@
 CC     = gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-OPTFLAGS= -O2 -g $(EXTFLAGS)
-CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -rdynamic
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
+       $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
+LIBS   = -lpthread -lm -lrt
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o
 
-OBJS += lib/rand.o
-OBJS += lib/flist_sort.o
-OBJS += lib/num2str.o
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
+       lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
+       engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
+       engines/net.c
 
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-
-SOURCE = eta.c filehash.c filesetup.c fio.c gettime.c init.c ioengines.c \
-        io_u.c log.c memory.c mutex.c options.c parse.c rbtree.c smalloc.c \
-        stat.c parse.c crc/*.c engines/cpu.c engines/mmap.c \
-        engines/posixaio.c engines/sync.c engines/null.c engines/net.c
+OBJS = $(SOURCE:.c=.o)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -47,13 +29,14 @@ prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -pthread -lm -lrt
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
 
 depend:
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) $(SOURCE) 1> .depend
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
 $(PROGS): depend
 
index 02ff95d..77e75df 100644 (file)
@@ -1,39 +1,20 @@
 CC     = gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-OPTFLAGS= -O2 -g $(EXTFLAGS)
-CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -rdynamic
+CPPFLAGS= -D_GNU_SOURCE $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
+LIBS   = -lpthread -lm -lrt
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o
 
-OBJS += lib/rand.o
-OBJS += lib/flist_sort.o
-OBJS += lib/num2str.o
-
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-
-SOURCE = eta.c filehash.c filesetup.c fio.c gettime.c init.c ioengines.c \
-        io_u.c log.c memory.c mutex.c options.c parse.c rbtree.c smalloc.c \
-        stat.c parse.c crc/*.c engines/cpu.c engines/mmap.c \
-        engines/posixaio.c engines/sync.c engines/null.c engines/net.c
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
+       lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
+       engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
+       engines/net.c
+       
+OBJS = $(SOURCE:.c=.o)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -47,13 +28,14 @@ prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -lrt
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
 
 depend:
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) $(SOURCE) 1> .depend
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
 $(PROGS): depend
 
index 97a2813..f8e2697 100644 (file)
@@ -1,40 +1,21 @@
-CC     = gcc-3\r
-DEBUGFLAGS = -DFIO_INC_DEBUG\r
-OPTFLAGS=  -O2 -g $(EXTFLAGS)\r
-CFLAGS =  -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) \r
+CC     = gcc\r
+DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG\r
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \\r
+       $(DEBUGFLAGS)\r
+OPTFLAGS= -O2 -fno-omit-frame-pointer -gstabs+\r
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS)\r
+LIBS   = -lpthread -lm -lrt\r
 PROGS  = fio\r
 SCRIPTS = fio_generate_plots\r
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \\r
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \\r
-       rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o\r
 \r
-OBJS += lib/rand.o\r
-OBJS += lib/flist_sort.o\r
-OBJS += lib/num2str.o\r
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \\r
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \\r
+       smalloc.c filehash.c profile.c debug.c lib/rand.c \\r
+       lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \\r
+       engines/mmap.c engines/sync.c engines/null.c engines/net.c \\r
+       engines/net.c engines/windowsaio.c\r
 \r
-OBJS += crc/crc7.o\r
-OBJS += crc/crc16.o\r
-OBJS += crc/crc32.o\r
-OBJS += crc/crc32c.o\r
-OBJS += crc/crc32c-intel.o\r
-OBJS += crc/crc64.o\r
-OBJS += crc/sha1.o\r
-OBJS += crc/sha256.o\r
-OBJS += crc/sha512.o\r
-OBJS += crc/md5.o\r
-\r
-OBJS += engines/cpu.o\r
-OBJS += engines/mmap.o\r
-OBJS += engines/posixaio.o\r
-OBJS += engines/sync.o\r
-OBJS += engines/null.o\r
-OBJS += engines/net.o\r
-OBJS += engines/windowsaio.o\r
-\r
-SOURCE = eta.c filehash.c filesetup.c fio.c gettime.c init.c ioengines.c \\r
-        io_u.c log.c memory.c mutex.c options.c parse.c rbtree.c smalloc.c \\r
-        stat.c parse.c crc/*.c engines/cpu.c engines/mmap.c \\r
-        engines/posixaio.c engines/sync.c engines/null.c engines/net.c engines/windowsaio.c\r
+OBJS = $(SOURCE:.c=.o)\r
 \r
 ifneq ($(findstring $(MAKEFLAGS),s),s)\r
 ifndef V\r
@@ -48,14 +29,15 @@ prefix = /usr/local
 bindir = $(prefix)/bin\r
 mandir = $(prefix)/man\r
 \r
-%.o: %.c\r
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<\r
+.c.o:\r
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<\r
+\r
 fio: $(OBJS)\r
        $(QUIET_CC)windres os/windows/version.rc -O coff -o version.o\r
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -lrt version.o\r
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) version.o\r
 \r
 depend:\r
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) $(SOURCE) 1> .depend\r
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend\r
 \r
 $(PROGS): depend\r
 \r
index 32d22a3..fd49e06 100644 (file)
@@ -1,37 +1,21 @@
 CC     = gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-OPTFLAGS= -O2 -g $(EXTFLAGS)
-CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -fno-omit-frame-pointer -D_LARGE_FILES -D__ppc__
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
+       -D_LARGE_FILES -D__ppc__ $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
+LIBS   = -lpthread -lm -ldl -lrt
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o fifo.o smalloc.o filehash.o helpers.o \
-       profile.o debug.o
 
-OBJS += lib/rand.o
-OBJS += lib/getopt_long.o
-OBJS += lib/num2str.o
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       fifo.c smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
+       lib/getopt_long.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
+       engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
+       engines/net.c profiles/tiobench.c
 
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-
-OBJS += profiles/tiobench.o
+OBJS = $(SOURCE:.c=.o)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -45,13 +29,14 @@ prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -ldl -lrt
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
 
 depend:
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) *.c engines/*.c crc/*.c 1> .depend
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
 $(PROGS): depend
 
index 3eb20be..f237aba 100644 (file)
@@ -1,39 +1,21 @@
 CC     = gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-OPTFLAGS= -O2 -g $(EXTFLAGS)
-CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -rdynamic
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
+       $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
+LIBS   = -lpthread -lm -ldl
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o
 
-OBJS += lib/rand.o
-OBJS += lib/flist_sort.o
-OBJS += lib/num2str.o
-
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-
-SOURCE = eta.c filehash.c filesetup.c fio.c gettime.c init.c ioengines.c \
-        io_u.c log.c memory.c mutex.c options.c parse.c rbtree.c smalloc.c \
-        stat.c parse.c crc/*.c engines/cpu.c engines/mmap.c \
-        engines/posixaio.c engines/sync.c engines/null.c engines/net.c
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
+       lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
+       engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
+       engines/net.c
+       
+OBJS = $(SOURCE:.c=.o)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -47,13 +29,14 @@ prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
 
 depend:
-       $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) $(SOURCE) 1> .depend
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
 $(PROGS): depend
 
index 3b499e4..8423312 100644 (file)
@@ -1,46 +1,46 @@
 CC     = gcc
-CFLAGS = -Wall -O2 -g -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INC_DEBUG
+DEBUGFLAGS = -DFIO_INC_DEBUG
+CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
+       -D__EXTENSIONS__ $(DEBUGFLAGS)
+OPTFLAGS= -O2 -fno-omit-frame-pointer -g
+CFLAGS = -std=gnu99 -Wall $(OPTFLAGS)
+LIBS   = -lpthread -lm -ldl -laio -lrt -lnsl -lsocket
 PROGS  = fio
 SCRIPTS = fio_generate_plots
-OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
-       eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
-       rbtree.o fifo.o smalloc.o filehash.o lib/strsep.o helpers.o solaris.o \
-       profile.o debug.o
-
-OBJS += lib/rand.o
-OBJS += lib/flist_sort.o
-OBJS += lib/num2str.o
-
-OBJS += crc/crc7.o
-OBJS += crc/crc16.o
-OBJS += crc/crc32.o
-OBJS += crc/crc32c.o
-OBJS += crc/crc32c-intel.o
-OBJS += crc/crc64.o
-OBJS += crc/sha1.o
-OBJS += crc/sha256.o
-OBJS += crc/sha512.o
-OBJS += crc/md5.o
-
-OBJS += engines/cpu.o
-OBJS += engines/mmap.o
-OBJS += engines/posixaio.o
-OBJS += engines/sync.o
-OBJS += engines/null.o
-OBJS += engines/net.o
-OBJS += engines/solarisaio.o
+
+SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
+       eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
+       fifo.c smalloc.c filehash.c lib/strsep.c helpers.c solaris.c \
+       profile.c debug.c lib/rand.c lib/flist_sort.c lib/num2str.c \
+       $(wildcard crc/*.c) engines/cpu.c engines/mmap.c engines/posixaio.c \
+       engines/sync.c engines/null.c engines/net.c engines/solarisaio.c
+
+OBJS = $(SOURCE:.c=.o)
+
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+       QUIET_CC        = @echo '   ' CC $@;
+       QUIET_DEP       = @echo '   ' DEP $@;
+endif
+endif
 
 INSTALL = install
 prefix = /usr/local
 bindir = $(prefix)/bin
 mandir = $(prefix)/man
 
-%.o: %.c
-       $(CC) -o $*.o -c $(CFLAGS) $<
+.c.o:
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
+       
 fio: $(OBJS)
-       $(CC) $(CFLAGS) -o $@ $(OBJS) $(EXTLIBS) -lpthread -lm -ldl -laio -lrt -lnsl -lsocket
+       $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
+       
+depend:
+       $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
 
-all: $(PROGS) $(SCRIPTS)
+$(PROGS): depend
+
+all: depend $(PROGS) $(SCRIPTS)
 
 clean:
        -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
@@ -54,3 +54,7 @@ install: $(PROGS) $(SCRIPTS)
        $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
        $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
        $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
index 2fcc0d8..566987a 100644 (file)
@@ -7,8 +7,4 @@
 #endif
 #endif
 
-#ifdef __CYGWIN__
-#define __weak
-#endif
-
 #endif
index c1923dd..33500a9 100644 (file)
 #define uninitialized_var(x) x = x
 
 #ifndef __weak
+#ifndef __CYGWIN__
 #define __weak __attribute__((weak))
+#else
+#define __weak
+#endif
 #endif
 
 #endif
index 849ae41..f66b9a2 100644 (file)
 
 #include "../fio.h"
 
-BOOL windowsaio_debug = FALSE;
-
-struct windowsaio_data {
-       struct io_u **aio_events;
-       HANDLE *busyIoHandles;
-       unsigned int busyIo;
-       unsigned int ioFinished;
-       BOOL running;
-       BOOL stopped;
-       HANDLE hThread;
-};
-
 typedef struct {
  OVERLAPPED o;
  struct io_u *io_u;
 } FIO_OVERLAPPED;
 
+struct windowsaio_data {
+       HANDLE *io_handles;
+       unsigned int io_index;
+       FIO_OVERLAPPED *ovls;
+
+       HANDLE iothread;
+       HANDLE iothread_stopped;
+       BOOL iothread_running;
+
+       struct io_u **aio_events;
+       HANDLE iocomplete_event;
+       BOOL have_cancelioex;
+};
+
 struct thread_ctx {
-       HANDLE ioCP;
+       HANDLE iocp;
        struct windowsaio_data *wd;
 };
 
 static void PrintError(LPCSTR lpszFunction);
 static int fio_windowsaio_cancel(struct thread_data *td,
                               struct io_u *io_u);
-static BOOL TimedOut(DWORD startCount, DWORD endCount);
+static BOOL TimedOut(DWORD start_count, DWORD end_count);
 static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min,
                                    unsigned int max, struct timespec *t);
 static struct io_u *fio_windowsaio_event(struct thread_data *td, int event);
@@ -49,6 +51,21 @@ static int fio_windowsaio_init(struct thread_data *td);
 static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f);
 static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct fio_file *f);
 
+/* CancelIoEx isn't in Cygwin's w32api */
+BOOL WINAPI CancelIoEx(
+  HANDLE hFile,
+  LPOVERLAPPED lpOverlapped
+);
+
+
+
+int sync_file_range(int fd, off64_t offset, off64_t nbytes,
+                          unsigned int flags)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
 static void PrintError(LPCSTR lpszFunction)
 {
        // Retrieve the system error message for the last-error code
@@ -73,27 +90,31 @@ static void PrintError(LPCSTR lpszFunction)
 static int fio_windowsaio_cancel(struct thread_data *td,
                               struct io_u *io_u)
 {
-       BOOL bSuccess;
        int rc = 0;
 
-       bSuccess = CancelIo(io_u->file->hFile);
+       struct windowsaio_data *wd = td->io_ops->data;
 
-       if (!bSuccess)
+       /* If we're running on Vista, we can cancel individual IO requests */
+       if (wd->have_cancelioex) {
+               FIO_OVERLAPPED *ovl = io_u->engine_data;
+               if (!CancelIoEx(io_u->file->hFile, &ovl->o))
+                       rc = 1;
+       } else
                rc = 1;
 
        return rc;
 }
 
-static BOOL TimedOut(DWORD startCount, DWORD endCount)
+static BOOL TimedOut(DWORD start_count, DWORD end_count)
 {
        BOOL expired = FALSE;
-       DWORD currentTime;
+       DWORD current_time;
 
-       currentTime = GetTickCount();
+       current_time = GetTickCount();
 
-       if ((endCount > startCount) && currentTime >= endCount)
+       if ((end_count > start_count) && current_time >= end_count)
                expired = TRUE;
-       else if (currentTime < startCount && currentTime > endCount)
+       else if (current_time < start_count && current_time > end_count)
                expired = TRUE;
 
        return expired;
@@ -106,39 +127,35 @@ static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min,
        struct flist_head *entry;
        unsigned int dequeued = 0;
        struct io_u *io_u;
-       DWORD startCount = 0, endCount = 0;
+       DWORD start_count = 0, end_count = 0;
        BOOL timedout = FALSE;
-       unsigned int r = 0;
-       unsigned int waitInMs = 100;
+       unsigned int mswait = 100;
 
        if (t != NULL) {
-               waitInMs = (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
-               startCount = GetTickCount();
-               endCount = startCount + (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
+               mswait = (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
+               start_count = GetTickCount();
+               end_count = start_count + (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
        }
 
        while (dequeued < min && !timedout) {
-               WaitForMultipleObjects(wd->busyIo, wd->busyIoHandles, FALSE, waitInMs);
-
                flist_for_each(entry, &td->io_u_busylist) {
                        io_u = flist_entry(entry, struct io_u, list);
 
-                       if (io_u->seen == 0)
-                               continue;
-
-                       dequeued++;
-
-                       wd->ioFinished--;
-                       wd->aio_events[r] = io_u;
-                       r++;
-
-                       wd->busyIo--;
+                       if (io_u->seen == 1) {
+                               io_u->seen = 2;
+                               wd->aio_events[dequeued] = io_u;
+                               dequeued++;
+                       }
 
                        if (dequeued == max)
                                break;
                }
 
-               if (t != NULL && TimedOut(startCount, endCount))
+               if (dequeued < min) {
+                       WaitForSingleObject(wd->iocomplete_event, mswait);
+               }
+
+               if (t != NULL && TimedOut(start_count, end_count))
                        timedout = TRUE;
        }
 
@@ -154,35 +171,33 @@ static struct io_u *fio_windowsaio_event(struct thread_data *td, int event)
 static int fio_windowsaio_queue(struct thread_data *td,
                              struct io_u *io_u)
 {
-       FIO_OVERLAPPED *fov;
-       DWORD ioBytes;
-       BOOL bSuccess = TRUE;
+       struct windowsaio_data *wd;
+       DWORD iobytes;
+       BOOL success = TRUE;
+       int ind;
        int rc;
 
        fio_ro_check(td, io_u);
 
-       fov = malloc(sizeof(FIO_OVERLAPPED));
-       ZeroMemory(fov, sizeof(FIO_OVERLAPPED));
+       wd = td->io_ops->data;
+       ind = wd->io_index;
 
-       struct windowsaio_data *wd = td->io_ops->data;
+       ResetEvent(wd->io_handles[ind]);
+       wd->ovls[ind].o.Internal = 0;
+       wd->ovls[ind].o.InternalHigh = 0;
+       wd->ovls[ind].o.Offset = io_u->offset & 0xFFFFFFFF;
+       wd->ovls[ind].o.OffsetHigh = io_u->offset >> 32;
+       wd->ovls[ind].o.hEvent = wd->io_handles[ind];
+       wd->ovls[ind].io_u = io_u;
 
+       io_u->engine_data = &wd->ovls[ind];
        io_u->seen = 0;
 
-       fov->o.Offset = io_u->offset & 0xFFFFFFFF;
-       fov->o.OffsetHigh = io_u->offset >> 32;
-       fov->o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-       fov->io_u = io_u;
-
-       if (fov->o.hEvent == NULL) {
-               PrintError(__func__);
-               return 1;
-       }
-
-       if (io_u->ddir == DDIR_WRITE)
-               bSuccess = WriteFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &ioBytes, &fov->o);
-       else if (io_u->ddir == DDIR_READ)
-               bSuccess = ReadFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &ioBytes, &fov->o);
-       else if (io_u->ddir == DDIR_SYNC     ||
+       if (io_u->ddir == DDIR_WRITE) {
+               success = WriteFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, &wd->ovls[ind].o);
+       } else if (io_u->ddir == DDIR_READ) {
+               success = ReadFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, &wd->ovls[ind].o);
+       } else if (io_u->ddir == DDIR_SYNC     ||
                         io_u->ddir == DDIR_DATASYNC ||
                         io_u->ddir == DDIR_SYNC_FILE_RANGE)
        {
@@ -191,15 +206,16 @@ static int fio_windowsaio_queue(struct thread_data *td,
        } else if (io_u->ddir == DDIR_TRIM) {
                log_info("explicit TRIM isn't supported on Windows");
                return FIO_Q_COMPLETED;
-       }
+       } else
+               assert(0);
 
-       if (bSuccess) {
+       if (success) {
                io_u->seen = 1;
-               io_u->resid = io_u->xfer_buflen - fov->o.InternalHigh;
+               io_u->resid = io_u->xfer_buflen - iobytes;
                io_u->error = 0;
                rc = FIO_Q_COMPLETED;
-       } else if (!bSuccess && GetLastError() == ERROR_IO_PENDING) {
-               wd->busyIoHandles[wd->busyIo++] = fov->o.hEvent;
+       } else if (!success && GetLastError() == ERROR_IO_PENDING) {
+               wd->io_index = (wd->io_index + 1) % (2 * td->o.iodepth);
                rc = FIO_Q_QUEUED;
        } else {
                PrintError(__func__);
@@ -213,114 +229,134 @@ static int fio_windowsaio_queue(struct thread_data *td,
 
 static void fio_windowsaio_cleanup(struct thread_data *td)
 {
+       int i;
        struct windowsaio_data *wd;
 
        wd = td->io_ops->data;
-       wd->running = FALSE;
 
-       while (wd->stopped == FALSE)
-               Sleep(20);
+       WaitForSingleObject(wd->iothread_stopped, INFINITE);
 
        if (wd != NULL) {
-               CloseHandle(wd->hThread);
+               CloseHandle(wd->iothread);
+               CloseHandle(wd->iothread_stopped);
+               CloseHandle(wd->iocomplete_event);
+
+               for (i = 0; i < 2 * td->o.iodepth; i++) {
+                       CloseHandle(wd->io_handles[i]);
+               }
 
                free(wd->aio_events);
-               free(wd->busyIoHandles);
+               free(wd->io_handles);
+               free(wd->ovls);
                free(wd);
 
                td->io_ops->data = NULL;
        }
-
 }
 
+/* Runs as a thread and waits for queued IO to complete */
 static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter)
 {
        OVERLAPPED *ovl;
        FIO_OVERLAPPED *fov;
        struct io_u *io_u;
        struct windowsaio_data *wd;
-
        struct thread_ctx *ctx;
        ULONG_PTR ulKey = 0;
-       BOOL bSuccess;
        DWORD bytes;
 
-
        ctx = (struct thread_ctx*)lpParameter;
        wd = ctx->wd;
-       bSuccess = TRUE;
-
-       while (ctx->wd->running) {
-               bSuccess = GetQueuedCompletionStatus(ctx->ioCP, &bytes, &ulKey, &ovl, 100);
 
-               if (!bSuccess) {
-                       if (GetLastError() == WAIT_TIMEOUT) {
-                               continue;
-                       } else {
-                               PrintError(__func__);
-                               continue;
-                       }
-               }
+       while (ctx->wd->iothread_running) {
+               if (!GetQueuedCompletionStatus(ctx->iocp, &bytes, &ulKey, &ovl, 250))
+                       continue;
 
                fov = CONTAINING_RECORD(ovl, FIO_OVERLAPPED, o);
                io_u = fov->io_u;
 
-               if (io_u->seen == 1)
+               if (io_u->seen != 0)
                        continue;
 
-               ctx->wd->ioFinished++;
-
                if (ovl->Internal == ERROR_SUCCESS) {
                        io_u->resid = io_u->xfer_buflen - ovl->InternalHigh;
                        io_u->error = 0;
                } else {
                        io_u->resid = io_u->xfer_buflen;
-                       io_u->error = 1;
+                       io_u->error = ovl->Internal;
                }
 
                io_u->seen = 1;
-               CloseHandle(ovl->hEvent);
-               free(ovl);
+               SetEvent(wd->iocomplete_event);
        }
 
-       bSuccess = CloseHandle(ctx->ioCP);
-       if (!bSuccess)
-               PrintError(__func__);
-
-       ctx->wd->stopped = TRUE;
+       CloseHandle(ctx->iocp);
+       SetEvent(ctx->wd->iothread_stopped);
        free(ctx);
+
        return 0;
 }
 
 static int fio_windowsaio_init(struct thread_data *td)
 {
        struct windowsaio_data *wd;
+       OSVERSIONINFO osInfo;
+       int rc = 0;
 
        wd = malloc(sizeof(struct windowsaio_data));
-       if (wd == NULL)
-               return 1;
+       if (wd != NULL)
+               ZeroMemory(wd, sizeof(struct windowsaio_data));
+       else
+               rc = 1;
 
-       wd->aio_events = malloc((td->o.iodepth + 1) * sizeof(struct io_u *));
-       if (wd->aio_events == NULL) {
-               free(wd);
-               return 1;
+       if (!rc) {
+               wd->aio_events = malloc(td->o.iodepth * sizeof(struct io_u*));
+               if (wd->aio_events == NULL)
+                       rc = 1;
        }
 
-       wd->busyIoHandles = malloc((td->o.iodepth + 1) * sizeof(struct io_u *));
-       if (wd->busyIoHandles == NULL) {
-               free(wd->aio_events);
-               free(wd);
-               return 1;
+       if (!rc) {
+               wd->io_handles = malloc(2 * td->o.iodepth * sizeof(HANDLE));
+               if (wd->io_handles == NULL)
+                       rc = 1;
        }
 
-       ZeroMemory(wd->aio_events, (td->o.iodepth + 1) * sizeof(struct io_u *));
-       ZeroMemory(wd->busyIoHandles, (td->o.iodepth + 1) * sizeof(struct io_u *));
+       if (!rc) {
+               wd->ovls = malloc(2 * td->o.iodepth * sizeof(FIO_OVERLAPPED));
+               if (wd->ovls == NULL)
+                       rc = 1;
+       }
 
-       wd->busyIo = 0;
-       wd->ioFinished = 0;
-       wd->running = FALSE;
-       wd->stopped = FALSE;
-       wd->hThread = FALSE;
+       if (!rc) {
+               /* Create an auto-reset event */
+               wd->iocomplete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+               if (wd->iocomplete_event == NULL)
+                       rc = 1;
+       }
+
+       if (!rc) {
+               osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+               GetVersionEx(&osInfo);
+
+               if (osInfo.dwMajorVersion >= 6)
+                       wd->have_cancelioex = TRUE;
+               else
+                       wd->have_cancelioex = FALSE;
+       }
+
+       if (rc) {
+               PrintError(__func__);
+               if (wd != NULL) {
+                       if (wd->ovls != NULL)
+                               free(wd->ovls);
+                       if (wd->io_handles != NULL)
+                               free(wd->io_handles);
+                       if (wd->aio_events != NULL)
+                               free(wd->aio_events);
+
+                       free(wd);
+               }
+       }
 
        td->io_ops->data = wd;
        return 0;
@@ -334,6 +370,7 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f)
        DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE;
        DWORD openmode = OPEN_ALWAYS;
        DWORD access;
+       int i;
 
        dprint(FD_FILE, "fd open %s\n", f->file_name);
 
@@ -378,7 +415,6 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f)
                NULL, openmode, flags, NULL);
 
        if (f->hFile == INVALID_HANDLE_VALUE) {
-               log_err("Failed to open %s\n", f->file_name);
                PrintError(__func__);
                rc = 1;
        }
@@ -391,16 +427,36 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f)
                hFile = CreateIoCompletionPort(f->hFile, NULL, 0, 0);
 
                wd = td->io_ops->data;
-               wd->running = TRUE;
-               wd->stopped = FALSE;
 
-               ctx = malloc(sizeof(struct thread_ctx));
-               ctx->ioCP = hFile;
-               ctx->wd = wd;
+               wd->io_index = 0;
+               wd->iothread_running = TRUE;
+               /* Create a manual-reset event */
+               wd->iothread_stopped = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+               if (wd->iothread_stopped == NULL)
+                       rc = 1;
+
+               if (!rc) {
+                       for (i = 0; i < 2 * td->o.iodepth; i++) {
+                               /* Create a manual-reset event for putting in OVERLAPPED */
+                               wd->io_handles[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
+                               if (wd->io_handles[i] == NULL) {
+                                       PrintError(__func__);
+                                       rc = 1;
+                                       break;
+                               }
+                       }
+               }
 
-               wd->hThread = CreateThread(NULL, 0, IoCompletionRoutine, ctx, 0, NULL);
+               if (!rc) {
+                       ctx = malloc(sizeof(struct thread_ctx));
+                       ctx->iocp = hFile;
+                       ctx->wd = wd;
+
+                       wd->iothread = CreateThread(NULL, 0, IoCompletionRoutine, ctx, 0, NULL);
+               }
 
-               if (wd->hThread == NULL) {
+               if (rc || wd->iothread == NULL) {
                        PrintError(__func__);
                        rc = 1;
                }
@@ -411,11 +467,18 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f)
 
 static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct fio_file *f)
 {
-       BOOL bSuccess;
+       struct windowsaio_data *wd;
+
+       dprint(FD_FILE, "fd close %s\n", f->file_name);
+
+       if (td->io_ops->data != NULL) {
+               wd = td->io_ops->data;
+               wd->iothread_running = FALSE;
+               WaitForSingleObject(wd->iothread_stopped, INFINITE);
+       }
 
        if (f->hFile != INVALID_HANDLE_VALUE) {
-               bSuccess = CloseHandle(f->hFile);
-               if (!bSuccess)
+               if (!CloseHandle(f->hFile))
                        PrintError(__func__);
        }
 
index 9d42deb..d050506 100644 (file)
@@ -78,7 +78,7 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                }
        }
 #endif
-       
+
        if (!new_layout)
                goto done;
 
@@ -233,7 +233,7 @@ static int file_size(struct thread_data *td, struct fio_file *f)
 
 static int bdev_size(struct thread_data *td, struct fio_file *f)
 {
-       unsigned long long bytes;
+       unsigned long long bytes = 0;
        int r;
 
        if (td->io_ops->open_file(td, f)) {
@@ -265,7 +265,7 @@ err:
 static int char_size(struct thread_data *td, struct fio_file *f)
 {
 #ifdef FIO_HAVE_CHARDEV_SIZE
-       unsigned long long bytes;
+       unsigned long long bytes = 0;
        int r;
 
        if (td->io_ops->open_file(td, f)) {
diff --git a/fio.c b/fio.c
index 93482f5..a85f577 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <limits.h>
 #include <signal.h>
 #include <time.h>
 #include <locale.h>
@@ -988,7 +989,7 @@ void reset_all_stats(struct thread_data *td)
                td->io_issues[i] = 0;
                td->ts.total_io_u[i] = 0;
        }
-       
+
        fio_gettime(&tv, NULL);
        td->ts.runtime[0] = 0;
        td->ts.runtime[1] = 0;
diff --git a/mutex.c b/mutex.c
index c1ce2a3..e33e7cc 100644 (file)
--- a/mutex.c
+++ b/mutex.c
@@ -34,11 +34,7 @@ struct fio_mutex *fio_mutex_init(int value)
        }
 
 #ifdef FIO_HAVE_FALLOCATE
-       ret = posix_fallocate(fd, 0, sizeof(struct fio_mutex));
-       if (ret > 0) {
-               fprintf(stderr, "posix_fallocate mutex failed: %s\n", strerror(ret));
-               goto err;
-       }
+       posix_fallocate(fd, 0, sizeof(struct fio_mutex));
 #endif
 
        if (ftruncate(fd, sizeof(struct fio_mutex)) < 0) {
index 8e4a71d..91c8bcd 100644 (file)
@@ -25,7 +25,7 @@
 #define OS_MAP_ANON            MAP_ANON
 #define OS_MSG_DONTWAIT                0
 
-static inline int blockdev_invalidate_cache(struct fio_file fio_unused *f)
+static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
        return EINVAL;
 }
index 1f114f8..7a79dd0 100644 (file)
@@ -9,7 +9,6 @@
 
 #define FIO_HAVE_POSIXAIO
 #define FIO_HAVE_ODIRECT
-#define FIO_HAVE_IOPRIO
 #define FIO_HAVE_STRSEP
 #define FIO_USE_GENERIC_RAND
 #define FIO_HAVE_CHARDEV_SIZE
@@ -34,7 +33,7 @@ static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)
 
 static inline int chardev_size(struct fio_file *f, unsigned long long *bytes)
 {
-       return blockdev_size(f->fd, bytes);
+       return blockdev_size(f, bytes);
 }
 
 static inline int blockdev_invalidate_cache(struct fio_file *f)
index 068bc5c..1a0a887 100644 (file)
@@ -3,6 +3,9 @@
 
 #include <errno.h>
 #include <sys/sysctl.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <signal.h>
 
 #include "../file.h"
 
 
 #define OS_MAP_ANON            MAP_ANON
 
-typedef unsigned int clockid_t;
 typedef off_t off64_t;
 
-static inline int blockdev_invalidate_cache(struct fio_file fio_unused *f)
+/* OS X as of 10.6 doesn't have the timer_* functions. 
+ * Emulate the functionality using setitimer and sigaction here
+ */
+
+#define MAX_TIMERS 64
+
+typedef unsigned int clockid_t;
+typedef unsigned int timer_t;
+
+struct itimerspec {
+       struct timespec it_value;
+       struct timespec it_interval;
+};
+
+static struct sigevent fio_timers[MAX_TIMERS];
+static unsigned int num_timers = 0;
+
+static inline int timer_create(clockid_t clockid, struct sigevent *restrict evp,
+                                timer_t *restrict timerid)
+{
+       int current_timer = num_timers;
+       fio_timers[current_timer] = *evp;
+       num_timers++;
+       
+       *timerid = current_timer;
+       return 0;
+}
+
+static void sig_alrm(int signum)
+{
+       union sigval sv;
+       
+       for (int i = 0; i < num_timers; i++) {
+               if (fio_timers[i].sigev_notify_function == NULL)
+                       continue;
+               
+               if (fio_timers[i].sigev_notify == SIGEV_THREAD)
+                       fio_timers[i].sigev_notify_function(sv);
+               else if (fio_timers[i].sigev_notify == SIGEV_SIGNAL)
+                       kill(getpid(), fio_timers[i].sigev_signo);
+       }
+}
+
+static inline int timer_settime(timer_t timerid, int flags,
+                                                               const struct itimerspec *value, struct itimerspec *ovalue)
+{
+       struct sigaction sa;
+       struct itimerval tv;
+       struct itimerval tv_out;
+       int rc;
+       
+       tv.it_interval.tv_sec = value->it_interval.tv_sec;
+       tv.it_interval.tv_usec = value->it_interval.tv_nsec / 1000;
+
+       tv.it_value.tv_sec = value->it_value.tv_sec;
+       tv.it_value.tv_usec = value->it_value.tv_nsec / 1000;
+
+       sa.sa_handler = sig_alrm;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = 0;
+       
+       rc = sigaction(SIGALRM, &sa, NULL);
+
+       if (!rc)
+               rc = setitimer(ITIMER_REAL, &tv, &tv_out);
+       
+       if (!rc && ovalue != NULL) {
+               ovalue->it_interval.tv_sec = tv_out.it_interval.tv_sec;
+               ovalue->it_interval.tv_nsec = tv_out.it_interval.tv_usec * 1000;
+               ovalue->it_value.tv_sec = tv_out.it_value.tv_sec;
+               ovalue->it_value.tv_nsec = tv_out.it_value.tv_usec * 1000;
+       }
+
+       return rc;
+}
+
+static inline int timer_delete(timer_t timer)
+{
+       return 0;
+}
+
+static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
        return EINVAL;
 }
index 6478f30..8f61ec5 100644 (file)
@@ -17,7 +17,6 @@
 #define FIO_HAVE_ODIRECT
 #define FIO_HAVE_STRSEP
 #define FIO_HAVE_FDATASYNC
-#define FIO_HAVE_CLOCK_MONOTONIC
 #define FIO_USE_GENERIC_BDEV_SIZE
 #define FIO_USE_GENERIC_RAND
 
 
 #define OS_MAP_ANON            MAP_ANON
 
+#ifndef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 4096
+#endif
+
 typedef off_t off64_t;
 
-static inline int blockdev_invalidate_cache(struct fio_file fio_unused *f)
+static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
        return EINVAL;
 }
index e292172..3e82543 100644 (file)
@@ -17,7 +17,6 @@
 #define FIO_HAVE_PSHARED_MUTEX
 #define FIO_USE_GENERIC_BDEV_SIZE
 #define FIO_HAVE_FDATASYNC
-#define FIO_HAVE_CLOCK_MONOTONIC
 
 #define OS_MAP_ANON            MAP_ANON
 #define OS_RAND_MAX            2147483648UL
@@ -29,7 +28,7 @@ struct solaris_rand_seed {
 typedef psetid_t os_cpu_mask_t;
 typedef struct solaris_rand_seed os_random_state_t;
 
-static inline int blockdev_invalidate_cache(struct fio_file fio_unused *f)
+static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
        return EINVAL;
 }
index f7712a1..9edacf3 100644 (file)
@@ -36,8 +36,8 @@ static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)
        HANDLE hFile;\r
 \r
        if (f->hFile == NULL) {\r
-               hFile = CreateFile(f->file_name, (GENERIC_READ | GENERIC_WRITE),\r
-                       (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, 0, NULL);\r
+               hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                               NULL, OPEN_EXISTING, 0, NULL);\r
        } else {\r
                hFile = f->hFile;\r
        }\r
index 42008eb..fdf7d22 100644 (file)
--- a/smalloc.c
+++ b/smalloc.c
@@ -203,15 +203,7 @@ static int add_pool(struct pool *pool, unsigned int alloc_size)
        pool->free_blocks = bitmap_blocks * SMALLOC_BPB;
 
 #ifdef FIO_HAVE_FALLOCATE
-       {
-               int ret;
-
-               ret = posix_fallocate(fd, 0, alloc_size);
-               if (ret > 0) {
-                       fprintf(stderr, "posix_fallocate pool file failed: %s\n", strerror(ret));
-                       goto out_unlink;
-               }
-       }
+       posix_fallocate(fd, 0, alloc_size);
 #endif
 
        if (ftruncate(fd, alloc_size) < 0)