Exemple #1
0
/* elevate to maximum realtime priority :) */
static void elevate_prio(void)
{
	struct sched_param sp;
	FILE *cgroup_fp;
	pid_t us;
	int rc;

	us = getpid();

	/* if cgroups are present add us otherwise we don't have permission to enable RT */
	cgroup_fp = fopen("/sys/fs/cgroup/cpu/tasks", "w");
	if (!cgroup_fp)
		goto nop;

	rc = fprintf(cgroup_fp, "%d", us);
	if (rc < 0)
		DIE_PERROR("fprintf failed");
	fclose(cgroup_fp);

nop:
	sp.sched_priority = sched_get_priority_max(SCHED_RR);
	if (sp.sched_priority < 0)
		DIE_PERROR("sched_get_priority_max failed");
	rc = sched_setscheduler(0, SCHED_RR, &sp);
	if (rc < 0)
		DIE_PERROR("sched_setscheduler failed");
}
Exemple #2
0
void data_init_cpu(void)
{
	int i, values = 0;
	char *ptr;

	cpu_fp = fopen("/proc/stat", "r");
	if (!cpu_fp)
		DIE_PERROR("open procfs failed");

	/* detect number of columns in cpu line */
	i = getline(&cpu_buf_ptr, &cpu_line_size, cpu_fp);
	if (i < 0)
		DIE_PERROR("getline failed");
	/* skiped cpu summary line */
	i = getline(&cpu_buf_ptr, &cpu_line_size, cpu_fp);
	if (i < 0)
		DIE_PERROR("getline failed");
	fclose(cpu_fp);

	ptr = cpu_buf_ptr;
	while (*ptr != '\n') {
		if (*ptr == ' ')
			values++;
		ptr++;
	}
	cpu_line_entries = values;
	DEBUG("%d numerical values in cpu lines\n", cpu_line_entries);

	cpu_hist = calloc(nr_cpus, sizeof(struct cpu_usage));
	if (!cpu_hist)
		DIE_PERROR("malloc failed");
	cpu_delta = calloc(nr_cpus, sizeof(struct cpu_usage));
	if (!cpu_delta)
		DIE_PERROR("malloc failed");
}
Exemple #3
0
static int setup_netlink(void)
{
	int rc, id, rcvbufsz = 0;
	struct sockaddr_nl nla;
	socklen_t len;

	nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (nl_fd < 0)
		DIE_PERROR("netlink socket failed");

	memset(&nla, 0, sizeof(nla));
	nla.nl_family = AF_NETLINK;

	rc = bind(nl_fd, (struct sockaddr *) &nla, sizeof(struct sockaddr_nl));
	if (rc < 0)
		DIE_PERROR("netlink bind failed");

	len = sizeof(int);
	if (getsockopt(nl_fd, SOL_SOCKET, SO_RCVBUF, &rcvbufsz, &len) < 0)
		fprintf(stderr, "Unable to get socket rcv buf size\n");
	else
		DEBUG("receive buffer size: %d\n", rcvbufsz);

	id = get_family_id(nl_fd);
	if (!id)
		DIE_PERROR("Error getting family id");

	nl_id = id;
	DEBUG("family id %d\n", nl_id);
	return 0;
}
Exemple #4
0
/* get CPU summary values out of proc */
void query_cpu_summary(void)
{
	struct cpu_usage now;
	ssize_t len;
	int cpu = 0;

	cpu_fp = fopen("/proc/stat", "r");
	if (!cpu_fp)
		DIE_PERROR("open procfs failed");

	len = getline(&cpu_buf_ptr, &cpu_line_size, cpu_fp);
	if (len < 0)
		DIE_PERROR("getline failed");

	parse_cpu_sum_info(cpu_buf_ptr, cpu, &now);

	// XXX calc deltas and store in cpu_delta
	cpu_delta[cpu].user = (now.user - cpu_hist[cpu].user) * 10;
	cpu_delta[cpu].system = (now.system - cpu_hist[cpu].system) * 10;
	cpu_delta[cpu].irq = (now.irq - cpu_hist[cpu].irq) * 10;
	cpu_delta[cpu].softirq = (now.softirq - cpu_hist[cpu].softirq) * 10;
	cpu_delta[cpu].iowait = (now.iowait - cpu_hist[cpu].iowait) * 10;
	cpu_delta[cpu].idle = (now.idle - cpu_hist[cpu].idle) * 10;

	/* update cpu values */
	memcpy(&cpu_hist[cpu], &now, sizeof(now));

	fclose(cpu_fp);
}
Exemple #5
0
/* get system memory usage out of proc */
void query_memory(void)
{
	size_t mem_line_size = 256;
	char mem_buf[256];
	char *mem_buf_ptr = mem_buf;
	FILE *mem_fp;
	ssize_t len;
	int i = 0;

	mem_fp = fopen("/proc/meminfo", "r");
	if (!mem_fp)
		DIE_PERROR("open procfs failed");

	do {
		/* only intrested in first two lines:
		 * MemTotal:        4980832 kB
		 * MemFree:         1376304 kB
		 */
		if (i++ > 1)
			break;

		len = getline(&mem_buf_ptr, &mem_line_size, mem_fp);
		if (len < 0)
			DIE_PERROR("getline failed");

		if (i == 1)
			sscanf(mem_buf_ptr, "MemTotal: %u kB\n", &mem_total);
		if (i == 2)
			sscanf(mem_buf_ptr, "MemFree: %u kB\n", &mem_free);

	} while (!feof(mem_fp));

	fclose(mem_fp);
}
Exemple #6
0
static void measure_one_cycle(void)
{
	struct timespec ts1, ts2, delta, sleep;
	int rc;

	current_sum_utime = 0;
	current_sum_stime = 0;
	current_sum_cpu_utime = 0;
	current_sum_cpu_stime = 0;

	if (nr_cycles)
		output->print_cycle_start();
	else
		output->print_sync();
	new_cycle = 1;

	rc = clock_gettime(CLOCK_MONOTONIC, &ts1);
	if (rc < 0)
		DIE_PERROR("clock_gettime failed");

	query_tasks();
	query_memory();
	query_cpus(opt_all_cpus);

	print_tasks();
	print_memory();
	print_cpus(opt_all_cpus);

	rc = clock_gettime(CLOCK_MONOTONIC, &ts2);
	if (rc < 0)
		DIE_PERROR("clock_gettime failed");

	timespec_delta(&ts1, &ts2, &delta);
	if (nr_cycles)
		output->print_cycle_end(&delta);

	/* check if we can meet the target measurement interval */
	if (delta.tv_sec > target.tv_sec ||
	    (delta.tv_sec == target.tv_sec && delta.tv_nsec > target.tv_nsec)) {
		output->exit_output();
		DIE("Target measurement intervall too small. Current overhead: %u seconds %lu ms\n",
			(int) delta.tv_sec, delta.tv_nsec / NSECS_PER_MSEC);
	}

	/* now go sleeping for the rest of the measurement interval */
	if (nr_cycles)
		timespec_delta(&delta, &target, &sleep);
	else
		timespec_delta(&delta, &ts_sync, &sleep);

	wait_for_cycle_end(&sleep);
	nr_cycles++;
}
Exemple #7
0
static int open_conf_file(FILE **fh)
{
    const char *home_env;

    conf_file = malloc(4096);
    if (conf_file == NULL)
        DIE_PERROR("malloc failed");

    home_env = getenv("HOME");
    if (home_env == NULL)
        goto no_home;

    sprintf(conf_file, "%s/.cmsfs-fuse/filetypes.conf", home_env);
    *fh = fopen(conf_file, "r");
    if (*fh != NULL)
        goto out;

no_home:
    sprintf(conf_file, "%s/%s", TOOLS_SYSCONFDIR,
            "/cmsfs-fuse/filetypes.conf");
    *fh = fopen(conf_file, "r");
    if (*fh == NULL) {
        free(conf_file);
        return -ENOENT;
    }
out:
    DEBUG("using config file: %s\n", conf_file);
    return 0;
}
Exemple #8
0
/* get the number of configured CPUs, some may be offline */
int get_nr_cpus(void)
{
	unsigned long cpus = sysconf(_SC_NPROCESSORS_CONF);

	if (cpus < 0)
		DIE_PERROR("sysconf failed");
	return cpus;
}
Exemple #9
0
static void setup_cpumask(void)
{
	nl_cpumask = malloc(20);	/* enough for "0-4096" :) */
	if (nl_cpumask < 0)
		DIE_PERROR("malloc failed");
	memset(nl_cpumask, 0, 20);
	snprintf(nl_cpumask, 20, "0-%d", nr_cpus - 1);
}
Exemple #10
0
static void add_filetype(char *name, struct util_list *list)
{
    struct filetype *entry;

    entry = malloc(sizeof(*entry));
    if (entry == NULL)
        DIE_PERROR("malloc failed");
    strncpy(entry->name, name, MAX_TYPE_LEN);
    util_list_add_head(list, entry);
}
Exemple #11
0
/* get per CPU values out of proc */
void query_all_cpus(void)
{
	struct cpu_usage now;
	ssize_t len;
	int cpu, line;

	cpu_fp = fopen("/proc/stat", "r");
	if (!cpu_fp)
		DIE_PERROR("open procfs failed");

	/* this is a bit ugly (nr_cpus + 1) because of the summary line... */
	for (line = 0; line < nr_cpus + 1; line++) {
		len = getline(&cpu_buf_ptr, &cpu_line_size, cpu_fp);
		if (len < 0)
			DIE_PERROR("getline failed");

		/* skip summary line */
		if (line == 0)
			continue;

		cpu = line - 1;

		parse_cpu_info(cpu_buf_ptr, cpu, &now);
		//if (nr_cycles)
		//	output->print_cpu_info(i - 1, &now);

		// XXX calc deltas and store in cpu_delta
		cpu_delta[cpu].user = (now.user - cpu_hist[cpu].user) * 10;
		cpu_delta[cpu].system = (now.system - cpu_hist[cpu].system) * 10;
		cpu_delta[cpu].irq = (now.irq - cpu_hist[cpu].irq) * 10;
		cpu_delta[cpu].softirq = (now.softirq - cpu_hist[cpu].softirq) * 10;
		cpu_delta[cpu].iowait = (now.iowait - cpu_hist[cpu].iowait) * 10;
		cpu_delta[cpu].idle = (now.idle - cpu_hist[cpu].idle) * 10;

		/* update cpu values */
		memcpy(&cpu_hist[cpu], &now, sizeof(now));
	}
	fclose(cpu_fp);
}
int
main(int ac, char **av)
{
	state_t state;
	int rc, c, repetitions = -1, warmup = 0;
	char	buf[256];
	char	*usage = "-s\n OR [-S] [-W <warmup>] [-N <repetitions>] server\n";

	while (( c = getopt(ac, av, "sSP:W:N:")) != EOF) {
		switch(c) {
		case 's': /* Server */
			if (fork() == 0) {
				server_main();
			}
			exit(0);
		case 'S': /* shutdown serverhost */
		{
			int sock = tcp_connect(av[optind],
					       TCP_CONNECT,
					       SOCKOPT_NONE);
			rc = write(sock, "0", 1);
			if (rc < 0)
				DIE_PERROR("write failed");
			close(sock);
			exit(0);
		}
		case 'W':
			warmup = atoi(optarg);
			break;
		case 'N':
			repetitions = atoi(optarg);
			break;
		default:
			lmbench_usage(ac, av, usage);
			break;
		}
	}

	if (optind + 1 != ac) {
		lmbench_usage(ac, av, usage);
	}

	handle_scheduler(benchmp_childid(), 0, 0);

	state.server = av[optind];
	benchmp(NULL, doclient, NULL, 0, 1, warmup, repetitions, &state);

	sprintf(buf, "TCP/IP connection cost to %s", state.server);
	micro(buf, get_n());
	exit(0);
}
void
server(void* cookie)
{
	int pid, rc;
	state_t* state = (state_t*)cookie;

	pid = getpid();
	state->pid = 0;

	if (state->fid_f == open_file) {
		/* Create a temporary file for clients to open */
		sprintf(state->fname, "lat_selectXXXXXX");
		state->fid = mkstemp(state->fname);
		if (state->fid <= 0) {
			char buf[L_tmpnam+128];
			sprintf(buf, "lat_select: Could not create temp file %s", state->fname);
			perror(buf);
			exit(1);
		}
		close(state->fid);
		return;
	}

	/* Create a socket for clients to connect to */
	state->sock = tcp_server(TCP_SELECT, SOCKOPT_REUSE);
	if (state->sock <= 0) {
		perror("lat_select: Could not open tcp server socket");
		exit(1);
	}

	/* Start a server process to accept client connections */
	switch(state->pid = fork()) {
	case 0:
		/* child server process */
		while (pid == getppid()) {
			int newsock = tcp_accept(state->sock, SOCKOPT_NONE);
			rc = read(newsock, &state->fid, 1);
			if (rc < 0)
				DIE_PERROR("read failed");
			close(newsock);
		}
		exit(0);
	case -1:
		/* error */
		perror("lat_select::server(): fork() failed");
		exit(1);
	default:
		break;
	}
}
Exemple #14
0
/*
 * TODO: check alignment
 */
