| .. | .. |
|---|
| 12 | 12 | #include "strlist.h" |
|---|
| 13 | 13 | #include <string.h> |
|---|
| 14 | 14 | #include <api/fs/fs.h> |
|---|
| 15 | +#include <linux/string.h> |
|---|
| 16 | +#include <linux/zalloc.h> |
|---|
| 15 | 17 | #include "asm/bug.h" |
|---|
| 16 | 18 | #include "thread_map.h" |
|---|
| 17 | | -#include "util.h" |
|---|
| 18 | 19 | #include "debug.h" |
|---|
| 19 | 20 | #include "event.h" |
|---|
| 20 | 21 | |
|---|
| .. | .. |
|---|
| 27 | 28 | return 1; |
|---|
| 28 | 29 | } |
|---|
| 29 | 30 | |
|---|
| 30 | | -static void thread_map__reset(struct thread_map *map, int start, int nr) |
|---|
| 31 | +#define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr) |
|---|
| 32 | + |
|---|
| 33 | +struct perf_thread_map *thread_map__new_by_pid(pid_t pid) |
|---|
| 31 | 34 | { |
|---|
| 32 | | - size_t size = (nr - start) * sizeof(map->map[0]); |
|---|
| 33 | | - |
|---|
| 34 | | - memset(&map->map[start], 0, size); |
|---|
| 35 | | - map->err_thread = -1; |
|---|
| 36 | | -} |
|---|
| 37 | | - |
|---|
| 38 | | -static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) |
|---|
| 39 | | -{ |
|---|
| 40 | | - size_t size = sizeof(*map) + sizeof(map->map[0]) * nr; |
|---|
| 41 | | - int start = map ? map->nr : 0; |
|---|
| 42 | | - |
|---|
| 43 | | - map = realloc(map, size); |
|---|
| 44 | | - /* |
|---|
| 45 | | - * We only realloc to add more items, let's reset new items. |
|---|
| 46 | | - */ |
|---|
| 47 | | - if (map) |
|---|
| 48 | | - thread_map__reset(map, start, nr); |
|---|
| 49 | | - |
|---|
| 50 | | - return map; |
|---|
| 51 | | -} |
|---|
| 52 | | - |
|---|
| 53 | | -#define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr) |
|---|
| 54 | | - |
|---|
| 55 | | -struct thread_map *thread_map__new_by_pid(pid_t pid) |
|---|
| 56 | | -{ |
|---|
| 57 | | - struct thread_map *threads; |
|---|
| 35 | + struct perf_thread_map *threads; |
|---|
| 58 | 36 | char name[256]; |
|---|
| 59 | 37 | int items; |
|---|
| 60 | 38 | struct dirent **namelist = NULL; |
|---|
| .. | .. |
|---|
| 68 | 46 | threads = thread_map__alloc(items); |
|---|
| 69 | 47 | if (threads != NULL) { |
|---|
| 70 | 48 | for (i = 0; i < items; i++) |
|---|
| 71 | | - thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); |
|---|
| 49 | + perf_thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); |
|---|
| 72 | 50 | threads->nr = items; |
|---|
| 73 | 51 | refcount_set(&threads->refcnt, 1); |
|---|
| 74 | 52 | } |
|---|
| .. | .. |
|---|
| 80 | 58 | return threads; |
|---|
| 81 | 59 | } |
|---|
| 82 | 60 | |
|---|
| 83 | | -struct thread_map *thread_map__new_by_tid(pid_t tid) |
|---|
| 61 | +struct perf_thread_map *thread_map__new_by_tid(pid_t tid) |
|---|
| 84 | 62 | { |
|---|
| 85 | | - struct thread_map *threads = thread_map__alloc(1); |
|---|
| 63 | + struct perf_thread_map *threads = thread_map__alloc(1); |
|---|
| 86 | 64 | |
|---|
| 87 | 65 | if (threads != NULL) { |
|---|
| 88 | | - thread_map__set_pid(threads, 0, tid); |
|---|
| 66 | + perf_thread_map__set_pid(threads, 0, tid); |
|---|
| 89 | 67 | threads->nr = 1; |
|---|
| 90 | 68 | refcount_set(&threads->refcnt, 1); |
|---|
| 91 | 69 | } |
|---|
| .. | .. |
|---|
| 93 | 71 | return threads; |
|---|
| 94 | 72 | } |
|---|
| 95 | 73 | |
|---|
| 96 | | -static struct thread_map *__thread_map__new_all_cpus(uid_t uid) |
|---|
| 74 | +static struct perf_thread_map *__thread_map__new_all_cpus(uid_t uid) |
|---|
| 97 | 75 | { |
|---|
| 98 | 76 | DIR *proc; |
|---|
| 99 | 77 | int max_threads = 32, items, i; |
|---|
| 100 | 78 | char path[NAME_MAX + 1 + 6]; |
|---|
| 101 | 79 | struct dirent *dirent, **namelist = NULL; |
|---|
| 102 | | - struct thread_map *threads = thread_map__alloc(max_threads); |
|---|
| 80 | + struct perf_thread_map *threads = thread_map__alloc(max_threads); |
|---|
| 103 | 81 | |
|---|
| 104 | 82 | if (threads == NULL) |
|---|
| 105 | 83 | goto out; |
|---|
| .. | .. |
|---|
| 139 | 117 | } |
|---|
| 140 | 118 | |
|---|
| 141 | 119 | if (grow) { |
|---|
| 142 | | - struct thread_map *tmp; |
|---|
| 120 | + struct perf_thread_map *tmp; |
|---|
| 143 | 121 | |
|---|
| 144 | | - tmp = thread_map__realloc(threads, max_threads); |
|---|
| 122 | + tmp = perf_thread_map__realloc(threads, max_threads); |
|---|
| 145 | 123 | if (tmp == NULL) |
|---|
| 146 | 124 | goto out_free_namelist; |
|---|
| 147 | 125 | |
|---|
| .. | .. |
|---|
| 149 | 127 | } |
|---|
| 150 | 128 | |
|---|
| 151 | 129 | for (i = 0; i < items; i++) { |
|---|
| 152 | | - thread_map__set_pid(threads, threads->nr + i, |
|---|
| 153 | | - atoi(namelist[i]->d_name)); |
|---|
| 130 | + perf_thread_map__set_pid(threads, threads->nr + i, |
|---|
| 131 | + atoi(namelist[i]->d_name)); |
|---|
| 154 | 132 | } |
|---|
| 155 | 133 | |
|---|
| 156 | 134 | for (i = 0; i < items; i++) |
|---|
| .. | .. |
|---|
| 179 | 157 | goto out_closedir; |
|---|
| 180 | 158 | } |
|---|
| 181 | 159 | |
|---|
| 182 | | -struct thread_map *thread_map__new_all_cpus(void) |
|---|
| 160 | +struct perf_thread_map *thread_map__new_all_cpus(void) |
|---|
| 183 | 161 | { |
|---|
| 184 | 162 | return __thread_map__new_all_cpus(UINT_MAX); |
|---|
| 185 | 163 | } |
|---|
| 186 | 164 | |
|---|
| 187 | | -struct thread_map *thread_map__new_by_uid(uid_t uid) |
|---|
| 165 | +struct perf_thread_map *thread_map__new_by_uid(uid_t uid) |
|---|
| 188 | 166 | { |
|---|
| 189 | 167 | return __thread_map__new_all_cpus(uid); |
|---|
| 190 | 168 | } |
|---|
| 191 | 169 | |
|---|
| 192 | | -struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) |
|---|
| 170 | +struct perf_thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) |
|---|
| 193 | 171 | { |
|---|
| 194 | 172 | if (pid != -1) |
|---|
| 195 | 173 | return thread_map__new_by_pid(pid); |
|---|
| .. | .. |
|---|
| 200 | 178 | return thread_map__new_by_tid(tid); |
|---|
| 201 | 179 | } |
|---|
| 202 | 180 | |
|---|
| 203 | | -static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) |
|---|
| 181 | +static struct perf_thread_map *thread_map__new_by_pid_str(const char *pid_str) |
|---|
| 204 | 182 | { |
|---|
| 205 | | - struct thread_map *threads = NULL, *nt; |
|---|
| 183 | + struct perf_thread_map *threads = NULL, *nt; |
|---|
| 206 | 184 | char name[256]; |
|---|
| 207 | 185 | int items, total_tasks = 0; |
|---|
| 208 | 186 | struct dirent **namelist = NULL; |
|---|
| .. | .. |
|---|
| 232 | 210 | goto out_free_threads; |
|---|
| 233 | 211 | |
|---|
| 234 | 212 | total_tasks += items; |
|---|
| 235 | | - nt = thread_map__realloc(threads, total_tasks); |
|---|
| 213 | + nt = perf_thread_map__realloc(threads, total_tasks); |
|---|
| 236 | 214 | if (nt == NULL) |
|---|
| 237 | 215 | goto out_free_namelist; |
|---|
| 238 | 216 | |
|---|
| 239 | 217 | threads = nt; |
|---|
| 240 | 218 | |
|---|
| 241 | 219 | for (i = 0; i < items; i++) { |
|---|
| 242 | | - thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); |
|---|
| 220 | + perf_thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); |
|---|
| 243 | 221 | zfree(&namelist[i]); |
|---|
| 244 | 222 | } |
|---|
| 245 | 223 | threads->nr = total_tasks; |
|---|
| .. | .. |
|---|
| 262 | 240 | goto out; |
|---|
| 263 | 241 | } |
|---|
| 264 | 242 | |
|---|
| 265 | | -struct thread_map *thread_map__new_dummy(void) |
|---|
| 243 | +struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) |
|---|
| 266 | 244 | { |
|---|
| 267 | | - struct thread_map *threads = thread_map__alloc(1); |
|---|
| 268 | | - |
|---|
| 269 | | - if (threads != NULL) { |
|---|
| 270 | | - thread_map__set_pid(threads, 0, -1); |
|---|
| 271 | | - threads->nr = 1; |
|---|
| 272 | | - refcount_set(&threads->refcnt, 1); |
|---|
| 273 | | - } |
|---|
| 274 | | - return threads; |
|---|
| 275 | | -} |
|---|
| 276 | | - |
|---|
| 277 | | -struct thread_map *thread_map__new_by_tid_str(const char *tid_str) |
|---|
| 278 | | -{ |
|---|
| 279 | | - struct thread_map *threads = NULL, *nt; |
|---|
| 245 | + struct perf_thread_map *threads = NULL, *nt; |
|---|
| 280 | 246 | int ntasks = 0; |
|---|
| 281 | 247 | pid_t tid, prev_tid = INT_MAX; |
|---|
| 282 | 248 | char *end_ptr; |
|---|
| .. | .. |
|---|
| 286 | 252 | |
|---|
| 287 | 253 | /* perf-stat expects threads to be generated even if tid not given */ |
|---|
| 288 | 254 | if (!tid_str) |
|---|
| 289 | | - return thread_map__new_dummy(); |
|---|
| 255 | + return perf_thread_map__new_dummy(); |
|---|
| 290 | 256 | |
|---|
| 291 | 257 | slist = strlist__new(tid_str, &slist_config); |
|---|
| 292 | 258 | if (!slist) |
|---|
| .. | .. |
|---|
| 303 | 269 | continue; |
|---|
| 304 | 270 | |
|---|
| 305 | 271 | ntasks++; |
|---|
| 306 | | - nt = thread_map__realloc(threads, ntasks); |
|---|
| 272 | + nt = perf_thread_map__realloc(threads, ntasks); |
|---|
| 307 | 273 | |
|---|
| 308 | 274 | if (nt == NULL) |
|---|
| 309 | 275 | goto out_free_threads; |
|---|
| 310 | 276 | |
|---|
| 311 | 277 | threads = nt; |
|---|
| 312 | | - thread_map__set_pid(threads, ntasks - 1, tid); |
|---|
| 278 | + perf_thread_map__set_pid(threads, ntasks - 1, tid); |
|---|
| 313 | 279 | threads->nr = ntasks; |
|---|
| 314 | 280 | } |
|---|
| 315 | 281 | out: |
|---|
| .. | .. |
|---|
| 323 | 289 | goto out; |
|---|
| 324 | 290 | } |
|---|
| 325 | 291 | |
|---|
| 326 | | -struct thread_map *thread_map__new_str(const char *pid, const char *tid, |
|---|
| 292 | +struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, |
|---|
| 327 | 293 | uid_t uid, bool all_threads) |
|---|
| 328 | 294 | { |
|---|
| 329 | 295 | if (pid) |
|---|
| .. | .. |
|---|
| 338 | 304 | return thread_map__new_by_tid_str(tid); |
|---|
| 339 | 305 | } |
|---|
| 340 | 306 | |
|---|
| 341 | | -static void thread_map__delete(struct thread_map *threads) |
|---|
| 342 | | -{ |
|---|
| 343 | | - if (threads) { |
|---|
| 344 | | - int i; |
|---|
| 345 | | - |
|---|
| 346 | | - WARN_ONCE(refcount_read(&threads->refcnt) != 0, |
|---|
| 347 | | - "thread map refcnt unbalanced\n"); |
|---|
| 348 | | - for (i = 0; i < threads->nr; i++) |
|---|
| 349 | | - free(thread_map__comm(threads, i)); |
|---|
| 350 | | - free(threads); |
|---|
| 351 | | - } |
|---|
| 352 | | -} |
|---|
| 353 | | - |
|---|
| 354 | | -struct thread_map *thread_map__get(struct thread_map *map) |
|---|
| 355 | | -{ |
|---|
| 356 | | - if (map) |
|---|
| 357 | | - refcount_inc(&map->refcnt); |
|---|
| 358 | | - return map; |
|---|
| 359 | | -} |
|---|
| 360 | | - |
|---|
| 361 | | -void thread_map__put(struct thread_map *map) |
|---|
| 362 | | -{ |
|---|
| 363 | | - if (map && refcount_dec_and_test(&map->refcnt)) |
|---|
| 364 | | - thread_map__delete(map); |
|---|
| 365 | | -} |
|---|
| 366 | | - |
|---|
| 367 | | -size_t thread_map__fprintf(struct thread_map *threads, FILE *fp) |
|---|
| 307 | +size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp) |
|---|
| 368 | 308 | { |
|---|
| 369 | 309 | int i; |
|---|
| 370 | 310 | size_t printed = fprintf(fp, "%d thread%s: ", |
|---|
| 371 | 311 | threads->nr, threads->nr > 1 ? "s" : ""); |
|---|
| 372 | 312 | for (i = 0; i < threads->nr; ++i) |
|---|
| 373 | | - printed += fprintf(fp, "%s%d", i ? ", " : "", thread_map__pid(threads, i)); |
|---|
| 313 | + printed += fprintf(fp, "%s%d", i ? ", " : "", perf_thread_map__pid(threads, i)); |
|---|
| 374 | 314 | |
|---|
| 375 | 315 | return printed + fprintf(fp, "\n"); |
|---|
| 376 | 316 | } |
|---|
| .. | .. |
|---|
| 392 | 332 | * mark the end of the string. |
|---|
| 393 | 333 | */ |
|---|
| 394 | 334 | (*comm)[size] = 0; |
|---|
| 395 | | - rtrim(*comm); |
|---|
| 335 | + strim(*comm); |
|---|
| 396 | 336 | } |
|---|
| 397 | 337 | |
|---|
| 398 | 338 | free(path); |
|---|
| 399 | 339 | return err; |
|---|
| 400 | 340 | } |
|---|
| 401 | 341 | |
|---|
| 402 | | -static void comm_init(struct thread_map *map, int i) |
|---|
| 342 | +static void comm_init(struct perf_thread_map *map, int i) |
|---|
| 403 | 343 | { |
|---|
| 404 | | - pid_t pid = thread_map__pid(map, i); |
|---|
| 344 | + pid_t pid = perf_thread_map__pid(map, i); |
|---|
| 405 | 345 | char *comm = NULL; |
|---|
| 406 | 346 | |
|---|
| 407 | 347 | /* dummy pid comm initialization */ |
|---|
| .. | .. |
|---|
| 420 | 360 | map->map[i].comm = comm; |
|---|
| 421 | 361 | } |
|---|
| 422 | 362 | |
|---|
| 423 | | -void thread_map__read_comms(struct thread_map *threads) |
|---|
| 363 | +void thread_map__read_comms(struct perf_thread_map *threads) |
|---|
| 424 | 364 | { |
|---|
| 425 | 365 | int i; |
|---|
| 426 | 366 | |
|---|
| .. | .. |
|---|
| 428 | 368 | comm_init(threads, i); |
|---|
| 429 | 369 | } |
|---|
| 430 | 370 | |
|---|
| 431 | | -static void thread_map__copy_event(struct thread_map *threads, |
|---|
| 432 | | - struct thread_map_event *event) |
|---|
| 371 | +static void thread_map__copy_event(struct perf_thread_map *threads, |
|---|
| 372 | + struct perf_record_thread_map *event) |
|---|
| 433 | 373 | { |
|---|
| 434 | 374 | unsigned i; |
|---|
| 435 | 375 | |
|---|
| 436 | 376 | threads->nr = (int) event->nr; |
|---|
| 437 | 377 | |
|---|
| 438 | 378 | for (i = 0; i < event->nr; i++) { |
|---|
| 439 | | - thread_map__set_pid(threads, i, (pid_t) event->entries[i].pid); |
|---|
| 379 | + perf_thread_map__set_pid(threads, i, (pid_t) event->entries[i].pid); |
|---|
| 440 | 380 | threads->map[i].comm = strndup(event->entries[i].comm, 16); |
|---|
| 441 | 381 | } |
|---|
| 442 | 382 | |
|---|
| 443 | 383 | refcount_set(&threads->refcnt, 1); |
|---|
| 444 | 384 | } |
|---|
| 445 | 385 | |
|---|
| 446 | | -struct thread_map *thread_map__new_event(struct thread_map_event *event) |
|---|
| 386 | +struct perf_thread_map *thread_map__new_event(struct perf_record_thread_map *event) |
|---|
| 447 | 387 | { |
|---|
| 448 | | - struct thread_map *threads; |
|---|
| 388 | + struct perf_thread_map *threads; |
|---|
| 449 | 389 | |
|---|
| 450 | 390 | threads = thread_map__alloc(event->nr); |
|---|
| 451 | 391 | if (threads) |
|---|
| .. | .. |
|---|
| 454 | 394 | return threads; |
|---|
| 455 | 395 | } |
|---|
| 456 | 396 | |
|---|
| 457 | | -bool thread_map__has(struct thread_map *threads, pid_t pid) |
|---|
| 397 | +bool thread_map__has(struct perf_thread_map *threads, pid_t pid) |
|---|
| 458 | 398 | { |
|---|
| 459 | 399 | int i; |
|---|
| 460 | 400 | |
|---|
| .. | .. |
|---|
| 466 | 406 | return false; |
|---|
| 467 | 407 | } |
|---|
| 468 | 408 | |
|---|
| 469 | | -int thread_map__remove(struct thread_map *threads, int idx) |
|---|
| 409 | +int thread_map__remove(struct perf_thread_map *threads, int idx) |
|---|
| 470 | 410 | { |
|---|
| 471 | 411 | int i; |
|---|
| 472 | 412 | |
|---|
| .. | .. |
|---|
| 479 | 419 | /* |
|---|
| 480 | 420 | * Free the 'idx' item and shift the rest up. |
|---|
| 481 | 421 | */ |
|---|
| 482 | | - free(threads->map[idx].comm); |
|---|
| 422 | + zfree(&threads->map[idx].comm); |
|---|
| 483 | 423 | |
|---|
| 484 | 424 | for (i = idx; i < threads->nr - 1; i++) |
|---|
| 485 | 425 | threads->map[i] = threads->map[i + 1]; |
|---|