Recent changes (gfio)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit d7213923067aa49922962a469a691c3ec951064d:

  Merge branch 'master' into gfio (2013-03-21 06:45:27 -0600)

are available in the git repository at:

  git://git.kernel.dk/fio.git gfio

Bruce Cran (2):
      Fix rwlock error messages to specify the correct function names.
      Workaround pthreads-win32 pthread_rwlock_init limitation.

Jens Axboe (15):
      mutex: add magic checks
      Only attempt file unlock if we use locking
      posixaio: restart suspend list after we have used aio_suspend()
      Consider the maximum block size difference the minimum for loop exit
      configure: check for v2 of libnuma
      Fix build if just one of libverbs or librdma is installed
      Fix usr/sys/ctx/majf/minf for -USR1 usage
      configure: fixup build so that it's more resilient
      axmap: fix bug with max_bs/min_bs ratio being > 64
      t/axmap: add test for multi bit sets
      axmap: get rid of old debug ->fail_ok checking
      parse: fix misparse of bs=64k-128k
      Merge branch 'master' into gfio
      Fix merge error
      configure: check for zlib

Jianpeng Ma (1):
      mutex: fix the expression for checking the mutext magic

Shaohua Li (2):
      mutex: set pshared attributes on rw semaphore
      Fixup json bandwidth output

Steven Noonan (1):
      gitignore: ignore configure script outputs

 .gitignore         |   12 ++++--
 Makefile           |   16 ++++----
 backend.c          |   29 ++++++++++++++--
 configure          |   52 +++++++++++++++++++++++++---
 engines/posixaio.c |    5 ++-
 fio.h              |   10 +++++
 ioengines.c        |    4 ++-
 lib/axmap.c        |   32 ++++++++++++-----
 mutex.c            |   38 ++++++++++++++++++++-
 mutex.h            |    5 +++
 parse.c            |   20 ++++++++++-
 stat.c             |   12 +++++-
 t/axmap.c          |   96 ++++++++++++++++++++++++++++++++++++++++++++++-----
 13 files changed, 284 insertions(+), 47 deletions(-)

---

Diff of recent changes:

diff --git a/.gitignore b/.gitignore
index 2457d65..3993a30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,9 @@
-fio
-*.o
 *.d
-.depend
-cscope.out
+*.o
+/.depend
+/FIO-VERSION-FILE
+/config-host.h
+/config-host.mak
+/config.log
+/cscope.out
+/fio
diff --git a/Makefile b/Makefile
index 4aa05fa..21e6ad3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,3 @@
-DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-CPPFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(DEBUGFLAGS)
-OPTFLAGS= -O3 -g -ffast-math $(EXTFLAGS)
-CFLAGS	= -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS)
-LIBS	= -lm -lz $(EXTLIBS)
-PROGS	= fio
-SCRIPTS = fio_generate_plots
-
 ifneq ($(wildcard config-host.mak),)
 all:
 include config-host.mak
@@ -20,6 +12,14 @@ all:
 include config-host.mak
 endif
 
+DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
+CPPFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(DEBUGFLAGS)
+OPTFLAGS= -O3 -g -ffast-math
+CFLAGS	= -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS)
+LIBS	+= -lm $(EXTLIBS)
+PROGS	= fio
+SCRIPTS = fio_generate_plots
+
 ifdef CONFIG_GFIO
   PROGS += gfio
 endif
diff --git a/backend.c b/backend.c
index 600f5ce..022122a 100644
--- a/backend.c
+++ b/backend.c
@@ -406,6 +406,15 @@ static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
 	return 0;
 }
 
