perf evlist: Rename for_each() macros to for_each_entry()
[deliverable/linux.git] / tools / perf / util / evlist.c
index c4bfe11479a0e0d7559ff941c63e96557400bce4..113507716044a31a697214e6dce35b46452911fa 100644 (file)
@@ -44,6 +44,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
        perf_evlist__set_maps(evlist, cpus, threads);
        fdarray__init(&evlist->pollfd, 64);
        evlist->workload.pid = -1;
+       evlist->backward = false;
 }
 
 struct perf_evlist *perf_evlist__new(void)
@@ -99,7 +100,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                perf_evsel__calc_id_pos(evsel);
 
        perf_evlist__set_id_pos(evlist);
@@ -109,7 +110,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
 {
        struct perf_evsel *pos, *n;
 
-       evlist__for_each_safe(evlist, n, pos) {
+       evlist__for_each_entry_safe(evlist, n, pos) {
                list_del_init(&pos->node);
                pos->evlist = NULL;
                perf_evsel__delete(pos);
@@ -126,6 +127,9 @@ void perf_evlist__exit(struct perf_evlist *evlist)
 
 void perf_evlist__delete(struct perf_evlist *evlist)
 {
+       if (evlist == NULL)
+               return;
+
        perf_evlist__munmap(evlist);
        perf_evlist__close(evlist);
        cpu_map__put(evlist->cpus);
@@ -160,7 +164,7 @@ static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                __perf_evlist__propagate_maps(evlist, evsel);
 }
 
@@ -189,7 +193,7 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
 {
        struct perf_evsel *evsel, *temp;
 
-       __evlist__for_each_safe(list, temp, evsel) {
+       __evlist__for_each_entry_safe(list, temp, evsel) {
                list_del_init(&evsel->node);
                perf_evlist__add(evlist, evsel);
        }
@@ -204,7 +208,7 @@ void __perf_evlist__set_leader(struct list_head *list)
 
        leader->nr_members = evsel->idx - leader->idx + 1;
 
-       __evlist__for_each(list, evsel) {
+       __evlist__for_each_entry(list, evsel) {
                evsel->leader = leader;
        }
 }
@@ -295,7 +299,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
        return 0;
 
 out_delete_partial_list:
-       __evlist__for_each_safe(&head, n, evsel)
+       __evlist__for_each_entry_safe(&head, n, evsel)
                perf_evsel__delete(evsel);
        return -1;
 }
@@ -316,7 +320,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (evsel->attr.type   == PERF_TYPE_TRACEPOINT &&
                    (int)evsel->attr.config == id)
                        return evsel;
@@ -331,7 +335,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
                    (strcmp(evsel->name, name) == 0))
                        return evsel;
@@ -366,7 +370,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
 {
        struct perf_evsel *pos;
 
-       evlist__for_each(evlist, pos) {
+       evlist__for_each_entry(evlist, pos) {
                if (!perf_evsel__is_group_leader(pos) || !pos->fd)
                        continue;
                perf_evsel__disable(pos);
@@ -379,7 +383,7 @@ void perf_evlist__enable(struct perf_evlist *evlist)
 {
        struct perf_evsel *pos;
 
-       evlist__for_each(evlist, pos) {
+       evlist__for_each_entry(evlist, pos) {
                if (!perf_evsel__is_group_leader(pos) || !pos->fd)
                        continue;
                perf_evsel__enable(pos);
@@ -447,7 +451,7 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
        int nfds = 0;
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (evsel->system_wide)
                        nfds += nr_cpus;
                else
@@ -461,9 +465,9 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
        return 0;
 }
 
-static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx)
+static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx, short revent)
 {
-       int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP);
+       int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP);
        /*
         * Save the idx so that when we filter out fds POLLHUP'ed we can
         * close the associated evlist->mmap[] entry.
@@ -479,10 +483,11 @@ static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx
 
 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
 {
-       return __perf_evlist__add_pollfd(evlist, fd, -1);
+       return __perf_evlist__add_pollfd(evlist, fd, -1, POLLIN);
 }
 
-static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd)
+static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
+                                        void *arg __maybe_unused)
 {
        struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd);
 
@@ -492,7 +497,7 @@ static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd)
 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
 {
        return fdarray__filter(&evlist->pollfd, revents_and_mask,
-                              perf_evlist__munmap_filtered);
+                              perf_evlist__munmap_filtered, NULL);
 }
 
 int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
@@ -679,6 +684,33 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
        return NULL;
 }
 
+static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value)
+{
+       int i;
+
+       for (i = 0; i < evlist->nr_mmaps; i++) {
+               int fd = evlist->mmap[i].fd;
+               int err;
+
+               if (fd < 0)
+                       continue;
+               err = ioctl(fd, PERF_EVENT_IOC_PAUSE_OUTPUT, value ? 1 : 0);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+int perf_evlist__pause(struct perf_evlist *evlist)
+{
+       return perf_evlist__set_paused(evlist, true);
+}
+
+int perf_evlist__resume(struct perf_evlist *evlist)
+{
+       return perf_evlist__set_paused(evlist, false);
+}
+
 /* When check_messup is true, 'end' must points to a good entry */
 static union perf_event *
 perf_mmap__read(struct perf_mmap *md, bool check_messup, u64 start,
@@ -749,7 +781,7 @@ broken_event:
        return event;
 }
 
-union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
+union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx)
 {
        struct perf_mmap *md = &evlist->mmap[idx];
        u64 head;
@@ -804,6 +836,13 @@ perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
        return perf_mmap__read(md, false, start, end, &md->prev);
 }
 
+union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
+{
+       if (!evlist->backward)
+               return perf_evlist__mmap_read_forward(evlist, idx);
+       return perf_evlist__mmap_read_backward(evlist, idx);
+}
+
 void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
 {
        struct perf_mmap *md = &evlist->mmap[idx];
@@ -828,9 +867,11 @@ static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
 
 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx)
 {
-       BUG_ON(atomic_read(&evlist->mmap[idx].refcnt) == 0);
+       struct perf_mmap *md = &evlist->mmap[idx];
 
-       if (atomic_dec_and_test(&evlist->mmap[idx].refcnt))
+       BUG_ON(md->base && atomic_read(&md->refcnt) == 0);
+
+       if (atomic_dec_and_test(&md->refcnt))
                __perf_evlist__munmap(evlist, idx);
 }
 
@@ -881,6 +922,7 @@ static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
        if (evlist->mmap[idx].base != NULL) {
                munmap(evlist->mmap[idx].base, evlist->mmap_len);
                evlist->mmap[idx].base = NULL;
+               evlist->mmap[idx].fd = -1;
                atomic_set(&evlist->mmap[idx].refcnt, 0);
        }
        auxtrace_mmap__munmap(&evlist->mmap[idx].auxtrace_mmap);
@@ -901,11 +943,18 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
 
 static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
 {
+       int i;
+
        evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
        if (cpu_map__empty(evlist->cpus))
                evlist->nr_mmaps = thread_map__nr(evlist->threads);
        evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
-       return evlist->mmap != NULL ? 0 : -ENOMEM;
+       if (!evlist->mmap)
+               return -ENOMEM;
+
+       for (i = 0; i < evlist->nr_mmaps; i++)
+               evlist->mmap[i].fd = -1;
+       return 0;
 }
 
 struct mmap_params {
@@ -941,6 +990,7 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
                evlist->mmap[idx].base = NULL;
                return -1;
        }
+       evlist->mmap[idx].fd = fd;
 
        if (auxtrace_mmap__mmap(&evlist->mmap[idx].auxtrace_mmap,
                                &mp->auxtrace_mp, evlist->mmap[idx].base, fd))
@@ -949,15 +999,28 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
        return 0;
 }
 
+static bool
+perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused,
+                        struct perf_evsel *evsel)
+{
+       if (evsel->overwrite)
+               return false;
+       return true;
+}
+
 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
                                       struct mmap_params *mp, int cpu,
                                       int thread, int *output)
 {
        struct perf_evsel *evsel;
+       int revent;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                int fd;
 
+               if (evsel->overwrite != (evlist->overwrite && evlist->backward))
+                       continue;
+
                if (evsel->system_wide && thread)
                        continue;
 
@@ -974,6 +1037,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
                        perf_evlist__mmap_get(evlist, idx);
                }
 
+               revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0;
+
                /*
                 * The system_wide flag causes a selected event to be opened
                 * always without a pid.  Consequently it will never get a
@@ -982,7 +1047,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
                 * Therefore don't add it for polling.
                 */
                if (!evsel->system_wide &&
-                   __perf_evlist__add_pollfd(evlist, fd, idx) < 0) {
+                   __perf_evlist__add_pollfd(evlist, fd, idx, revent) < 0) {
                        perf_evlist__mmap_put(evlist, idx);
                        return -1;
                }
@@ -1197,7 +1262,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
        auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len,
                                   auxtrace_pages, auxtrace_overwrite);
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
                    evsel->sample_id == NULL &&
                    perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
