[PATCH] Add thinktime_spin parameter

If you specify thinktime currently, fio will sleep for the duration.
Apps will typically do some data processing before sleeping, so add
a thinktime_spin parameter to control how much CPU to burn before
sleeping.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/HOWTO b/HOWTO
index f61b4c1..8e6e29b 100644
--- a/HOWTO
+++ b/HOWTO
@@ -343,7 +343,14 @@
 
 thinktime=int	Stall the job x microseconds after an io has completed before
 		issuing the next. May be used to simulate processing being
-		done by an application. See thinktime_blocks.
+		done by an application. See thinktime_blocks and
+		thinktime_spin.
+
+thinktime_spin=int
+		Only valid if thinktime is set - pretend to spend CPU time
+		doing something with the data received, before falling back
+		to sleeping for the rest of the period specified by
+		thinktime.
 
 thinktime_blocks
 		Only valid if thinktime is set - control how many blocks
diff --git a/fio.c b/fio.c
index 78dca9a..ff169f8 100644
--- a/fio.c
+++ b/fio.c
@@ -466,8 +466,16 @@
 			unsigned long long b;
 
 			b = td->io_blocks[0] + td->io_blocks[1];
-			if (!(b % td->thinktime_blocks))
-				usec_sleep(td, td->thinktime);
+			if (!(b % td->thinktime_blocks)) {
+				int left;
+
+				if (td->thinktime_spin)
+					__usec_sleep(td->thinktime_spin);
+
+				left = td->thinktime - td->thinktime_spin;
+				if (left)
+					usec_sleep(td, left);
+			}
 		}
 	}
 
diff --git a/fio.h b/fio.h
index 67cc065..934d897 100644
--- a/fio.h
+++ b/fio.h
@@ -274,6 +274,7 @@
 	unsigned int hugepage_size;
 	unsigned int rw_min_bs;
 	unsigned int thinktime;
+	unsigned int thinktime_spin;
 	unsigned int thinktime_blocks;
 	unsigned int fsync_blocks;
 	unsigned int start_delay;
diff --git a/init.c b/init.c
index 1dec2bb..9e7fb2c 100644
--- a/init.c
+++ b/init.c
@@ -331,6 +331,13 @@
 		.def	= "0",
 	},
 	{
+		.name	= "thinktime_spin",
+		.type	= FIO_OPT_INT,
+		.off1	= td_var_offset(thinktime_spin),
+		.help	= "Start thinktime by spinning this amount (usec)",
+		.def	= "0",
+	},
+	{
 		.name	= "thinktime_blocks",
 		.type	= FIO_OPT_INT,
 		.off1	= td_var_offset(thinktime_blocks),
@@ -631,6 +638,12 @@
 	 */
 	if (td->filetype == FIO_TYPE_CHAR && td->odirect)
 		td->odirect = 0;
+
+	/*
+	 * thinktime_spin must be less than thinktime
+	 */
+	if (td->thinktime_spin > td->thinktime)
+		td->thinktime_spin = td->thinktime;
 }
 
 /*