Wrap thread_data in thread_segment
No functional changes in this patch, just in preparation for having
multiple shm segments for the thread_data structures. They are getting
very large, and since it's hard to know upfront how many we need, let's
instead refactor the code a bit to allow us to add chunks of them as
needed when parsing the job file (or command line).
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/backend.c b/backend.c
index f91f3ca..d2b97db 100644
--- a/backend.c
+++ b/backend.c
@@ -63,7 +63,6 @@
int groupid = 0;
unsigned int thread_number = 0;
unsigned int stat_number = 0;
-int shm_id = 0;
int temp_stall_ts;
unsigned long done_secs = 0;
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
@@ -76,7 +75,7 @@
static void sig_int(int sig)
{
- if (threads) {
+ if (segments[0].threads) {
if (is_backend)
fio_server_got_signal(sig);
else {
diff --git a/fio.h b/fio.h
index 9d189eb..691976a 100644
--- a/fio.h
+++ b/fio.h
@@ -467,6 +467,11 @@
};
+struct thread_segment {
+ struct thread_data *threads;
+ int shm_id;
+};
+
/*
* when should interactive ETA output be generated
*/
@@ -510,10 +515,13 @@
#define __fio_stringify_1(x) #x
#define __fio_stringify(x) __fio_stringify_1(x)
+#define REAL_MAX_JOBS 4096
+#define JOBS_PER_SEG 8
+#define REAL_MAX_SEG (REAL_MAX_JOBS / JOBS_PER_SEG)
+
extern bool exitall_on_terminate;
extern unsigned int thread_number;
extern unsigned int stat_number;
-extern int shm_id;
extern int groupid;
extern int output_format;
extern int append_terse_output;
@@ -542,7 +550,7 @@
extern long long trigger_timeout;
extern char *aux_path;
-extern struct thread_data *threads;
+extern struct thread_segment segments[REAL_MAX_SEG];
static inline bool is_running_backend(void)
{
@@ -557,8 +565,6 @@
!(io_u->ddir == DDIR_TRIM && !td_trim(td)));
}
-#define REAL_MAX_JOBS 4096
-
static inline bool should_fsync(struct thread_data *td)
{
if (td->last_was_sync)
@@ -709,7 +715,7 @@
* Iterates all threads/processes within all the defined jobs
*/
#define for_each_td(td, i) \
- for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++)
+ for ((i) = 0, (td) = &segments[0].threads[0]; (i) < (int) thread_number; (i)++, (td)++)
#define for_each_file(td, f, i) \
if ((td)->files_index) \
for ((i) = 0, (f) = (td)->files[0]; \
diff --git a/gettime-thread.c b/gettime-thread.c
index 953e4e6..9b82e53 100644
--- a/gettime-thread.c
+++ b/gettime-thread.c
@@ -58,7 +58,7 @@
* but I'm not sure what to use outside of a simple CPU nop to relax
* it - we don't want to lose precision.
*/
- while (threads) {
+ while (segments[0].threads) {
fio_gtod_update();
nop;
}
diff --git a/init.c b/init.c
index 7f64ce2..36b10ea 100644
--- a/init.c
+++ b/init.c
@@ -51,7 +51,7 @@
static bool merge_blktrace_only;
static struct thread_data def_thread;
-struct thread_data *threads = NULL;
+struct thread_segment segments[REAL_MAX_SEG];
static char **job_sections;
static int nr_job_sections;
@@ -301,17 +301,17 @@
void free_threads_shm(void)
{
- if (threads) {
- void *tp = threads;
+ if (segments[0].threads) {
+ void *tp = segments[0].threads;
#ifndef CONFIG_NO_SHM
struct shmid_ds sbuf;
- threads = NULL;
+ segments[0].threads = NULL;
shmdt(tp);
- shmctl(shm_id, IPC_RMID, &sbuf);
- shm_id = -1;
+ shmctl(segments[0].shm_id, IPC_RMID, &sbuf);
+ segments[0].shm_id = -1;
#else
- threads = NULL;
+ segments[0].threads = NULL;
free(tp);
#endif
}
@@ -319,7 +319,7 @@
static void free_shm(void)
{
- if (threads) {
+ if (segments[0].threads) {
flow_exit();
fio_debug_jobp = NULL;
fio_warned = NULL;
@@ -345,9 +345,10 @@
*/
static int setup_thread_area(void)
{
+ struct thread_segment *seg = &segments[0];
int i;
- if (threads)
+ if (seg->threads)
return 0;
/*
@@ -360,16 +361,16 @@
size += 2 * sizeof(unsigned int);
#ifndef CONFIG_NO_SHM
- shm_id = shmget(0, size, IPC_CREAT | 0600);
- if (shm_id != -1)
+ seg->shm_id = shmget(0, size, IPC_CREAT | 0600);
+ if (seg->shm_id != -1)
break;
if (errno != EINVAL && errno != ENOMEM && errno != ENOSPC) {
perror("shmget");
break;
}
#else
- threads = malloc(size);
- if (threads)
+ seg->threads = malloc(size);
+ if (seg->threads)
break;
#endif
@@ -377,22 +378,22 @@
} while (max_jobs);
#ifndef CONFIG_NO_SHM
- if (shm_id == -1)
+ if (seg->shm_id == -1)
return 1;
- threads = shmat(shm_id, NULL, 0);
- if (threads == (void *) -1) {
+ seg->threads = shmat(seg->shm_id, NULL, 0);
+ if (seg->threads == (void *) -1) {
perror("shmat");
return 1;
}
if (shm_attach_to_open_removed())
- shmctl(shm_id, IPC_RMID, NULL);
+ shmctl(seg->shm_id, IPC_RMID, NULL);
#endif
- memset(threads, 0, max_jobs * sizeof(struct thread_data));
+ memset(seg->threads, 0, max_jobs * sizeof(struct thread_data));
for (i = 0; i < max_jobs; i++)
- DRD_IGNORE_VAR(threads[i]);
- fio_debug_jobp = (unsigned int *)(threads + max_jobs);
+ DRD_IGNORE_VAR(seg->threads[i]);
+ fio_debug_jobp = (unsigned int *)(seg->threads + max_jobs);
*fio_debug_jobp = -1;
fio_warned = fio_debug_jobp + 1;
*fio_warned = 0;
@@ -484,7 +485,7 @@
return NULL;
}
- td = &threads[thread_number++];
+ td = &segments[0].threads[thread_number++];
*td = *parent;
INIT_FLIST_HEAD(&td->opt_list);
@@ -534,7 +535,7 @@
if (td->o.name)
free(td->o.name);
- memset(&threads[td->thread_number - 1], 0, sizeof(*td));
+ memset(td, 0, sizeof(*td));
thread_number--;
}
diff --git a/server.c b/server.c
index 248a2d4..c9b5c28 100644
--- a/server.c
+++ b/server.c
@@ -950,7 +950,7 @@
return 0;
}
- td = &threads[tnumber - 1];
+ td = &segments[0].threads[tnumber - 1];
convert_thread_options_to_cpu(&td->o, &pdu->top);
send_update_job_reply(cmd->tag, 0);
return 0;