1fd78260bSArnaldo Carvalho de Melo #include <dirent.h> 20d37aa34SArnaldo Carvalho de Melo #include <limits.h> 30d37aa34SArnaldo Carvalho de Melo #include <stdbool.h> 4fd78260bSArnaldo Carvalho de Melo #include <stdlib.h> 5fd78260bSArnaldo Carvalho de Melo #include <stdio.h> 60d37aa34SArnaldo Carvalho de Melo #include <sys/types.h> 70d37aa34SArnaldo Carvalho de Melo #include <sys/stat.h> 80d37aa34SArnaldo Carvalho de Melo #include <unistd.h> 9b52956c9SDavid Ahern #include "strlist.h" 10b52956c9SDavid Ahern #include <string.h> 11792402fdSJiri Olsa #include <api/fs/fs.h> 12186fbb74SJiri Olsa #include "asm/bug.h" 13fd78260bSArnaldo Carvalho de Melo #include "thread_map.h" 1404662523SArnaldo Carvalho de Melo #include "util.h" 15792402fdSJiri Olsa #include "debug.h" 16fd78260bSArnaldo Carvalho de Melo 17fd78260bSArnaldo Carvalho de Melo /* Skip "." and ".." directories */ 18fd78260bSArnaldo Carvalho de Melo static int filter(const struct dirent *dir) 19fd78260bSArnaldo Carvalho de Melo { 20fd78260bSArnaldo Carvalho de Melo if (dir->d_name[0] == '.') 21fd78260bSArnaldo Carvalho de Melo return 0; 22fd78260bSArnaldo Carvalho de Melo else 23fd78260bSArnaldo Carvalho de Melo return 1; 24fd78260bSArnaldo Carvalho de Melo } 25fd78260bSArnaldo Carvalho de Melo 2662eea464SJiri Olsa static void thread_map__reset(struct thread_map *map, int start, int nr) 2762eea464SJiri Olsa { 2862eea464SJiri Olsa size_t size = (nr - start) * sizeof(map->map[0]); 2962eea464SJiri Olsa 3062eea464SJiri Olsa memset(&map->map[start], 0, size); 3162eea464SJiri Olsa } 3262eea464SJiri Olsa 339d7e8c3aSJiri Olsa static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) 349d7e8c3aSJiri Olsa { 35060664f3SArnaldo Carvalho de Melo size_t size = sizeof(*map) + sizeof(map->map[0]) * nr; 3662eea464SJiri Olsa int start = map ? map->nr : 0; 379d7e8c3aSJiri Olsa 3862eea464SJiri Olsa map = realloc(map, size); 3962eea464SJiri Olsa /* 4062eea464SJiri Olsa * We only realloc to add more items, let's reset new items. 4162eea464SJiri Olsa */ 4262eea464SJiri Olsa if (map) 4362eea464SJiri Olsa thread_map__reset(map, start, nr); 4462eea464SJiri Olsa 4562eea464SJiri Olsa return map; 469d7e8c3aSJiri Olsa } 479d7e8c3aSJiri Olsa 489d7e8c3aSJiri Olsa #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr) 499d7e8c3aSJiri Olsa 50fd78260bSArnaldo Carvalho de Melo struct thread_map *thread_map__new_by_pid(pid_t pid) 51fd78260bSArnaldo Carvalho de Melo { 52fd78260bSArnaldo Carvalho de Melo struct thread_map *threads; 53fd78260bSArnaldo Carvalho de Melo char name[256]; 54fd78260bSArnaldo Carvalho de Melo int items; 55fd78260bSArnaldo Carvalho de Melo struct dirent **namelist = NULL; 56fd78260bSArnaldo Carvalho de Melo int i; 57fd78260bSArnaldo Carvalho de Melo 58fd78260bSArnaldo Carvalho de Melo sprintf(name, "/proc/%d/task", pid); 59fd78260bSArnaldo Carvalho de Melo items = scandir(name, &namelist, filter, NULL); 60fd78260bSArnaldo Carvalho de Melo if (items <= 0) 61fd78260bSArnaldo Carvalho de Melo return NULL; 62fd78260bSArnaldo Carvalho de Melo 639d7e8c3aSJiri Olsa threads = thread_map__alloc(items); 64fd78260bSArnaldo Carvalho de Melo if (threads != NULL) { 65fd78260bSArnaldo Carvalho de Melo for (i = 0; i < items; i++) 66e13798c7SJiri Olsa thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); 67fd78260bSArnaldo Carvalho de Melo threads->nr = items; 68186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 69fd78260bSArnaldo Carvalho de Melo } 70fd78260bSArnaldo Carvalho de Melo 71fd78260bSArnaldo Carvalho de Melo for (i=0; i<items; i++) 7274cf249dSArnaldo Carvalho de Melo zfree(&namelist[i]); 73fd78260bSArnaldo Carvalho de Melo free(namelist); 74fd78260bSArnaldo Carvalho de Melo 75fd78260bSArnaldo Carvalho de Melo return threads; 76fd78260bSArnaldo Carvalho de Melo } 77fd78260bSArnaldo Carvalho de Melo 78fd78260bSArnaldo Carvalho de Melo struct thread_map *thread_map__new_by_tid(pid_t tid) 79fd78260bSArnaldo Carvalho de Melo { 809d7e8c3aSJiri Olsa struct thread_map *threads = thread_map__alloc(1); 81fd78260bSArnaldo Carvalho de Melo 82fd78260bSArnaldo Carvalho de Melo if (threads != NULL) { 83e13798c7SJiri Olsa thread_map__set_pid(threads, 0, tid); 84fd78260bSArnaldo Carvalho de Melo threads->nr = 1; 85186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 86fd78260bSArnaldo Carvalho de Melo } 87fd78260bSArnaldo Carvalho de Melo 88fd78260bSArnaldo Carvalho de Melo return threads; 89fd78260bSArnaldo Carvalho de Melo } 90fd78260bSArnaldo Carvalho de Melo 910d37aa34SArnaldo Carvalho de Melo struct thread_map *thread_map__new_by_uid(uid_t uid) 920d37aa34SArnaldo Carvalho de Melo { 930d37aa34SArnaldo Carvalho de Melo DIR *proc; 940d37aa34SArnaldo Carvalho de Melo int max_threads = 32, items, i; 950d37aa34SArnaldo Carvalho de Melo char path[256]; 960d37aa34SArnaldo Carvalho de Melo struct dirent dirent, *next, **namelist = NULL; 979d7e8c3aSJiri Olsa struct thread_map *threads = thread_map__alloc(max_threads); 989d7e8c3aSJiri Olsa 990d37aa34SArnaldo Carvalho de Melo if (threads == NULL) 1000d37aa34SArnaldo Carvalho de Melo goto out; 1010d37aa34SArnaldo Carvalho de Melo 1020d37aa34SArnaldo Carvalho de Melo proc = opendir("/proc"); 1030d37aa34SArnaldo Carvalho de Melo if (proc == NULL) 1040d37aa34SArnaldo Carvalho de Melo goto out_free_threads; 1050d37aa34SArnaldo Carvalho de Melo 1060d37aa34SArnaldo Carvalho de Melo threads->nr = 0; 107186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 1080d37aa34SArnaldo Carvalho de Melo 1090d37aa34SArnaldo Carvalho de Melo while (!readdir_r(proc, &dirent, &next) && next) { 1100d37aa34SArnaldo Carvalho de Melo char *end; 1110d37aa34SArnaldo Carvalho de Melo bool grow = false; 1120d37aa34SArnaldo Carvalho de Melo struct stat st; 1130d37aa34SArnaldo Carvalho de Melo pid_t pid = strtol(dirent.d_name, &end, 10); 1140d37aa34SArnaldo Carvalho de Melo 1150d37aa34SArnaldo Carvalho de Melo if (*end) /* only interested in proper numerical dirents */ 1160d37aa34SArnaldo Carvalho de Melo continue; 1170d37aa34SArnaldo Carvalho de Melo 1180d37aa34SArnaldo Carvalho de Melo snprintf(path, sizeof(path), "/proc/%s", dirent.d_name); 1190d37aa34SArnaldo Carvalho de Melo 1200d37aa34SArnaldo Carvalho de Melo if (stat(path, &st) != 0) 1210d37aa34SArnaldo Carvalho de Melo continue; 1220d37aa34SArnaldo Carvalho de Melo 1230d37aa34SArnaldo Carvalho de Melo if (st.st_uid != uid) 1240d37aa34SArnaldo Carvalho de Melo continue; 1250d37aa34SArnaldo Carvalho de Melo 1260d37aa34SArnaldo Carvalho de Melo snprintf(path, sizeof(path), "/proc/%d/task", pid); 1270d37aa34SArnaldo Carvalho de Melo items = scandir(path, &namelist, filter, NULL); 1280d37aa34SArnaldo Carvalho de Melo if (items <= 0) 1290d37aa34SArnaldo Carvalho de Melo goto out_free_closedir; 1300d37aa34SArnaldo Carvalho de Melo 1310d37aa34SArnaldo Carvalho de Melo while (threads->nr + items >= max_threads) { 1320d37aa34SArnaldo Carvalho de Melo max_threads *= 2; 1330d37aa34SArnaldo Carvalho de Melo grow = true; 1340d37aa34SArnaldo Carvalho de Melo } 1350d37aa34SArnaldo Carvalho de Melo 1360d37aa34SArnaldo Carvalho de Melo if (grow) { 1370d37aa34SArnaldo Carvalho de Melo struct thread_map *tmp; 1380d37aa34SArnaldo Carvalho de Melo 1390d37aa34SArnaldo Carvalho de Melo tmp = realloc(threads, (sizeof(*threads) + 1400d37aa34SArnaldo Carvalho de Melo max_threads * sizeof(pid_t))); 1410d37aa34SArnaldo Carvalho de Melo if (tmp == NULL) 1420d37aa34SArnaldo Carvalho de Melo goto out_free_namelist; 1430d37aa34SArnaldo Carvalho de Melo 1440d37aa34SArnaldo Carvalho de Melo threads = tmp; 1450d37aa34SArnaldo Carvalho de Melo } 1460d37aa34SArnaldo Carvalho de Melo 147e13798c7SJiri Olsa for (i = 0; i < items; i++) { 148e13798c7SJiri Olsa thread_map__set_pid(threads, threads->nr + i, 149e13798c7SJiri Olsa atoi(namelist[i]->d_name)); 150e13798c7SJiri Olsa } 1510d37aa34SArnaldo Carvalho de Melo 1520d37aa34SArnaldo Carvalho de Melo for (i = 0; i < items; i++) 15374cf249dSArnaldo Carvalho de Melo zfree(&namelist[i]); 1540d37aa34SArnaldo Carvalho de Melo free(namelist); 1550d37aa34SArnaldo Carvalho de Melo 1560d37aa34SArnaldo Carvalho de Melo threads->nr += items; 1570d37aa34SArnaldo Carvalho de Melo } 1580d37aa34SArnaldo Carvalho de Melo 1590d37aa34SArnaldo Carvalho de Melo out_closedir: 1600d37aa34SArnaldo Carvalho de Melo closedir(proc); 1610d37aa34SArnaldo Carvalho de Melo out: 1620d37aa34SArnaldo Carvalho de Melo return threads; 1630d37aa34SArnaldo Carvalho de Melo 1640d37aa34SArnaldo Carvalho de Melo out_free_threads: 1650d37aa34SArnaldo Carvalho de Melo free(threads); 1660d37aa34SArnaldo Carvalho de Melo return NULL; 1670d37aa34SArnaldo Carvalho de Melo 1680d37aa34SArnaldo Carvalho de Melo out_free_namelist: 1690d37aa34SArnaldo Carvalho de Melo for (i = 0; i < items; i++) 17074cf249dSArnaldo Carvalho de Melo zfree(&namelist[i]); 1710d37aa34SArnaldo Carvalho de Melo free(namelist); 1720d37aa34SArnaldo Carvalho de Melo 1730d37aa34SArnaldo Carvalho de Melo out_free_closedir: 17404662523SArnaldo Carvalho de Melo zfree(&threads); 1750d37aa34SArnaldo Carvalho de Melo goto out_closedir; 1760d37aa34SArnaldo Carvalho de Melo } 1770d37aa34SArnaldo Carvalho de Melo 1780d37aa34SArnaldo Carvalho de Melo struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) 179fd78260bSArnaldo Carvalho de Melo { 180fd78260bSArnaldo Carvalho de Melo if (pid != -1) 181fd78260bSArnaldo Carvalho de Melo return thread_map__new_by_pid(pid); 1820d37aa34SArnaldo Carvalho de Melo 1830d37aa34SArnaldo Carvalho de Melo if (tid == -1 && uid != UINT_MAX) 1840d37aa34SArnaldo Carvalho de Melo return thread_map__new_by_uid(uid); 1850d37aa34SArnaldo Carvalho de Melo 186fd78260bSArnaldo Carvalho de Melo return thread_map__new_by_tid(tid); 187fd78260bSArnaldo Carvalho de Melo } 188fd78260bSArnaldo Carvalho de Melo 189b52956c9SDavid Ahern static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) 190b52956c9SDavid Ahern { 191b52956c9SDavid Ahern struct thread_map *threads = NULL, *nt; 192b52956c9SDavid Ahern char name[256]; 193b52956c9SDavid Ahern int items, total_tasks = 0; 194b52956c9SDavid Ahern struct dirent **namelist = NULL; 195b52956c9SDavid Ahern int i, j = 0; 196b52956c9SDavid Ahern pid_t pid, prev_pid = INT_MAX; 197b52956c9SDavid Ahern char *end_ptr; 198b52956c9SDavid Ahern struct str_node *pos; 199*4a77e218SArnaldo Carvalho de Melo struct strlist_config slist_config = { .dont_dupstr = true, }; 200*4a77e218SArnaldo Carvalho de Melo struct strlist *slist = strlist__new(pid_str, &slist_config); 201b52956c9SDavid Ahern 202b52956c9SDavid Ahern if (!slist) 203b52956c9SDavid Ahern return NULL; 204b52956c9SDavid Ahern 205b52956c9SDavid Ahern strlist__for_each(pos, slist) { 206b52956c9SDavid Ahern pid = strtol(pos->s, &end_ptr, 10); 207b52956c9SDavid Ahern 208b52956c9SDavid Ahern if (pid == INT_MIN || pid == INT_MAX || 209b52956c9SDavid Ahern (*end_ptr != '\0' && *end_ptr != ',')) 210b52956c9SDavid Ahern goto out_free_threads; 211b52956c9SDavid Ahern 212b52956c9SDavid Ahern if (pid == prev_pid) 213b52956c9SDavid Ahern continue; 214b52956c9SDavid Ahern 215b52956c9SDavid Ahern sprintf(name, "/proc/%d/task", pid); 216b52956c9SDavid Ahern items = scandir(name, &namelist, filter, NULL); 217b52956c9SDavid Ahern if (items <= 0) 218b52956c9SDavid Ahern goto out_free_threads; 219b52956c9SDavid Ahern 220b52956c9SDavid Ahern total_tasks += items; 2219d7e8c3aSJiri Olsa nt = thread_map__realloc(threads, total_tasks); 222b52956c9SDavid Ahern if (nt == NULL) 223e8cdd947SFranck Bui-Huu goto out_free_namelist; 224b52956c9SDavid Ahern 225b52956c9SDavid Ahern threads = nt; 226b52956c9SDavid Ahern 227e8cdd947SFranck Bui-Huu for (i = 0; i < items; i++) { 228e13798c7SJiri Olsa thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); 22974cf249dSArnaldo Carvalho de Melo zfree(&namelist[i]); 230e8cdd947SFranck Bui-Huu } 231e8cdd947SFranck Bui-Huu threads->nr = total_tasks; 232b52956c9SDavid Ahern free(namelist); 233b52956c9SDavid Ahern } 234b52956c9SDavid Ahern 235b52956c9SDavid Ahern out: 236b52956c9SDavid Ahern strlist__delete(slist); 237186fbb74SJiri Olsa if (threads) 238186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 239b52956c9SDavid Ahern return threads; 240b52956c9SDavid Ahern 241e8cdd947SFranck Bui-Huu out_free_namelist: 242e8cdd947SFranck Bui-Huu for (i = 0; i < items; i++) 24374cf249dSArnaldo Carvalho de Melo zfree(&namelist[i]); 244e8cdd947SFranck Bui-Huu free(namelist); 245e8cdd947SFranck Bui-Huu 246b52956c9SDavid Ahern out_free_threads: 24704662523SArnaldo Carvalho de Melo zfree(&threads); 248b52956c9SDavid Ahern goto out; 249b52956c9SDavid Ahern } 250b52956c9SDavid Ahern 251641556c9SArnaldo Carvalho de Melo struct thread_map *thread_map__new_dummy(void) 252641556c9SArnaldo Carvalho de Melo { 2539d7e8c3aSJiri Olsa struct thread_map *threads = thread_map__alloc(1); 254641556c9SArnaldo Carvalho de Melo 255641556c9SArnaldo Carvalho de Melo if (threads != NULL) { 256e13798c7SJiri Olsa thread_map__set_pid(threads, 0, -1); 257641556c9SArnaldo Carvalho de Melo threads->nr = 1; 258186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 259641556c9SArnaldo Carvalho de Melo } 260641556c9SArnaldo Carvalho de Melo return threads; 261641556c9SArnaldo Carvalho de Melo } 262641556c9SArnaldo Carvalho de Melo 263b52956c9SDavid Ahern static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) 264b52956c9SDavid Ahern { 265b52956c9SDavid Ahern struct thread_map *threads = NULL, *nt; 266b52956c9SDavid Ahern int ntasks = 0; 267b52956c9SDavid Ahern pid_t tid, prev_tid = INT_MAX; 268b52956c9SDavid Ahern char *end_ptr; 269b52956c9SDavid Ahern struct str_node *pos; 270*4a77e218SArnaldo Carvalho de Melo struct strlist_config slist_config = { .dont_dupstr = true, }; 271b52956c9SDavid Ahern struct strlist *slist; 272b52956c9SDavid Ahern 273b52956c9SDavid Ahern /* perf-stat expects threads to be generated even if tid not given */ 274641556c9SArnaldo Carvalho de Melo if (!tid_str) 275641556c9SArnaldo Carvalho de Melo return thread_map__new_dummy(); 276b52956c9SDavid Ahern 277*4a77e218SArnaldo Carvalho de Melo slist = strlist__new(tid_str, &slist_config); 278b52956c9SDavid Ahern if (!slist) 279b52956c9SDavid Ahern return NULL; 280b52956c9SDavid Ahern 281b52956c9SDavid Ahern strlist__for_each(pos, slist) { 282b52956c9SDavid Ahern tid = strtol(pos->s, &end_ptr, 10); 283b52956c9SDavid Ahern 284b52956c9SDavid Ahern if (tid == INT_MIN || tid == INT_MAX || 285b52956c9SDavid Ahern (*end_ptr != '\0' && *end_ptr != ',')) 286b52956c9SDavid Ahern goto out_free_threads; 287b52956c9SDavid Ahern 288b52956c9SDavid Ahern if (tid == prev_tid) 289b52956c9SDavid Ahern continue; 290b52956c9SDavid Ahern 291b52956c9SDavid Ahern ntasks++; 2929d7e8c3aSJiri Olsa nt = thread_map__realloc(threads, ntasks); 293b52956c9SDavid Ahern 294b52956c9SDavid Ahern if (nt == NULL) 295b52956c9SDavid Ahern goto out_free_threads; 296b52956c9SDavid Ahern 297b52956c9SDavid Ahern threads = nt; 298e13798c7SJiri Olsa thread_map__set_pid(threads, ntasks - 1, tid); 299b52956c9SDavid Ahern threads->nr = ntasks; 300b52956c9SDavid Ahern } 301b52956c9SDavid Ahern out: 302186fbb74SJiri Olsa if (threads) 303186fbb74SJiri Olsa atomic_set(&threads->refcnt, 1); 304b52956c9SDavid Ahern return threads; 305b52956c9SDavid Ahern 306b52956c9SDavid Ahern out_free_threads: 30704662523SArnaldo Carvalho de Melo zfree(&threads); 308b52956c9SDavid Ahern goto out; 309b52956c9SDavid Ahern } 310b52956c9SDavid Ahern 311b52956c9SDavid Ahern struct thread_map *thread_map__new_str(const char *pid, const char *tid, 312b52956c9SDavid Ahern uid_t uid) 313b52956c9SDavid Ahern { 314b52956c9SDavid Ahern if (pid) 315b52956c9SDavid Ahern return thread_map__new_by_pid_str(pid); 316b52956c9SDavid Ahern 317b52956c9SDavid Ahern if (!tid && uid != UINT_MAX) 318b52956c9SDavid Ahern return thread_map__new_by_uid(uid); 319b52956c9SDavid Ahern 320b52956c9SDavid Ahern return thread_map__new_by_tid_str(tid); 321b52956c9SDavid Ahern } 322b52956c9SDavid Ahern 323186fbb74SJiri Olsa static void thread_map__delete(struct thread_map *threads) 324fd78260bSArnaldo Carvalho de Melo { 325186fbb74SJiri Olsa if (threads) { 326792402fdSJiri Olsa int i; 327792402fdSJiri Olsa 328186fbb74SJiri Olsa WARN_ONCE(atomic_read(&threads->refcnt) != 0, 329186fbb74SJiri Olsa "thread map refcnt unbalanced\n"); 330792402fdSJiri Olsa for (i = 0; i < threads->nr; i++) 331792402fdSJiri Olsa free(thread_map__comm(threads, i)); 332fd78260bSArnaldo Carvalho de Melo free(threads); 333fd78260bSArnaldo Carvalho de Melo } 334186fbb74SJiri Olsa } 335186fbb74SJiri Olsa 336186fbb74SJiri Olsa struct thread_map *thread_map__get(struct thread_map *map) 337186fbb74SJiri Olsa { 338186fbb74SJiri Olsa if (map) 339186fbb74SJiri Olsa atomic_inc(&map->refcnt); 340186fbb74SJiri Olsa return map; 341186fbb74SJiri Olsa } 342186fbb74SJiri Olsa 343186fbb74SJiri Olsa void thread_map__put(struct thread_map *map) 344186fbb74SJiri Olsa { 345186fbb74SJiri Olsa if (map && atomic_dec_and_test(&map->refcnt)) 346186fbb74SJiri Olsa thread_map__delete(map); 347186fbb74SJiri Olsa } 3489ae7d335SArnaldo Carvalho de Melo 3499ae7d335SArnaldo Carvalho de Melo size_t thread_map__fprintf(struct thread_map *threads, FILE *fp) 3509ae7d335SArnaldo Carvalho de Melo { 3519ae7d335SArnaldo Carvalho de Melo int i; 3529ae7d335SArnaldo Carvalho de Melo size_t printed = fprintf(fp, "%d thread%s: ", 3539ae7d335SArnaldo Carvalho de Melo threads->nr, threads->nr > 1 ? "s" : ""); 3549ae7d335SArnaldo Carvalho de Melo for (i = 0; i < threads->nr; ++i) 355e13798c7SJiri Olsa printed += fprintf(fp, "%s%d", i ? ", " : "", thread_map__pid(threads, i)); 3569ae7d335SArnaldo Carvalho de Melo 3579ae7d335SArnaldo Carvalho de Melo return printed + fprintf(fp, "\n"); 3589ae7d335SArnaldo Carvalho de Melo } 359792402fdSJiri Olsa 360792402fdSJiri Olsa static int get_comm(char **comm, pid_t pid) 361792402fdSJiri Olsa { 362792402fdSJiri Olsa char *path; 363792402fdSJiri Olsa size_t size; 364792402fdSJiri Olsa int err; 365792402fdSJiri Olsa 366792402fdSJiri Olsa if (asprintf(&path, "%s/%d/comm", procfs__mountpoint(), pid) == -1) 367792402fdSJiri Olsa return -ENOMEM; 368792402fdSJiri Olsa 369792402fdSJiri Olsa err = filename__read_str(path, comm, &size); 370792402fdSJiri Olsa if (!err) { 371792402fdSJiri Olsa /* 372792402fdSJiri Olsa * We're reading 16 bytes, while filename__read_str 373792402fdSJiri Olsa * allocates data per BUFSIZ bytes, so we can safely 374792402fdSJiri Olsa * mark the end of the string. 375792402fdSJiri Olsa */ 376792402fdSJiri Olsa (*comm)[size] = 0; 377792402fdSJiri Olsa rtrim(*comm); 378792402fdSJiri Olsa } 379792402fdSJiri Olsa 380792402fdSJiri Olsa free(path); 381792402fdSJiri Olsa return err; 382792402fdSJiri Olsa } 383792402fdSJiri Olsa 384792402fdSJiri Olsa static void comm_init(struct thread_map *map, int i) 385792402fdSJiri Olsa { 386792402fdSJiri Olsa pid_t pid = thread_map__pid(map, i); 387792402fdSJiri Olsa char *comm = NULL; 388792402fdSJiri Olsa 389792402fdSJiri Olsa /* dummy pid comm initialization */ 390792402fdSJiri Olsa if (pid == -1) { 391792402fdSJiri Olsa map->map[i].comm = strdup("dummy"); 392792402fdSJiri Olsa return; 393792402fdSJiri Olsa } 394792402fdSJiri Olsa 395792402fdSJiri Olsa /* 396792402fdSJiri Olsa * The comm name is like extra bonus ;-), 397792402fdSJiri Olsa * so just warn if we fail for any reason. 398792402fdSJiri Olsa */ 399792402fdSJiri Olsa if (get_comm(&comm, pid)) 400792402fdSJiri Olsa pr_warning("Couldn't resolve comm name for pid %d\n", pid); 401792402fdSJiri Olsa 402792402fdSJiri Olsa map->map[i].comm = comm; 403792402fdSJiri Olsa } 404792402fdSJiri Olsa 405792402fdSJiri Olsa void thread_map__read_comms(struct thread_map *threads) 406792402fdSJiri Olsa { 407792402fdSJiri Olsa int i; 408792402fdSJiri Olsa 409792402fdSJiri Olsa for (i = 0; i < threads->nr; ++i) 410792402fdSJiri Olsa comm_init(threads, i); 411792402fdSJiri Olsa } 412