@@ -1273,7 +1338,7 @@ void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                __perf_evsel__set_sample_bit(evsel, bit);
 }
 
@@ -1282,7 +1347,7 @@ void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                __perf_evsel__reset_sample_bit(evsel, bit);
 }
 
@@ -1293,7 +1358,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
        const int ncpus = cpu_map__nr(evlist->cpus),
                  nthreads = thread_map__nr(evlist->threads);
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (evsel->filter == NULL)
                        continue;
 
@@ -1316,7 +1381,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
        struct perf_evsel *evsel;
        int err = 0;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
                        continue;
 
@@ -1370,7 +1435,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
        if (evlist->id_pos < 0 || evlist->is_pos < 0)
                return false;
 
-       evlist__for_each(evlist, pos) {
+       evlist__for_each_entry(evlist, pos) {
                if (pos->id_pos != evlist->id_pos ||
                    pos->is_pos != evlist->is_pos)
                        return false;
@@ -1386,7 +1451,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
        if (evlist->combined_sample_type)
                return evlist->combined_sample_type;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                evlist->combined_sample_type |= evsel->attr.sample_type;
 
        return evlist->combined_sample_type;
@@ -1403,7 +1468,7 @@ u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist)
        struct perf_evsel *evsel;
        u64 branch_type = 0;
 
-       evlist__for_each(evlist, evsel)
+       evlist__for_each_entry(evlist, evsel)
                branch_type |= evsel->attr.branch_sample_type;
        return branch_type;
 }
