#include <signal.h>
#include <time.h>
#include <ctype.h>
+#include <sched.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
static int shm_id;
+static cpu_set_t def_cpumask;
+
#define DDIR_READ (0)
#define DDIR_WRITE (1)
int bs;
int odirect;
int delay_sleep;
+ cpu_set_t cpumask;
unsigned int rate;
unsigned int rate_usec_cycle;
td = data + offset * sizeof(struct thread_data);
td->pid = getpid();
+ td->fd = -1;
+
+ if (sched_setaffinity(td->pid, sizeof(td->cpumask), &td->cpumask) == -1) {
+ td->error = errno;
+ goto err;
+ }
+
printf("Thread (%s) (pid=%u) (f=%s) started\n", td->ddir == DDIR_READ ? "read" : "write", td->pid, td->file_name);
fflush(stdout);
ret = 0;
out:
- close(td->fd);
if (statbuf)
free(statbuf);
shutdown_stat_file(td);
err:
+ if (td->fd != -1)
+ close(td->fd);
sem_post(&td->done_mutex);
if (ret)
sem_post(&startup_sem);
td->rate_pending_usleep = 0;
}
-void add_job(const char *filename, int rw, int bs, int direct, int prio, int random, int delay, int rate)
+void add_job(const char *filename, int rw, int bs, int direct, int prio, int random, int delay, int rate, cpu_set_t cpumask)
{
struct thread_data *td = &threads[thread_number++];
td->odirect = direct;
td->bs = bs;
td->delay_sleep = delay;
+ td->cpumask = cpumask;
if (rate)
setup_rate(td, rate);
printf("Client%d: file=%s, rw=%d, prio=%d, seq=%d, odir=%d, bs=%d, rate=%d\n", thread_number, filename, rw, prio, !random, direct, bs, rate);
}
+static void fill_cpu_mask(cpu_set_t cpumask, int cpu)
+{
+ int i;
+
+ CPU_ZERO(&cpumask);
+
+ for (i = 0; i < sizeof(int) * 8; i++) {
+ if ((1 << i) & cpu)
+ CPU_SET(i, &cpumask);
+ }
+}
+
void fill_option(const char *input, char *output)
{
int i;
*/
int parse_jobs_cmd(int argc, char *argv[], int index)
{
- int rw, bs, direct, prio, random, prioclass, delay, rate;
+ int rw, bs, direct, prio, random, prioclass, delay, rate, cpu;
char *string, *filename, *p, *c;
+ cpu_set_t cpumask;
int i;
string = malloc(256);
prioclass = 2;
delay = 0;
rate = 0;
+ memcpy(&cpumask, &def_cpumask, sizeof(cpumask));
c = strstr(p, "rw=");
if (c) {
rate = strtoul(string, NULL, 10);
}
+ c = strstr(p, "cpumask=");
+ if (c) {
+ c += 8;
+ fill_option(c, string);
+ cpu = strtoul(string, NULL, 10);
+ fill_cpu_mask(cpumask, cpu);
+ }
+
+
c = strstr(p, "random");
if (c)
random = 1;
if (c)
random = 0;
- add_job(filename, rw, bs, direct, (prioclass << IOPRIO_CLASS_SHIFT) | prio, random, delay, rate);
+ add_job(filename, rw, bs, direct, (prioclass << IOPRIO_CLASS_SHIFT) | prio, random, delay, rate, cpumask);
}
free(string);
int parse_jobs_ini(char *file)
{
- int rw, bs, direct, prio, random, prioclass, delay, rate, jobs;
+ int rw, bs, direct, prio, random, prioclass, delay, rate, jobs, cpu;
+ cpu_set_t cpumask;
char *string, *name;
fpos_t off;
FILE *f;
prioclass = 2;
delay = 0;
rate = 0;
+ memcpy(&cpumask, &def_cpumask, sizeof(cpumask));
+ cpu = 0;
fgetpos(f, &off);
while ((p = fgets(string, 4096, f)) != NULL) {
fgetpos(f, &off);
continue;
}
+ if (!check_int(p, "cpumask", &cpu)) {
+ fill_cpu_mask(cpumask, cpu);
+ fgetpos(f, &off);
+ continue;
+ }
if (!strcmp(p, "sequential")) {
sequential = 1;
fgetpos(f, &off);
}
fsetpos(f, &off);
- add_job(name, rw, bs, direct, (prioclass << IOPRIO_CLASS_SHIFT) | prio, random, delay, rate);
+ add_job(name, rw, bs, direct, (prioclass << IOPRIO_CLASS_SHIFT) | prio, random, delay, rate, cpumask);
jobs++;
}
static unsigned long read_mb, write_mb, read_agg, write_agg;
int i, jobs;
+ if (sched_getaffinity(getpid(), sizeof(def_cpumask), &def_cpumask) == -1) {
+ perror("sched_getaffinity");
+ return 1;
+ }
+
shm_id = shmget(0, (argc - 1) * sizeof(struct thread_data), IPC_CREAT | 0600);
if (shm_id == -1) {
perror("shmget");