On Thu, Mar 07, 2019 at 09:58:09AM -0800, Song Liu wrote: SNIP > +static void *perf_evlist__poll_thread(void *arg) > +{ > + struct perf_evlist *evlist = arg; > + int i; > + > + while (!(evlist->thread.done)) { > + perf_evlist__poll(evlist, 1000); > + > + for (i = 0; i < evlist->nr_mmaps; i++) { > + struct perf_mmap *map = &evlist->mmap[i]; > + union perf_event *event; > + > + if (perf_mmap__read_init(map)) > + continue; > + while ((event = perf_mmap__read_event(map)) != NULL) { > + struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event); > + > + if (evsel && evsel->side_band.cb) > + evsel->side_band.cb(event, evsel->side_band.data); > + else > + pr_warning("cannot locate proper evsel for the side band event\n"); > + > + perf_mmap__consume(map); > + } > + perf_mmap__read_done(map); > + } shouldn't you drain the map before leaving? SNIP > +out_delete_evlist: > + perf_evlist__delete(evlist); > + evlist = NULL; > + return -1; > +} > + > +void perf_evlist__stop_sb_thread(struct perf_evlist *evlist) > +{ > + if (!evlist) > + return; > + evlist->thread.done = 1; > + pthread_join(evlist->thread.th, NULL); > + perf_evlist__exit(evlist); > + evlist = NULL; I think the interface is ok, but please let this function undo whatever perf_evlist__start_sb_thread did, so disable and close events and cleanup maps thanks, jirka