+static void check_update_rusage(struct thread_data *td)
+{
+	if (td->update_rusage) {
+		td->update_rusage = 0;
+		update_rusage_stat(td);
+		fio_mutex_up(td->rusage_sem);
+	}
+}
+
 /*
  * The main verify engine. Runs over the writes we previously submitted,
  * reads the blocks back in, and checks the crc/md5 of the data.
@@ -433,6 +442,8 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
 			break;
 	}
 
+	check_update_rusage(td);
+
 	if (td->error)
 		return;
 
@@ -444,6 +455,7 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
 		int ret2, full;
 
 		update_tv_cache(td);
+		check_update_rusage(td);
 
 		if (runtime_exceeded(td, &td->tv_cache)) {
 			__update_tv_cache(td);
@@ -597,6 +609,8 @@ sync_done:
 			break;
 	}
 
+	check_update_rusage(td);
+
 	if (!td->error) {
 		min_events = td->cur_depth;
 
@@ -652,6 +666,8 @@ static uint64_t do_io(struct thread_data *td)
 		int ret2, full;
 		enum fio_ddir ddir;
 
+		check_update_rusage(td);
+
 		if (td->terminate || td->done)
 			break;
 
@@ -816,6 +832,8 @@ sync_done:
 		}
 	}
 
+	check_update_rusage(td);
+
 	if (td->trim_entries)
 		log_err("fio: %d trim entries leaked?\n", td->trim_entries);
 
@@ -884,8 +902,7 @@ static int init_io_u(struct thread_data *td)
 	char *p;
 
 	max_units = td->o.iodepth;
-	max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
-	max_bs = max(td->o.max_bs[DDIR_TRIM], max_bs);
+	max_bs = td_max_bs(td);
 	min_write = td->o.min_bs[DDIR_WRITE];
 	td->orig_buffer_size = (unsigned long long) max_bs
 					* (unsigned long long) max_units;
@@ -1042,7 +1059,7 @@ static int keep_running(struct thread_data *td)
 		 * are done.
 		 */
 		diff = td->o.size - ddir_rw_sum(td->io_bytes);
-		if (diff < td->o.rw_min_bs)
+		if (diff < td_max_bs(td))
 			return 0;
 
 		return 1;
@@ -1392,6 +1409,9 @@ err:
 	if (td->o.write_iolog_file)
 		write_iolog_close(td);
 
+	fio_mutex_remove(td->rusage_sem);
+	td->rusage_sem = NULL;
+
 	td_set_runstate(td, TD_EXITED);
 	return (void *) (uintptr_t) td->error;
 }
@@ -1645,6 +1665,9 @@ static void run_threads(void)
 
 			init_disk_util(td);
 
