[PATCH] Add support for specifying job nice value with nice=x
diff --git a/README b/README
index 3d59337..b4e007c 100644
--- a/README
+++ b/README
@@ -102,6 +102,7 @@
 	lockmem=x	Lock down x amount of memory on the machine, to
 			simulate a machine with less memory available. x can
 			include k/m/g suffix.
+	nice=x		Run job at given nice value.
 
 Examples using a job file
 -------------------------
diff --git a/fio-ini.c b/fio-ini.c
index 0fec342..38d60a2 100644
--- a/fio-ini.c
+++ b/fio-ini.c
@@ -38,6 +38,7 @@
 #define DEF_ZONE_SKIP		(0)
 #define DEF_RWMIX_CYCLE		(500)
 #define DEF_RWMIX_READ		(50)
+#define DEF_NICE		(0)
 
 static char fio_version_string[] = "fio 1.3";
 
@@ -802,6 +803,10 @@
 				fgetpos(f, &off);
 				continue;
 			}
+			if (!check_int(p, "nice", &td->nice)) {
+				fgetpos(f, &off);
+				continue;
+			}
 			if (!check_range(p, "bsrange", &ul1, &ul2)) {
 				if (ul1 > ul2) {
 					td->max_bs = ul1;
@@ -937,6 +942,7 @@
 	def_thread.use_thread = DEF_USE_THREAD;
 	def_thread.rwmixcycle = DEF_RWMIX_CYCLE;
 	def_thread.rwmixread = DEF_RWMIX_READ;
+	def_thread.nice = DEF_NICE;
 #ifdef FIO_HAVE_DISK_UTIL
 	def_thread.do_disk_util = 1;
 #endif
diff --git a/fio.c b/fio.c
index c5e4f3c..571971d 100644
--- a/fio.c
+++ b/fio.c
@@ -1786,7 +1786,6 @@
 static void *thread_main(void *data)
 {
 	struct thread_data *td = data;
-	int ret = 1;
 
 	if (!td->use_thread)
 		setsid();
@@ -1819,6 +1818,11 @@
 		}
 	}
 
+	if (nice(td->nice) < 0) {
+		td_verror(td, errno);
+		goto err;
+	}
+
 	if (init_random_state(td))
 		goto err;
 
@@ -1867,8 +1871,6 @@
 			break;
 	}
 
-	ret = 0;
-
 	if (td->bw_log)
 		finish_log(td, td->bw_log, "bw");
 	if (td->slat_log)
@@ -1888,10 +1890,6 @@
 		munmap(td->mmap, td->file_size);
 	cleanup_io(td);
 	cleanup_io_u(td);
-	if (ret) {
-		sem_post(&startup_sem);
-		sem_wait(&td->mutex);
-	}
 	td_set_runstate(td, TD_EXITED);
 	return NULL;
 
@@ -2386,11 +2384,14 @@
 				td = map[i];
 				if (!td)
 					continue;
-				if (td->runstate == TD_INITIALIZED ||
-				    td->runstate >= TD_EXITED) {
+				if (td->runstate == TD_INITIALIZED) {
 					map[i] = NULL;
 					left--;
-					continue;
+				} else if (td->runstate >= TD_EXITED) {
+					map[i] = NULL;
+					left--;
+					todo--;
+					nr_running++; /* work-around... */
 				}
 			}
 		}
@@ -2407,7 +2408,7 @@
 		}
 
 		/*
-		 * start created threads (TD_INITIALIZED -> TD_RUNNING)
+		 * start created threads (TD_INITIALIZED -> TD_RUNNING).
 		 */
 		printf("fio: Go for launch\n");
 		for (i = 0; i < thread_number; i++) {
diff --git a/fio.h b/fio.h
index dbf476e..a75d3b2 100644
--- a/fio.h
+++ b/fio.h
@@ -153,6 +153,7 @@
 	unsigned int iolog;
 	unsigned int rwmixcycle;
 	unsigned int rwmixread;
+	unsigned int nice;
 
 	char iolog_file[256];