int min_evts = 0;
int ret;
+ if (td->flags & TD_F_REGROW_LOGS) {
+ ret = io_u_quiesce(td);
+ regrow_logs(td);
+ return ret;
+ }
+
/*
* if the queue is full, we MUST reap at least 1 event
*/
break;
}
+ if (td->flags & TD_F_REGROW_LOGS)
+ regrow_logs(td);
+
/*
* when doing I/O (not when verifying),
* check for any errors that are to be ignored
if (td->error)
return;
+ /*
+ * verify_state needs to be reset before verification
+ * proceeds so that expected random seeds match actual
+ * random seeds in headers. The main loop will reset
+ * all random number generators if randrepeat is set.
+ */
+ if (!td->o.rand_repeatable)
+ td_fill_verify_state_seed(td);
+
td_set_runstate(td, TD_VERIFYING);
io_u = NULL;
struct thread_data *td = fd->td;
struct thread_options *o = &td->o;
struct sk_out *sk_out = fd->sk_out;
- pthread_condattr_t attr;
int clear_state;
int ret;
INIT_FLIST_HEAD(&td->verify_list);
INIT_FLIST_HEAD(&td->trim_list);
INIT_FLIST_HEAD(&td->next_rand_list);
- pthread_mutex_init(&td->io_u_lock, NULL);
td->io_hist_tree = RB_ROOT;
- pthread_condattr_init(&attr);
- pthread_cond_init(&td->verify_cond, &attr);
- pthread_cond_init(&td->free_cond, &attr);
+ ret = mutex_cond_init_pshared(&td->io_u_lock, &td->free_cond);
+ if (ret) {
+ td_verror(td, ret, "mutex_cond_init_pshared");
+ goto err;
+ }
+ ret = cond_init_pshared(&td->verify_cond);
+ if (ret) {
+ td_verror(td, ret, "mutex_cond_pshared");
+ goto err;
+ }
td_set_runstate(td, TD_INITIALIZED);
dprint(FD_MUTEX, "up startup_mutex\n");
goto err;
}
+ /*
+ * Do this early, we don't want the compress threads to be limited
+ * to the same CPUs as the IO workers. So do this before we set
+ * any potential CPU affinity
+ */
+ if (iolog_compress_init(td, sk_out))
+ goto err;
+
/*
* If we have a gettimeofday() thread, make sure we exclude that
* thread from this job
goto err;
}
- if (iolog_compress_init(td, sk_out))
- goto err;
-
fio_verify_init(td);
if (rate_submit_init(td, sk_out))
break;
}
+ td_set_runstate(td, TD_FINISHING);
+
update_rusage_stat(td);
td->ts.total_run_time = mtime_since_now(&td->epoch);
td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
return (void *) (uintptr_t) td->error;
}
-
-/*
- * We cannot pass the td data into a forked process, so attach the td and
- * pass it to the thread worker.
- */
-static int fork_main(struct sk_out *sk_out, int shmid, int offset)
-{
- struct fork_data *fd;
- void *data, *ret;
-
-#if !defined(__hpux) && !defined(CONFIG_NO_SHM)
- data = shmat(shmid, NULL, 0);
- if (data == (void *) -1) {
- int __err = errno;
-
- perror("shmat");
- return __err;
- }
-#else
- /*
- * HP-UX inherits shm mappings?
- */
- data = threads;
-#endif
-
- fd = calloc(1, sizeof(*fd));
- fd->td = data + offset * sizeof(struct thread_data);
- fd->sk_out = sk_out;
- ret = thread_main(fd);
- shmdt(data);
- return (int) (uintptr_t) ret;
-}
-
static void dump_td_info(struct thread_data *td)
{
- log_err("fio: job '%s' hasn't exited in %lu seconds, it appears to "
- "be stuck. Doing forceful exit of this job.\n", td->o.name,
+ log_err("fio: job '%s' (state=%d) hasn't exited in %lu seconds, it "
+ "appears to be stuck. Doing forceful exit of this job.\n",
+ td->o.name, td->runstate,
(unsigned long) time_since_now(&td->terminate_time));
}
struct thread_data *map[REAL_MAX_JOBS];
struct timeval this_start;
int this_jobs = 0, left;
+ struct fork_data *fd;
/*
* create threads (TD_NOT_CREATED -> TD_CREATED)
map[this_jobs++] = td;
nr_started++;
+ fd = calloc(1, sizeof(*fd));
+ fd->td = td;
+ fd->sk_out = sk_out;
+
if (td->o.use_thread) {
- struct fork_data *fd;
int ret;
- fd = calloc(1, sizeof(*fd));
- fd->td = td;
- fd->sk_out = sk_out;
-
dprint(FD_PROCESS, "will pthread_create\n");
ret = pthread_create(&td->thread, NULL,
thread_main, fd);
dprint(FD_PROCESS, "will fork\n");
pid = fork();
if (!pid) {
- int ret = fork_main(sk_out, shm_id, i);
+ int ret;
+ ret = (int)(uintptr_t)thread_main(fd);
_exit(ret);
} else if (i == fio_debug_jobno)
*fio_debug_jobp = pid;
for (i = 0; i < DDIR_RWDIR_CNT; i++) {
struct io_log *log = agg_io_log[i];
- flush_log(log, 0);
+ flush_log(log, false);
free_log(log);
}
}