+			td->rusage_sem = fio_mutex_init(FIO_MUTEX_LOCKED);
+			td->update_rusage = 0;
+
 			/*
 			 * Set state to created. Thread will transition
 			 * to TD_INITIALIZED when it's done setting up.
diff --git a/configure b/configure
index 222befe..4e2202f 100755
--- a/configure
+++ b/configure
@@ -38,8 +38,8 @@ fatal() {
 }
 
 # Default CFLAGS
-CFLAGS="-D_GNU_SOURCE"
-EXTFLAGS="-include config-host.h"
+CFLAGS="-D_GNU_SOURCE -include config-host.h"
+BUILD_CFLAGS=""
 
 # Print a helpful header at the top of config.log
 echo "# FIO configure log $(date)" >> config.log
@@ -236,7 +236,7 @@ CYGWIN*)
   output_sym "CONFIG_SCHED_IDLE"
   output_sym "CONFIG_TCP_NODELAY"
   echo "CC=$CC" >> $config_host_mak
-  echo "EXTFLAGS=$CFLAGS -include config-host.h -D_GNU_SOURCE" >> $config_host_mak
+  echo "BUILD_CFLAGS=$CFLAGS -include config-host.h -D_GNU_SOURCE" >> $config_host_mak
   exit 0
   ;;
 esac
@@ -396,6 +396,28 @@ fi
 echo "Wordsize                      $wordsize"
 
 ##########################################
+# zlib probe
+zlib="no"
+cat > $TMPC <<EOF
+#include <zlib.h>
+int main(void)
+{
+  z_stream stream;
+  if (inflateInit(&stream) != Z_OK)
+    return 1;
+  return 0;
+}
+EOF
+if compile_prog "" "-lz" "zlib" ; then
+  zlib=yes
+  LIBS="-lz $LIBS"
+else
+  feature_not_found "zlib"
+  zlib=no
+fi
+echo "zlib                          $zlib"
+
+##########################################
 # linux-aio probe
 libaio="no"
 cat > $TMPC <<EOF
@@ -816,6 +838,24 @@ fi
 echo "libnuma                       $libnuma"
 
 ##########################################
+# libnuma 2.x version API
+if test "$libnuma" = "yes" ; then
+libnuma_v2="no"
+cat > $TMPC << EOF
+#include <numa.h>
+int main(int argc, char **argv)
+{
+  struct bitmask *mask = numa_parse_nodestring(NULL);
+  return 0;
+}
+EOF
+if compile_prog "" "" "libnuma api"; then
+  libnuma_v2="yes"
+fi
+echo "libnuma v2                    $libnuma_v2"
+fi
+
+##########################################
 # strsep() probe
 strsep="no"
 cat > $TMPC << EOF
@@ -1047,7 +1087,7 @@ fi
 if test "$sfaa" = "yes" ; then
   output_sym "CONFIG_SFAA"
 fi
-if test "$libverbs" = "yes" -o "rdmacm" = "yes" ; then
+if test "$libverbs" = "yes" -a "rdmacm" = "yes" ; then
   output_sym "CONFIG_RDMA"
 fi
 if test "$clock_gettime" = "yes" ; then
@@ -1094,7 +1134,7 @@ fi
 if test "$fusion_aw" = "yes" ; then
   output_sym "CONFIG_FUSION_AW"
 fi
-if test "$libnuma" = "yes" ; then
+if test "$libnuma_v2" = "yes" ; then
   output_sym "CONFIG_LIBNUMA"
 fi
 if test "$solaris_aio" = "yes" ; then
@@ -1122,4 +1162,4 @@ fi
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "CFLAGS+=$CFLAGS" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
-echo "EXTFLAGS=$EXTFLAGS $CFLAGS" >> $config_host_mak
+echo "BUILD_CFLAGS=$BUILD_CFLAGS $CFLAGS" >> $config_host_mak
diff --git a/engines/posixaio.c b/engines/posixaio.c
index a943e5b..1858e52 100644
--- a/engines/posixaio.c
+++ b/engines/posixaio.c
@@ -98,7 +98,7 @@ static int fio_posixaio_getevents(struct thread_data *td, unsigned int min,
 	struct flist_head *entry;
 	struct timespec start;
 	int have_timeout = 0;
-	int suspend_entries = 0;
+	int suspend_entries;
 	unsigned int r;
 
 	if (t && !fill_timespec(&start))
@@ -107,8 +107,9 @@ static int fio_posixaio_getevents(struct thread_data *td, unsigned int min,
 		memset(&start, 0, sizeof(start));
 
 	r = 0;
-	memset(suspend_list, 0, sizeof(*suspend_list));
 restart:
+	memset(suspend_list, 0, sizeof(*suspend_list));
+	suspend_entries = 0;
 	flist_for_each(entry, &td->io_u_busylist) {
 		struct io_u *io_u = flist_entry(entry, struct io_u, list);
 		int err;
diff --git a/fio.h b/fio.h
index 05406cb..1cb44e6 100644
--- a/fio.h
+++ b/fio.h
@@ -113,6 +113,8 @@ struct thread_data {
 	uint64_t stat_io_blocks[DDIR_RWDIR_CNT];
 	struct timeval iops_sample_time;
 
+	volatile int update_rusage;
+	struct fio_mutex *rusage_sem;
 	struct rusage ru_start;
 	struct rusage ru_end;
 
@@ -568,6 +570,14 @@ static inline int should_check_rate(struct thread_data *td,
 	return ret;
 }
 
+static inline unsigned int td_max_bs(struct thread_data *td)
+{
+	unsigned int max_bs;
+
+	max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
+	return max(td->o.max_bs[DDIR_TRIM], max_bs);
+}
+
 static inline int is_power_of_2(unsigned int val)
 {
 	return (val != 0 && ((val & (val - 1)) == 0));
diff --git a/ioengines.c b/ioengines.c
index f4eae04..93e7631 100644
--- a/ioengines.c
+++ b/ioengines.c
@@ -475,7 +475,9 @@ int td_io_close_file(struct thread_data *td, struct fio_file *f)
 	fio_file_set_closing(f);
 
 	disk_util_dec(f->du);
-	unlock_file_all(td, f);
+
+	if (td->o.file_lock_mode != FILE_LOCK_NONE)
+		unlock_file_all(td, f);
 
 	return put_file(td, f);
 }
diff --git a/lib/axmap.c b/lib/axmap.c
index eeb32d4..c9f3a4f 100644
--- a/lib/axmap.c
+++ b/lib/axmap.c
@@ -189,7 +189,6 @@ void axmap_clear(struct axmap *axmap, uint64_t bit_nr)
 struct axmap_set_data {
 	unsigned int nr_bits;
 	unsigned int set_bits;
-	unsigned int fail_ok;
 };
 
 static unsigned long bit_masks[] = {
@@ -229,10 +228,8 @@ static int axmap_set_fn(struct axmap_level *al, unsigned long offset,
 	 * Mask off any potential overlap, only sets contig regions
 	 */
 	overlap = al->map[offset] & mask;
