Token-based flow control

This patch allows two fio jobs to be kept to a certain
proportion of each other using token-based flow control.
There are three new parameters: flow, flow_watermark, and
flow_sleep, documented in the fio options. An example of an fio
job using these parameters is below:

[global]
norandommap
thread
time_based
runtime=30
direct=1
ioengine=libaio
iodepth=256
size=100g
bs=8k
filename=/tmp/testfile
flow_watermark=100
flow_sleep=1000

[job2]
numjobs=1
rw=write
flow=-8

[job1]
numjobs=1
rw=randread
flow=1

The motivating application of this patch was to allow random reads
and sequential writes at a particular given proportion.

This initial version is only correct when run with 'thread', as shared
state is represented with a global variable. It also only allows two
jobs to be synchronized properly. A future version might do more, but
no more functionality was needed for my application.

Tested: Ran a few fio jobs with this flow control, observing
the proportion of IOPS to match what was intended by the job file.
Varied the flow_watermark and flow_sleep parameters and observed
the effect on throughput.

Signed-off-by: Dan Ehrenberg <dehrenberg@google.com>

Modified by me to support flow_id, so an arbitrary number of flows can
be used. This means it no longer relies on global context, so it can be
used from a thread or process alike. Also added man page documentation.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/init.c b/init.c
index 8dc5784..d7d8011 100644
--- a/init.c
+++ b/init.c
@@ -221,6 +221,7 @@
 
 		threads = NULL;
 		file_hash_exit();
+		flow_exit();
 		fio_debug_jobp = NULL;
 		shmdt(tp);
 		shmctl(shm_id, IPC_RMID, &sbuf);
@@ -277,6 +278,9 @@
 	fio_debug_jobp = (void *) hash + file_hash_size;
 	*fio_debug_jobp = -1;
 	file_hash_init(hash);
+
+	flow_init();
+
 	return 0;
 }
 
@@ -324,6 +328,7 @@
 		return;
 
 	profile_td_exit(td);
+	flow_exit_job(td);
 
 	if (td->error)
 		log_info("fio: %s\n", td->verror);
@@ -796,6 +801,8 @@
 	if (fixup_options(td))
 		goto err;
 
+	flow_init_job(td);
+
 	/*
 	 * IO engines only need this for option callbacks, and the address may
 	 * change in subprocesses.