Make lockmem a per job option
[fio.git] / backend.c
index 7149c115e06163537c3417b4c398d05d1941cdb1..ad9231330547dc39278dd40d1ed94c37d0e2455e 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -56,13 +56,13 @@ static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 static int exit_value;
 static volatile int fio_abort;
+static unsigned int nr_process = 0;
+static unsigned int nr_thread = 0;
 
 struct io_log *agg_io_log[2];
 
 int groupid = 0;
 unsigned int thread_number = 0;
-unsigned int nr_process = 0;
-unsigned int nr_thread = 0;
 int shm_id = 0;
 int temp_stall_ts;
 unsigned long done_secs = 0;
@@ -335,8 +335,8 @@ static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
                        return 1;
 
                if (td_non_fatal_error(err)) {
-                       /*
-                        * Continue with the I/Os in case of
+                       /*
+                        * Continue with the I/Os in case of
                         * a non fatal error.
                         */
                        update_error_count(td, err);
@@ -494,7 +494,10 @@ sync_done:
                if (full || !td->o.iodepth_batch_complete) {
                        min_events = min(td->o.iodepth_batch_complete,
                                         td->cur_depth);
-                       if (full && !min_events && td->o.iodepth_batch_complete != 0)
+                       /*
+                        * if the queue is full, we MUST reap at least 1 event
+                        */
+                       if (full && !min_events)
                                min_events = 1;
 
                        do {
@@ -555,7 +558,8 @@ static void do_io(struct thread_data *td)
                td_set_runstate(td, TD_RUNNING);
 
        while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
-               (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td)) {
+               (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td) ||
+               td->o.time_based) {
                struct timeval comp_time;
                unsigned long bytes_done[2] = { 0, 0 };
                int min_evts = 0;
@@ -676,7 +680,10 @@ sync_done:
                if (full || !td->o.iodepth_batch_complete) {
                        min_evts = min(td->o.iodepth_batch_complete,
                                        td->cur_depth);
-                       if (full && !min_evts && td->o.iodepth_batch_complete != 0)
+                       /*
+                        * if the queue is full, we MUST reap at least 1 event
+                        */
+                       if (full && !min_evts)
                                min_evts = 1;
 
                        if (__should_check_rate(td, 0) ||
@@ -962,6 +969,9 @@ static void *thread_main(void *data)
 
        dprint(FD_PROCESS, "jobs pid=%d started\n", (int) td->pid);
 
+       if (is_backend)
+               fio_server_send_start(td);
+
        INIT_FLIST_HEAD(&td->io_u_freelist);
        INIT_FLIST_HEAD(&td->io_u_busylist);
        INIT_FLIST_HEAD(&td->io_u_requeues);
@@ -988,6 +998,7 @@ static void *thread_main(void *data)
         * eating a file descriptor
         */
        fio_mutex_remove(td->mutex);
+       td->mutex = NULL;
 
        /*
         * A new gid requires privilege, so we need to do this before setting
@@ -1018,6 +1029,9 @@ static void *thread_main(void *data)
                goto err;
        }
 
+       if (fio_pin_memory(td))
+               goto err;
+
        /*
         * May alter parameters that init_io_u() will use, so we need to
         * do this first.
@@ -1069,6 +1083,8 @@ static void *thread_main(void *data)
                        goto err;
        }
 
+       fio_verify_init(td);
+
        fio_gettime(&td->epoch, NULL);
        getrusage(RUSAGE_SELF, &td->ru_start);
 
@@ -1080,9 +1096,9 @@ static void *thread_main(void *data)
                memcpy(&td->tv_cache, &td->start, sizeof(td->start));
 
                if (td->o.ratemin[0] || td->o.ratemin[1]) {
-                       memcpy(&td->lastrate[0], &td->bw_sample_time,
+                       memcpy(&td->lastrate[0], &td->bw_sample_time,
                                                sizeof(td->bw_sample_time));
-                       memcpy(&td->lastrate[1], &td->bw_sample_time,
+                       memcpy(&td->lastrate[1], &td->bw_sample_time,
                                                sizeof(td->bw_sample_time));
                }
 
@@ -1131,6 +1147,8 @@ static void *thread_main(void *data)
        td->ts.io_bytes[0] = td->io_bytes[0];
        td->ts.io_bytes[1] = td->io_bytes[1];
 
+       fio_unpin_memory(td);
+
        fio_mutex_down(writeout_mutex);
        if (td->bw_log) {
                if (td->o.bw_log_file) {
@@ -1341,14 +1359,19 @@ static void run_threads(void)
        unsigned long spent;
        unsigned int i, todo, nr_running, m_rate, t_rate, nr_started;
 
-       if (fio_pin_memory())
-               return;
-
        if (fio_gtod_offload && fio_start_gtod_thread())
                return;
 
        set_sig_handlers();
 
+       nr_thread = nr_process = 0;
+       for_each_td(td, i) {
+               if (td->o.use_thread)
+                       nr_thread++;
+               else
+                       nr_process++;
+       }
+
        if (!terse_output) {
                log_info("Starting ");
                if (nr_thread)
@@ -1548,25 +1571,16 @@ static void run_threads(void)
 
                reap_threads(&nr_running, &t_rate, &m_rate);
 
-               if (todo) {
-                       if (is_backend)
-                               fio_server_idle_loop();
-                       else
-                               usleep(100000);
-               }
+               if (todo)
+                       usleep(100000);
        }
 
        while (nr_running) {
                reap_threads(&nr_running, &t_rate, &m_rate);
-
-               if (is_backend)
-                       fio_server_idle_loop();
-               else
-                       usleep(10000);
+               usleep(10000);
        }
 
        update_io_ticks();
-       fio_unpin_memory();
 }
 
 static void *disk_thread_main(void *data)