void bm_alloc(int bits)
{
	int bytes = bits / 8;

	if (!bits || bits < 0 || bits % 8)
		DIE("invalid bit count: %d", bits);

	map = malloc(bytes);
	if (!map)
		DIE_PERROR("allocating bitmap failed");
	memset(map, 0, bytes);

	nr_bits = bits;
	DEBUG("alloc map @ %p  for %d bits\n", map, nr_bits);
}
Exemple #15
0
void wait_for_cycle_end(struct timespec *sleep)
{
	struct timespec remain;
	int rc;

resume:
	rc = nanosleep(sleep, &remain);
	if (rc < 0 && errno == EINTR) {
		fprintf(stderr, "resuming interrupted sleep\n");
		*sleep = remain;
		goto resume;
	}
	if (rc < 0)
		DIE_PERROR("nanosleep failed");
}
Exemple #16
0
iter_t
benchmp_interval(void* _state)
{
	char		c;
	iter_t		iterations;
	double		result;
	fd_set		fds;
	struct timeval	timeout;
	int rc;
	benchmp_child_state* state = (benchmp_child_state*)_state;

	iterations = (state->state == timing_interval ? state->iterations : state->iterations_batch);

	if (state->need_warmup) {
		/* remove spurious compilation warning */
		result = state->enough;
	} else {
		result = stop(0,0);
		if (state->cleanup) {
			if (benchmp_sigchld_handler == SIG_DFL)
				signal(SIGCHLD, SIG_DFL);
			(*state->cleanup)(iterations, state->cookie);
		}
		save_n(state->iterations);
		result -= t_overhead() + get_n() * l_overhead();
		settime(result >= 0. ? (uint64)result : 0.);
	}

	/* if the parent died, then give up */
	if (getppid() == 1 && state->cleanup) {
		if (benchmp_sigchld_handler == SIG_DFL)
			signal(SIGCHLD, SIG_DFL);
		(*state->cleanup)(0, state->cookie);
		exit(0);
	}

	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
	FD_ZERO(&fds);

	switch (state->state) {
	case warmup:
		iterations = state->iterations_batch;
		FD_SET(state->start_signal, &fds);
		select(state->start_signal+1, &fds, NULL,
		       NULL, &timeout);
		if (FD_ISSET(state->start_signal, &fds)) {
			state->state = timing_interval;
			rc = read(state->start_signal, &c, sizeof(char));
			if (rc < 0)
				DIE_PERROR("read failed");
			iterations = state->iterations;
		}
		if (state->need_warmup) {
			state->need_warmup = 0;
			/* send 'ready' */
			rc = write(state->response, &c, sizeof(char));
			if (rc < 0)
				DIE_PERROR("write failed");
		}
		break;
	case timing_interval:
		iterations = state->iterations;
		if (state->parallel > 1 || result > 0.95 * state->enough) {
			insertsort(gettime(), get_n(), get_results());
			state->i++;
			/* we completed all the experiments, return results */
			if (state->i >= state->repetitions) {
				state->state = cooldown;
			}
		}
		if (state->parallel == 1 
		    && (result < 0.99 * state->enough || result > 1.2 * state->enough)) {
			if (result > 150.) {
				double tmp = iterations / result;
				tmp *= 1.1 * state->enough;
				iterations = (iter_t)(tmp + 1);
			} else {
				iterations <<= 3;
				if (iterations > 1<<27
				    || (result < 0. && iterations > 1<<20)) {
					state->state = cooldown;
				}
			}
		}
		state->iterations = iterations;
		if (state->state == cooldown) {
			/* send 'done' */
			rc = write(state->response, (void*)&c, sizeof(char));
			if (rc < 0)
				DIE_PERROR("write failed");
			iterations = state->iterations_batch;
		}
		break;
	case cooldown:
		iterations = state->iterations_batch;
		FD_SET(state->result_signal, &fds);
		select(state->result_signal+1, &fds, NULL, NULL, &timeout);
		if (FD_ISSET(state->result_signal, &fds)) {
			/* 
			 * At this point all children have stopped their
			 * measurement loops, so we can block waiting for
			 * the parent to tell us to send our results back.
			 * From this point on, we will do no more "work".
			 */
			rc = read(state->result_signal, (void*)&c, sizeof(char));
			if (rc < 0)
				DIE_PERROR("read failed");
			rc = write(state->response, (void*)get_results(), state->r_size);
			if (rc < 0)
				DIE_PERROR("write failed");
			if (state->cleanup) {
				if (benchmp_sigchld_handler == SIG_DFL)
					signal(SIGCHLD, SIG_DFL);
				(*state->cleanup)(0, state->cookie);
			}

			/* Now wait for signal to exit */
			rc = read(state->exit_signal, (void*)&c, sizeof(char));
			if (rc < 0)
				DIE_PERROR("read failed");
			exit(0);
		}
	};
	if (state->initialize) {
		(*state->initialize)(iterations, state->cookie);
	}
	start(0);
	return (iterations);
}
Exemple #17
0
void
benchmp_parent(	int response, 
		int start_signal, 
		int result_signal, 
		int exit_signal,
		pid_t* pids,
		int parallel, 
	        iter_t iterations,
		int warmup,
		int repetitions,
		int enough
		)
{
	int		i, j, rc, bytes_read;
	result_t*	results = NULL;
	result_t*	merged_results = NULL;
	char*		signals = NULL;
	unsigned char*	buf;
	fd_set		fds_read, fds_error;
	struct timeval	timeout;

	if (benchmp_sigchld_received || benchmp_sigterm_received) {
#ifdef _DEBUG
		fprintf(stderr, "benchmp_parent: entering, benchmp_sigchld_received=%d\n", benchmp_sigchld_received);
#endif
		goto error_exit;
	}

	results = (result_t*)malloc(sizeof_result(repetitions));
	merged_results = (result_t*)malloc(sizeof_result(parallel * repetitions));
	signals = (char*)malloc(parallel * sizeof(char));
	if (!results || !merged_results || !signals) return;

	/* Collect 'ready' signals */
	for (i = 0; i < parallel * sizeof(char); i += bytes_read) {
		bytes_read = 0;
		FD_ZERO(&fds_read);
		FD_ZERO(&fds_error);
		FD_SET(response, &fds_read);
		FD_SET(response, &fds_error);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		select(response+1, &fds_read, NULL, &fds_error, &timeout);
		if (benchmp_sigchld_received 
		    || benchmp_sigterm_received
		    || FD_ISSET(response, &fds_error)) 
		{
#ifdef _DEBUG
			fprintf(stderr, "benchmp_parent: ready, benchmp_sigchld_received=%d\n", benchmp_sigchld_received);
#endif
			goto error_exit;
		}
		if (!FD_ISSET(response, &fds_read)) {
			continue;
		}

		bytes_read = read(response, signals, parallel * sizeof(char) - i);
		if (bytes_read < 0) {
#ifdef _DEBUG
			fprintf(stderr, "benchmp_parent: ready, bytes_read=%d, %s\n", bytes_read, strerror(errno));
#endif
			goto error_exit;
		}
	}

	/* let the children run for warmup microseconds */
	if (warmup > 0) {
		struct timeval delay;
		delay.tv_sec = warmup / 1000000;
		delay.tv_usec = warmup % 1000000;

		select(0, NULL, NULL, NULL, &delay);
	}

	/* send 'start' signal */
	rc = write(start_signal, signals, parallel * sizeof(char));
	if (rc < 0)
		DIE_PERROR("write failed");

	/* Collect 'done' signals */
	for (i = 0; i < parallel * sizeof(char); i += bytes_read) {
		bytes_read = 0;
		FD_ZERO(&fds_read);
		FD_ZERO(&fds_error);
		FD_SET(response, &fds_read);
		FD_SET(response, &fds_error);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		select(response+1, &fds_read, NULL, &fds_error, &timeout);
		if (benchmp_sigchld_received 
		    || benchmp_sigterm_received
		    || FD_ISSET(response, &fds_error)) 
		{
#ifdef _DEBUG
			fprintf(stderr, "benchmp_parent: done, benchmp_child_died=%d\n", benchmp_sigchld_received);
#endif
			goto error_exit;
		}
		if (!FD_ISSET(response, &fds_read)) {
			continue;
		}

		bytes_read = read(response, signals, parallel * sizeof(char) - i);
		if (bytes_read < 0) {
#ifdef _DEBUG
			fprintf(stderr, "benchmp_parent: done, bytes_read=%d, %s\n", bytes_read, strerror(errno));
#endif
			goto error_exit;
		}
	}

	/* collect results */
	insertinit(merged_results);
	for (i = 0; i < parallel; ++i) {
		int n = sizeof_result(repetitions);
		buf = (unsigned char*)results;

		FD_ZERO(&fds_read);
		FD_ZERO(&fds_error);

		/* tell one child to report its results */
		rc = write(result_signal, buf, sizeof(char));

		for (; n > 0; n -= bytes_read, buf += bytes_read) {
			bytes_read = 0;
			FD_SET(response, &fds_read);
			FD_SET(response, &fds_error);

			timeout.tv_sec = 1;
			timeout.tv_usec = 0;
			select(response+1, &fds_read, NULL, &fds_error, &timeout);
			if (benchmp_sigchld_received 
			    || benchmp_sigterm_received
			    || FD_ISSET(response, &fds_error)) 
			{
#ifdef _DEBUG
				fprintf(stderr, "benchmp_parent: results, benchmp_sigchld_received=%d\n", benchmp_sigchld_received);
#endif
				goto error_exit;
			}
			if (!FD_ISSET(response, &fds_read)) {
				continue;
			}

			bytes_read = read(response, buf, n);
			if (bytes_read < 0) {
#ifdef _DEBUG
				fprintf(stderr, "benchmp_parent: results, bytes_read=%d, %s\n", bytes_read, strerror(errno));
#endif
				goto error_exit;
			}
		}
		for (j = 0; j < results->N; ++j) {
			insertsort(results->v[j].u, 
				   results->v[j].n, merged_results);
		}
	}

	/* we allow children to die now, without it causing an error */
	signal(SIGCHLD, SIG_DFL);
	
	/* send 'exit' signals */
	rc = write(exit_signal, results, parallel * sizeof(char));
	if (rc < 0)
		DIE_PERROR("write failed");

	/* Compute median time; iterations is constant! */
	set_results(merged_results);

	goto cleanup_exit;
error_exit:
#ifdef _DEBUG
	fprintf(stderr, "benchmp_parent: error_exit!\n");
#endif
	signal(SIGCHLD, SIG_DFL);
	for (i = 0; i < parallel; ++i) {
		kill(pids[i], SIGTERM);
		waitpid(pids[i], NULL, 0);
	}
	free(merged_results);
cleanup_exit:
	close(response);
	close(start_signal);
	close(result_signal);
	close(exit_signal);

	if (results) free(results);
	if (signals) free(signals);
}
Exemple #18
0
int main(int argc, char* argv[])
{
	pthread_t proc_events_thread;
	void *status;
	int rc, opt, cycles = INT_MAX;

#ifdef DEBUG_ENABLED
	logfile = fopen(DEBUG_LOGFILE, "w");
	if (logfile == NULL)
		DIE_PERROR("Cannot open file " DEBUG_LOGFILE " for writing");
#endif

#ifdef CONFIG_NCURSES
	/* default is ncurses output */
	output = &oops_ncurses;
#else
	output = &oops_stdout;
#endif

	while (1) {
		int option_index = 0;
		static struct option long_options[] = {
			{ "realtime",	no_argument,		&opt_realtime, 1},
			{ "all_cpus",	no_argument,		&opt_all_cpus, 1},
			{ "sort",	required_argument,	0,  's'},
			{ "output",	required_argument,	0,  'o'},
			{ "seconds",	required_argument,	0,  't' },
			{ "milliseconds",required_argument,	0,  'm' },
			{ "cycles",	required_argument,	0,  'c' },
			{ "help",	no_argument,		0,  'h' },
			{ 0, 0, 0, 0 },
		};

		opt = getopt_long(argc, argv, "s:o:c:h?", long_options, &option_index);
		if (opt == -1)
			break;

		switch (opt) {
		case 'o':
			if (strcmp(optarg, "csv") == 0)
				output = &oops_csv;
			else if (strcmp(optarg, "stdout") == 0)
				output = &oops_stdout;
#ifdef CONFIG_NCURSES
			else if (strcmp(optarg, "ncurses") == 0)
				output = &oops_ncurses;
#endif
			else if (strcmp(optarg, "nop") == 0)
				output = &oops_nop;
			else { /* unknown */
				fprintf(stderr, "Unknown output method %s\n", optarg);
				print_help(argc, argv);
			}
			break;
		case 's':
			if (strcmp(optarg, "name") == 0)
				opt_sort = OPT_SORT_NAME;
			else if (strcmp(optarg, "id") == 0)
				opt_sort = OPT_SORT_TID;
			else if (strcmp(optarg, "time") == 0)
				opt_sort = OPT_SORT_TIME;
			else if (strcmp(optarg, "io") == 0)
				opt_sort = OPT_SORT_IO;
			else if (strcmp(optarg, "mem") == 0)
				opt_sort = OPT_SORT_MEM;
			else { /* unknown */
				fprintf(stderr, "Unknown sort method %s\n", optarg);
				print_help(argc, argv);
			}
			break;
		case 't':
			target.tv_sec = atoi(optarg);
			break;
		case 'm':
			target.tv_nsec = atol(optarg) * NSECS_PER_MSEC;
			break;
		case 'c':
			cycles = atoi(optarg);
			break;
		case 0:
			break;
		case '?':
		case 'h':
		default:
			print_help(argc, argv);
		}
	}

	nr_cpus = get_nr_cpus();

	bm_alloc(PID_MAX);
	rc = pthread_create(&proc_events_thread, NULL, proc_events_main, NULL);
	if (rc)
		DIE_PERROR("pthread_create failed");
	pthread_setname_np(proc_events_thread, "nlmon-pevent");

	setup_netlink();
	start_task_monitor();

	while (!procfs_thread) {
		DEBUG("...\n");
		pthread_yield();
		__sync_synchronize();
	}

	rc = pthread_join(procfs_thread, &status);
	if (rc)
		DIE_PERROR("pthread_join failed");
	else
		DEBUG("procfs scan thread exited\n");

	data_init_cpu();
	if (opt_realtime)
		elevate_prio();

	cache_init();
	output->init_output();
	while (cycles--)
		measure_one_cycle();
	output->exit_output();
	stop_task_monitor();
	exit(EXIT_SUCCESS);
}
Exemple #19
0
static void gather_data(struct taskstats *t)
{
	struct taskstat_delta *delta;
	struct hash_entry *h;

	if (!nr_cycles && !once) {
		ts_version = t->version;
		ts_size = sizeof(*t);
		output->print_banner(t);
		once = 1;
	}

	h = get_hash_entry(t->ac_pid);
	if (!h)
		DIE("hash entry missing for process %d!", t->ac_pid);
	if (t->ac_pid != h->tid)
		DIE("pid mismatch in hash!");

	// XXX this sucks, optimize later
	delta = malloc(sizeof(struct taskstat_delta));
	if (!delta)
		DIE_PERROR("malloc failed");
	memset(delta, 0, sizeof(struct taskstat_delta));
	delta->pid = h->tgid;
	delta->tid = t->ac_pid;

	__gather_data_sanity(h, t);

	delta->utime = t->ac_utime - h->utime;
	delta->stime = t->ac_stime - h->stime;
	delta->cpu_delay = t->cpu_delay_total - h->cpu_delay;
	delta->rss = t->coremem - h->rss;
	delta->io_rd_bytes = t->read_char - h->io_rd_bytes;
	delta->io_wr_bytes = t->write_char - h->io_wr_bytes;
	delta->blkio_delay = t->blkio_delay_total - h->blkio_delay;

	/* store new values */
	h->utime = t->ac_utime;
	h->stime = t->ac_stime;
	h->cpu_delay = t->cpu_delay_total;
	h->rss = t->coremem;
	h->io_rd_bytes = t->read_char;
	h->io_wr_bytes = t->write_char;
	h->blkio_delay = t->blkio_delay_total;

	put_hash_entry(t->ac_pid);

	if (t->ac_exitcode)
		DEBUG("exiting task: %d [%s]\n", t->ac_pid, t->ac_comm);

	current_sum_utime += delta->utime / 1000;
	current_sum_stime += delta->stime / 1000;

	if (!nr_cycles)
		return;

	/* only output if one value changed! */
	if (output_wanted(delta)) {
		// XXX optimize later, maybe pointer to task string in hash entry?
		memcpy(&delta->comm, t->ac_comm, TS_COMM_LEN);
		cache_add(delta);
	}
}