@@ -1414,7 +1479,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
        u64 read_format = first->attr.read_format;
        u64 sample_type = first->attr.sample_type;
 
-       evlist__for_each(evlist, pos) {
+       evlist__for_each_entry(evlist, pos) {
                if (read_format != pos->attr.read_format)
                        return false;
        }
@@ -1471,7 +1536,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
 {
        struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
 
-       evlist__for_each_continue(evlist, pos) {
+       evlist__for_each_entry_continue(evlist, pos) {
                if (first->attr.sample_id_all != pos->attr.sample_id_all)
                        return false;
        }
@@ -1498,7 +1563,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
        int nthreads = thread_map__nr(evlist->threads);
        int n;
 
-       evlist__for_each_reverse(evlist, evsel) {
+       evlist__for_each_entry_reverse(evlist, evsel) {
                n = evsel->cpus ? evsel->cpus->nr : ncpus;
                perf_evsel__close(evsel, n, nthreads);
        }
@@ -1552,7 +1617,7 @@ int perf_evlist__open(struct perf_evlist *evlist)
 
        perf_evlist__update_id_pos(evlist);
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
                if (err < 0)
                        goto out_err;
@@ -1713,7 +1778,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
        struct perf_evsel *evsel;
        size_t printed = 0;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
                                   perf_evsel__name(evsel));
        }
@@ -1815,7 +1880,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
        if (move_evsel == perf_evlist__first(evlist))
                return;
 
-       evlist__for_each_safe(evlist, n, evsel) {
+       evlist__for_each_entry_safe(evlist, n, evsel) {
                if (evsel->leader == move_evsel->leader)
                        list_move_tail(&evsel->node, &move);
        }
@@ -1831,7 +1896,7 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
        if (tracking_evsel->tracking)
                return;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (evsel != tracking_evsel)
                        evsel->tracking = false;
        }
@@ -1845,7 +1910,7 @@ perf_evlist__find_evsel_by_str(struct perf_evlist *evlist,
 {
        struct perf_evsel *evsel;
 
-       evlist__for_each(evlist, evsel) {
+       evlist__for_each_entry(evlist, evsel) {
                if (!evsel->name)
                        continue;
                if (strcmp(str, evsel->name) == 0)
This page took 0.033031 seconds and 5 git commands to generate.