-	if (overlap == mask) {
-		assert(data->fail_ok);
+	if (overlap == mask)
 		return 1;
-	}
 
 	while (overlap) {
 		unsigned long clear_mask = ~(1UL << ffz(~overlap));
@@ -273,14 +270,14 @@ static void __axmap_set(struct axmap *axmap, uint64_t bit_nr,
 		axmap_handler(axmap, bit_nr, axmap_set_fn, data);
 		set_bits += data->set_bits;
 
-		if (data->set_bits != (BLOCKS_PER_UNIT - nr_bits))
+		if (!data->set_bits ||
+		    data->set_bits != (BLOCKS_PER_UNIT - nr_bits))
 			break;
 
 		nr_bits -= data->set_bits;
 		bit_nr += data->set_bits;
 
 		data->nr_bits = nr_bits;
-		data->fail_ok = 1;
 	}
 
 	data->set_bits = set_bits;
@@ -295,10 +292,27 @@ void axmap_set(struct axmap *axmap, uint64_t bit_nr)
 
 unsigned int axmap_set_nr(struct axmap *axmap, uint64_t bit_nr, unsigned int nr_bits)
 {
-	struct axmap_set_data data = { .nr_bits = nr_bits, };
+	unsigned int set_bits = 0;
 
-	__axmap_set(axmap, bit_nr, &data);
-	return data.set_bits;
+	do {
+		struct axmap_set_data data = { .nr_bits = nr_bits, };
+		unsigned int max_bits, this_set;
+
+		max_bits = BLOCKS_PER_UNIT - (bit_nr & BLOCKS_PER_UNIT_MASK);
+		if (max_bits < nr_bits)
+			data.nr_bits = max_bits;
+
+		this_set = data.nr_bits;
+		__axmap_set(axmap, bit_nr, &data);
+		set_bits += data.set_bits;
+		if (data.set_bits != this_set)
+			break;
+
+		nr_bits -= data.set_bits;
+		bit_nr += data.set_bits;
+	} while (nr_bits);
+
+	return set_bits;
 }
 
 static int axmap_isset_fn(struct axmap_level *al, unsigned long offset,
diff --git a/mutex.c b/mutex.c
index 332e9f9..e1fbb60 100644
--- a/mutex.c
+++ b/mutex.c
@@ -7,6 +7,7 @@
 #include <errno.h>
 #include <pthread.h>
 #include <sys/mman.h>
+#include <assert.h>
 
 #include "fio.h"
 #include "log.h"
@@ -19,6 +20,7 @@
 
 void fio_mutex_remove(struct fio_mutex *mutex)
 {
+	assert(mutex->magic == FIO_MUTEX_MAGIC);
 	pthread_cond_destroy(&mutex->cond);
 	munmap((void *) mutex, sizeof(*mutex));
 }
@@ -40,6 +42,7 @@ struct fio_mutex *fio_mutex_init(int value)
 	}
 
 	mutex->value = value;
+	mutex->magic = FIO_MUTEX_MAGIC;
 
 	ret = pthread_mutexattr_init(&attr);
 	if (ret) {
@@ -92,6 +95,8 @@ int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int seconds)
 	struct timespec t;
 	int ret = 0;
 
+	assert(mutex->magic == FIO_MUTEX_MAGIC);
+
 	gettimeofday(&tv_s, NULL);
 	t.tv_sec = tv_s.tv_sec + seconds;
 	t.tv_nsec = tv_s.tv_usec * 1000;
@@ -122,6 +127,8 @@ int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int seconds)
 
 void fio_mutex_down(struct fio_mutex *mutex)
 {
+	assert(mutex->magic == FIO_MUTEX_MAGIC);
+
 	pthread_mutex_lock(&mutex->lock);
 
 	while (!mutex->value) {
@@ -136,6 +143,8 @@ void fio_mutex_down(struct fio_mutex *mutex)
 
 void fio_mutex_up(struct fio_mutex *mutex)
 {
+	assert(mutex->magic == FIO_MUTEX_MAGIC);
+
 	pthread_mutex_lock(&mutex->lock);
 	read_barrier();
 	if (!mutex->value && mutex->waiters)
@@ -146,27 +155,32 @@ void fio_mutex_up(struct fio_mutex *mutex)
 
 void fio_rwlock_write(struct fio_rwlock *lock)
 {
+	assert(lock->magic == FIO_RWLOCK_MAGIC);
 	pthread_rwlock_wrlock(&lock->lock);
 }
 
 void fio_rwlock_read(struct fio_rwlock *lock)
 {
+	assert(lock->magic == FIO_RWLOCK_MAGIC);
 	pthread_rwlock_rdlock(&lock->lock);
 }
 
 void fio_rwlock_unlock(struct fio_rwlock *lock)
 {
+	assert(lock->magic == FIO_RWLOCK_MAGIC);
 	pthread_rwlock_unlock(&lock->lock);
 }
 
 void fio_rwlock_remove(struct fio_rwlock *lock)
 {
+	assert(lock->magic == FIO_RWLOCK_MAGIC);
 	munmap((void *) lock, sizeof(*lock));
 }
 
 struct fio_rwlock *fio_rwlock_init(void)
 {
 	struct fio_rwlock *lock;
+	pthread_rwlockattr_t attr;
 	int ret;
 
 	lock = (void *) mmap(NULL, sizeof(struct fio_rwlock),
@@ -178,13 +192,35 @@ struct fio_rwlock *fio_rwlock_init(void)
 		goto err;
 	}
 
+	lock->magic = FIO_RWLOCK_MAGIC;
+
+	ret = pthread_rwlockattr_init(&attr);
+	if (ret) {
+		log_err("pthread_rwlockattr_init: %s\n", strerror(ret));
+		goto err;
+	}
+#ifdef FIO_HAVE_PSHARED_MUTEX
+	ret = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+	if (ret) {
+		log_err("pthread_rwlockattr_setpshared: %s\n", strerror(ret));
+		goto destroy_attr;
+	}
+
+	ret = pthread_rwlock_init(&lock->lock, &attr);
+#else
 	ret = pthread_rwlock_init(&lock->lock, NULL);
+#endif
+
 	if (ret) {
 		log_err("pthread_rwlock_init: %s\n", strerror(ret));
-		goto err;
+		goto destroy_attr;
 	}
 
+	pthread_rwlockattr_destroy(&attr);
+
 	return lock;
+destroy_attr:
+	pthread_rwlockattr_destroy(&attr);
 err:
 	if (lock)
 		fio_rwlock_remove(lock);
diff --git a/mutex.h b/mutex.h
index 49a66e3..4f3486d 100644
--- a/mutex.h
+++ b/mutex.h
@@ -3,15 +3,20 @@
 
 #include <pthread.h>
 
+#define FIO_MUTEX_MAGIC		0x4d555445U
+#define FIO_RWLOCK_MAGIC	0x52574c4fU
+
 struct fio_mutex {
 	pthread_mutex_t lock;
 	pthread_cond_t cond;
 	int value;
 	int waiters;
+	int magic;
 };
 
 struct fio_rwlock {
 	pthread_rwlock_t lock;
+	int magic;
 };
 
 enum {
diff --git a/parse.c b/parse.c
index 9250133..a701a5b 100644
--- a/parse.c
+++ b/parse.c
@@ -139,6 +139,19 @@ static unsigned long get_mult_time(char c)
 	}
 }
 
+static int is_separator(char c)
+{
+	switch (c) {
+	case ':':
+	case '-':
+	case ',':
+	case '/':
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static unsigned long long __get_mult_bytes(const char *p, void *data,
 					   int *percent)
 {
@@ -152,8 +165,13 @@ static unsigned long long __get_mult_bytes(const char *p, void *data,
 
 	c = strdup(p);
 
-	for (i = 0; i < strlen(c); i++)
+	for (i = 0; i < strlen(c); i++) {
 		c[i] = tolower(c[i]);
+		if (is_separator(c[i])) {
+			c[i] = '\0';
+			break;
+		}
+	}
 
 	if (!strncmp("pib", c, 3)) {
 		pow = 5;
diff --git a/stat.c b/stat.c
index c3d3c4a..402a73f 100644
--- a/stat.c
+++ b/stat.c
@@ -734,7 +734,7 @@ static void add_ddir_status_json(struct thread_stat *ts,
 	if (ovals)
 		free(ovals);
 
-	if (!calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
+	if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
 		if (rs->agg[ddir]) {
 			p_of_agg = mean * 100 / (double) rs->agg[ddir];
 			if (p_of_agg > 100.0)
@@ -1350,13 +1350,21 @@ static void *__show_running_run_stats(void *arg)
 		if (td_trim(td) && td->io_bytes[DDIR_TRIM])
 			td->ts.runtime[DDIR_TRIM] += rt[i];
 
-		update_rusage_stat(td);
+		td->update_rusage = 1;
 		td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
 		td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
 		td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
 		td->ts.total_run_time = mtime_since(&td->epoch, &tv);
 	}
 
+	for_each_td(td, i) {
+		if (td->rusage_sem) {
+			td->update_rusage = 1;
+			fio_mutex_down(td->rusage_sem);
+		}
+		td->update_rusage = 0;
+	}
+
 	show_run_stats();
 
 	for_each_td(td, i) {
diff --git a/t/axmap.c b/t/axmap.c
index 7ab500f..57c585b 100644
--- a/t/axmap.c
+++ b/t/axmap.c
@@ -18,49 +18,125 @@ void sfree(void *ptr)
 	free(ptr);
 }
 
-int main(int argc, char *argv[])
+static int test_regular(size_t size, int seed)
 {
 	struct fio_lfsr lfsr;
-	size_t osize, size = (1UL << 28) - 200;
 	struct axmap *map;
+	size_t osize;
 	uint64_t ff;
-	int seed = 1;
+	int err;
 
-	if (argc > 1) {
-		size = strtoul(argv[1], NULL, 10);
-		if (argc > 2)
-			seed = strtoul(argv[2], NULL, 10);
-	}
-
-	printf("Using %llu entries\n", (unsigned long long) size);
+	printf("Using %llu entries...", (unsigned long long) size);
+	fflush(stdout);
 
 	lfsr_init(&lfsr, size, seed, seed & 0xF);
 	map = axmap_new(size);
 	osize = size;
+	err = 0;
 
 	while (size--) {
 		uint64_t val;
 
 		if (lfsr_next(&lfsr, &val, osize)) {
 			printf("lfsr: short loop\n");
+			err = 1;
 			break;
 		}
 		if (axmap_isset(map, val)) {
 			printf("bit already set\n");
+			err = 1;
 			break;
 		}
 		axmap_set(map, val);
 		if (!axmap_isset(map, val)) {
 			printf("bit not set\n");
+			err = 1;
 			break;
 		}
 	}
 
+	if (err)
+		return err;
+
 	ff = axmap_next_free(map, osize);
 	if (ff != (uint64_t) -1ULL) {
 		printf("axmap_next_free broken: got %llu\n", (unsigned long long) ff);
 		return 1;
 	}
 
+	printf("pass!\n");
+	axmap_free(map);
+	return 0;
+}
+
+static int test_multi(size_t size, unsigned int bit_off)
+{
+	unsigned int map_size = size;
+	struct axmap *map;
+	uint64_t val = bit_off;
+	int i, err;
+
+	printf("Test multi %llu entries %u offset...", (unsigned long long) size, bit_off);
+	fflush(stdout);
+
+	map = axmap_new(map_size);
+	while (val + 128 <= map_size) {
+		err = 0;
+		for (i = val; i < val + 128; i++) {
+			if (axmap_isset(map, val + i)) {
+				printf("bit already set\n");
+				err = 1;
+				break;
+			}
+		}
+
+		if (err)
+			break;
+
+		err = axmap_set_nr(map, val, 128);
+		if (err != 128) {
+			printf("only set %u bits\n", err);
+			break;
+		}
+
+		err = 0;
+		for (i = 0; i < 128; i++) {
+			if (!axmap_isset(map, val + i)) {
+				printf("bit not set: %llu\n", (unsigned long long) val + i);
+				err = 1;
+				break;
+			}
+		}
+
+		val += 128;
+		if (err)
+			break;
+	}
+
+	if (!err)
+		printf("pass!\n");
+
+	axmap_free(map);
+	return err;
+}
+
+int main(int argc, char *argv[])
+{
+	size_t size = (1UL << 23) - 200;
+	int seed = 1;
+
+	if (argc > 1) {
+		size = strtoul(argv[1], NULL, 10);
+		if (argc > 2)
+			seed = strtoul(argv[2], NULL, 10);
+	}
+
+	if (test_regular(size, seed))
+		return 1;
+	if (test_multi(size, 0))
+		return 2;
+	if (test_multi(size, 17))
+		return 3;
+
 	return 0;
 }
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux