Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c98d466 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf tools: Refactor all_tids to hold nr and the map



So that later, we can pass the thread_map instance instead of
(thread_num, thread_map) for things like perf_evsel__open and friends,
just like was done with cpu_map.

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 60d567e2
Loading
Loading
Loading
Loading
+15 −24
Original line number Diff line number Diff line
@@ -54,8 +54,7 @@ static bool sample_id_all_avail = true;
static bool			system_wide			=  false;
static pid_t			target_pid			=     -1;
static pid_t			target_tid			=     -1;
static pid_t			*all_tids			=      NULL;
static int			thread_num			=      0;
static struct thread_map	*threads;
static pid_t			child_pid			=     -1;
static bool			no_inherit			=  false;
static enum write_mode_t	write_mode			= WRITE_FORCE;
@@ -318,9 +317,9 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
retry_sample_id:
	attr->sample_id_all = sample_id_all_avail ? 1 : 0;

	for (thread_index = 0; thread_index < thread_num; thread_index++) {
	for (thread_index = 0; thread_index < threads->nr; thread_index++) {
try_again:
		FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, all_tids[thread_index], cpu, group_fd, 0);
		FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, threads->map[thread_index], cpu, group_fd, 0);

		if (FD(evsel, nr_cpu, thread_index) < 0) {
			int err = errno;
@@ -653,7 +652,7 @@ static int __cmd_record(int argc, const char **argv)
		}

		if (!system_wide && target_tid == -1 && target_pid == -1)
			all_tids[0] = child_pid;
			threads->map[0] = child_pid;

		close(child_ready_pipe[1]);
		close(go_pipe[0]);
@@ -793,7 +792,7 @@ static int __cmd_record(int argc, const char **argv)

				list_for_each_entry(pos, &evsel_list, node) {
					for (thread = 0;
						thread < thread_num;
						thread < threads->nr;
						thread++)
						ioctl(FD(pos, i, thread),
							PERF_EVENT_IOC_DISABLE);
@@ -910,21 +909,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
		goto out_symbol_exit;
	}

	if (target_pid != -1) {
	if (target_pid != -1)
		target_tid = target_pid;
		thread_num = find_all_tid(target_pid, &all_tids);
		if (thread_num <= 0) {
			fprintf(stderr, "Can't find all threads of pid %d\n",
					target_pid);
			usage_with_options(record_usage, record_options);
		}
	} else {
		all_tids=malloc(sizeof(pid_t));
		if (!all_tids)
			goto out_symbol_exit;

		all_tids[0] = target_tid;
		thread_num = 1;
	threads = thread_map__new(target_pid, target_tid);
	if (threads == NULL) {
		pr_err("Problems finding threads of monitor\n");
		usage_with_options(record_usage, record_options);
	}

	cpus = cpu_map__new(cpu_list);
@@ -934,11 +925,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	}

	list_for_each_entry(pos, &evsel_list, node) {
		if (perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0)
		if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
			goto out_free_fd;
	}
	event_array = malloc(
		sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
	event_array = malloc((sizeof(struct pollfd) * MAX_NR_CPUS *
			      MAX_COUNTERS * threads->nr));
	if (!event_array)
		goto out_free_fd;

@@ -965,8 +956,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
out_free_event_array:
	free(event_array);
out_free_fd:
	free(all_tids);
	all_tids = NULL;
	thread_map__delete(threads);
	threads = NULL;
out_symbol_exit:
	symbol__exit();
	return err;
+17 −24
Original line number Diff line number Diff line
@@ -81,8 +81,7 @@ static bool scale = true;
static bool			no_aggr				= false;
static pid_t			target_pid			= -1;
static pid_t			target_tid			= -1;
static pid_t			*all_tids			=  NULL;
static int			thread_num			=  0;
static struct thread_map	*threads;
static pid_t			child_pid			= -1;
static bool			null_run			=  false;
static bool			big_num				=  true;
@@ -175,7 +174,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
		attr->enable_on_exec = 1;
	}

	return perf_evsel__open_per_thread(evsel, thread_num, all_tids);
	return perf_evsel__open_per_thread(evsel, threads->nr, threads->map);
}

/*
@@ -200,7 +199,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
	u64 *count = counter->counts->aggr.values;
	int i;

	if (__perf_evsel__read(counter, cpus->nr, thread_num, scale) < 0)
	if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0)
		return -1;

	for (i = 0; i < 3; i++)
@@ -298,7 +297,7 @@ static int run_perf_stat(int argc __used, const char **argv)
		}

		if (target_tid == -1 && target_pid == -1 && !system_wide)
			all_tids[0] = child_pid;
			threads->map[0] = child_pid;

		/*
		 * Wait for the child to be ready to exec.
@@ -353,7 +352,7 @@ static int run_perf_stat(int argc __used, const char **argv)
	} else {
		list_for_each_entry(counter, &evsel_list, node) {
			read_counter_aggr(counter);
			perf_evsel__close_fd(counter, cpus->nr, thread_num);
			perf_evsel__close_fd(counter, cpus->nr, threads->nr);
		}
	}

@@ -693,6 +692,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
		}
	}

	if (target_pid != -1)
		target_tid = target_pid;

	threads = thread_map__new(target_pid, target_tid);
	if (threads == NULL) {
		pr_err("Problems finding threads of monitor\n");
		usage_with_options(stat_usage, options);
	}

	if (system_wide)
		cpus = cpu_map__new(cpu_list);
	else
@@ -704,27 +712,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
		return -1;
	}

	if (target_pid != -1) {
		target_tid = target_pid;
		thread_num = find_all_tid(target_pid, &all_tids);
		if (thread_num <= 0) {
			fprintf(stderr, "Can't find all threads of pid %d\n",
					target_pid);
			usage_with_options(stat_usage, options);
		}
	} else {
		all_tids=malloc(sizeof(pid_t));
		if (!all_tids)
			return -ENOMEM;

		all_tids[0] = target_tid;
		thread_num = 1;
	}

	list_for_each_entry(pos, &evsel_list, node) {
		if (perf_evsel__alloc_stat_priv(pos) < 0 ||
		    perf_evsel__alloc_counts(pos, cpus->nr) < 0 ||
		    perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0)
		    perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
			goto out_free_fd;
	}

@@ -752,5 +743,7 @@ out_free_fd:
	list_for_each_entry(pos, &evsel_list, node)
		perf_evsel__free_stat_priv(pos);
out:
	thread_map__delete(threads);
	threads = NULL;
	return status;
}
+13 −22
Original line number Diff line number Diff line
@@ -68,8 +68,7 @@ static int print_entries;

static int			target_pid			=     -1;
static int			target_tid			=     -1;
static pid_t			*all_tids			=      NULL;
static int			thread_num			=      0;
static struct thread_map	*threads;
static bool			inherit				=  false;
static struct cpu_map		*cpus;
static int			realtime_prio			=      0;
@@ -1200,7 +1199,7 @@ static void perf_session__mmap_read(struct perf_session *self)
	for (i = 0; i < cpus->nr; i++) {
		list_for_each_entry(counter, &evsel_list, node) {
			for (thread_index = 0;
				thread_index < thread_num;
				thread_index < threads->nr;
				thread_index++) {
				perf_session__mmap_read_counter(self,
					counter, i, thread_index);
@@ -1236,10 +1235,10 @@ static void start_counter(int i, struct perf_evsel *evsel)
	attr->inherit		= (cpu < 0) && inherit;
	attr->mmap		= 1;

	for (thread_index = 0; thread_index < thread_num; thread_index++) {
	for (thread_index = 0; thread_index < threads->nr; thread_index++) {
try_again:
		FD(evsel, i, thread_index) = sys_perf_event_open(attr,
				all_tids[thread_index], cpu, group_fd, 0);
				threads->map[thread_index], cpu, group_fd, 0);

		if (FD(evsel, i, thread_index) < 0) {
			int err = errno;
@@ -1410,25 +1409,17 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
	if (argc)
		usage_with_options(top_usage, options);

	if (target_pid != -1) {
	if (target_pid != -1)
		target_tid = target_pid;
		thread_num = find_all_tid(target_pid, &all_tids);
		if (thread_num <= 0) {
			fprintf(stderr, "Can't find all threads of pid %d\n",
				target_pid);
			usage_with_options(top_usage, options);
		}
	} else {
		all_tids=malloc(sizeof(pid_t));
		if (!all_tids)
			return -ENOMEM;

		all_tids[0] = target_tid;
		thread_num = 1;
	threads = thread_map__new(target_pid, target_tid);
	if (threads == NULL) {
		pr_err("Problems finding threads of monitor\n");
		usage_with_options(top_usage, options);
	}

	event_array = malloc(
		sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
	event_array = malloc((sizeof(struct pollfd) *
			      MAX_NR_CPUS * MAX_COUNTERS * threads->nr));
	if (!event_array)
		return -ENOMEM;

@@ -1468,8 +1459,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
		usage_with_options(top_usage, options);

	list_for_each_entry(pos, &evsel_list, node) {
		if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, thread_num) < 0 ||
		    perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0)
		if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 ||
		    perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
			goto out_free_fd;
		/*
		 * Fill in the ones not specifically initialized via -c:
+29 −14
Original line number Diff line number Diff line
@@ -16,35 +16,50 @@ static int filter(const struct dirent *dir)
		return 1;
}

int find_all_tid(int pid, pid_t ** all_tid)
struct thread_map *thread_map__new_by_pid(pid_t pid)
{
	struct thread_map *threads;
	char name[256];
	int items;
	struct dirent **namelist = NULL;
	int ret = 0;
	int i;

	sprintf(name, "/proc/%d/task", pid);
	items = scandir(name, &namelist, filter, NULL);
	if (items <= 0)
                return -ENOENT;
	*all_tid = malloc(sizeof(pid_t) * items);
	if (!*all_tid) {
		ret = -ENOMEM;
		goto failure;
	}
                return NULL;

	threads = malloc(sizeof(*threads) + sizeof(pid_t) * items);
	if (threads != NULL) {
		for (i = 0; i < items; i++)
		(*all_tid)[i] = atoi(namelist[i]->d_name);

	ret = items;
			threads->map[i] = atoi(namelist[i]->d_name);
		threads->nr = items;
	}

failure:
	for (i=0; i<items; i++)
		free(namelist[i]);
	free(namelist);

	return ret;
	return threads;
}

struct thread_map *thread_map__new_by_tid(pid_t tid)
{
	struct thread_map *threads = malloc(sizeof(*threads) + sizeof(pid_t));

	if (threads != NULL) {
		threads->map[0] = tid;
		threads->nr	= 1;
	}

	return threads;
}

struct thread_map *thread_map__new(pid_t pid, pid_t tid)
{
	if (pid != -1)
		return thread_map__new_by_pid(pid);
	return thread_map__new_by_tid(tid);
}

static struct thread *thread__new(pid_t pid)
+14 −1
Original line number Diff line number Diff line
@@ -18,11 +18,24 @@ struct thread {
	int			comm_len;
};

struct thread_map {
	int nr;
	int map[];
};

struct perf_session;

void thread__delete(struct thread *self);

int find_all_tid(int pid, pid_t ** all_tid);
struct thread_map *thread_map__new_by_pid(pid_t pid);
struct thread_map *thread_map__new_by_tid(pid_t tid);
struct thread_map *thread_map__new(pid_t pid, pid_t tid);

static inline void thread_map__delete(struct thread_map *threads)
{
	free(threads);
}

int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);