static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width __used) { FILE *fp; char cmd[PATH_MAX + 2], *path = self->srcline, *nl; size_t line_len; if (path != NULL) goto out_path; snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, self->ms.map->dso->long_name, self->ip); fp = popen(cmd, "r"); if (!fp) goto out_ip; if (getline(&path, &line_len, fp) < 0 || !line_len) goto out_ip; fclose(fp); self->srcline = strdup(path); if (self->srcline == NULL) goto out_ip; nl = strchr(self->srcline, '\n'); if (nl != NULL) *nl = '\0'; path = self->srcline; out_path: return repsep_snprintf(bf, size, "%s", path); out_ip: return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip); }
static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, u64 ip, char level, char *bf, size_t size, unsigned int width __used) { size_t ret = 0; if (verbose) { char o = map ? dso__symtab_origin(map->dso) : '!'; ret += repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4, ip, o); } ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); if (sym) ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, sym->name); else { size_t len = BITS_PER_LONG / 4; ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, ip); ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); } return ret; }
static int hist_entry__cycles_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { if (he->branch_info->flags.cycles == 0) return repsep_snprintf(bf, size, "%-*s", width, "-"); return repsep_snprintf(bf, size, "%-*hd", width, he->branch_info->flags.cycles); }
static int _hist_entry__dso_snprintf(struct map *map, char *bf, size_t size, unsigned int width) { if (map && map->dso) { const char *dso_name = !verbose ? map->dso->short_name : map->dso->long_name; return repsep_snprintf(bf, size, "%-*s", width, dso_name); } return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); }
static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, u64 ip, char level, char *bf, size_t size, unsigned int width) { size_t ret = 0; if (verbose) { char o = map ? dso__symtab_origin(map->dso) : '!'; ret += repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4 + 2, ip, o); } ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); if (sym && map) { if (map->type == MAP__VARIABLE) { ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", ip - map->unmap_ip(map, sym->start)); ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); } else { ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, sym->name); } } else { size_t len = BITS_PER_LONG / 4; ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, ip); ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); } return ret; }
static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { char out[64]; size_t sz = sizeof(out) - 1; /* -1 for null termination */ size_t i, l = 0; u64 m = PERF_MEM_SNOOP_NA; out[0] = '\0'; if (he->mem_info) m = he->mem_info->data_src.mem_snoop; for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) { if (!(m & 0x1)) continue; if (l) { strcat(out, " or "); l += 4; } strncat(out, snoop_access[i], sz - l); l += strlen(snoop_access[i]); } if (*out == '\0') strcpy(out, "N/A"); return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { static const char *out = "."; if (he->branch_info->flags.abort) out = "A"; return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { if (he->branch_info) return _hist_entry__dso_snprintf(he->branch_info->to.map, bf, size, width); else return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); }
static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width){ static const char *out = "N/A"; if (self->branch_info->flags.predicted) out = "N"; else if (self->branch_info->flags.mispred) out = "Y"; return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { if (he->branch_info) { struct addr_map_symbol *to = &he->branch_info->to; return _hist_entry__sym_snprintf(to->map, to->sym, to->addr, he->level, bf, size, width); } return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); }
static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { char out[64]; size_t sz = sizeof(out) - 1; /* -1 for null termination */ size_t i, l = 0; u64 m = PERF_MEM_LVL_NA; u64 hit, miss; int filter; if (he->mem_info) m = he->mem_info->data_src.mem_lvl; out[0] = '\0'; //PERF_MEM_LVL_HIT = 0x2 , PERF_MEM_LVL_MISS= 0x04 hit = m & PERF_MEM_LVL_HIT; miss = m & PERF_MEM_LVL_MISS; /* already taken care of */ //the result of the or operation is 0b110 //negated 111..001 it means it will clear bit positions 1 and 2 m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); //see above function for definition of NUM_MEM_LVL for (i = 0; m && i < NUM_MEM_LVL; i++, m >>= 1) { //nothing happens it the ith bit is 0 if (!(m & 0x1)) continue; if (l) { strcat(out, " or "); l += 4; } //If the mask is not one it will add something to the output string strncat(out, mem_lvl[i], sz - l); l += strlen(mem_lvl[i]); } filter=filter_local_accesses(he); char filt[3]; sprintf(filt," %d ",filter); if (*out == '\0') strcpy(out, "N/A"); if (hit) strncat(out, " hit", sz - l); if (miss) strncat(out, " miss", sz - l); strncat(out, filt,3); return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { static const char *out = "N/A"; if (he->branch_info) { if (he->branch_info->flags.in_tx) out = "T"; else out = "."; } return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { const char *out; u64 mask = PERF_MEM_LOCK_NA; if (he->mem_info) mask = he->mem_info->data_src.mem_lock; if (mask & PERF_MEM_LOCK_NA) out = "N/A"; else if (mask & PERF_MEM_LOCK_LOCKED) out = "Yes"; else out = "No"; return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { char out[64]; size_t sz = sizeof(out) - 1; /* -1 for null termination */ size_t i, l = 0; u64 m = PERF_MEM_LVL_NA; u64 hit, miss; if (he->mem_info) m = he->mem_info->data_src.mem_lvl; out[0] = '\0'; hit = m & PERF_MEM_LVL_HIT; miss = m & PERF_MEM_LVL_MISS; /* already taken care of */ m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); for (i = 0; m && i < NUM_MEM_LVL; i++, m >>= 1) { if (!(m & 0x1)) continue; if (l) { strcat(out, " or "); l += 4; } strncat(out, mem_lvl[i], sz - l); l += strlen(mem_lvl[i]); } if (*out == '\0') strcpy(out, "N/A"); if (hit) strncat(out, " hit", sz - l); if (miss) strncat(out, " miss", sz - l); return repsep_snprintf(bf, size, "%-*s", width, out); }
static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%-*d", width, self->cpu); }
static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width __maybe_unused) { return repsep_snprintf(bf, size, "%s", he->srcline); }
static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%-*s", width, self->parent ? self->parent->name : "[other]"); }
static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%-*.*s", width, width, comm__str(he->comm)); }
static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%*.*-s", width, width, he->srcline); }
static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%*.*d", width, width, he->cpu); }
static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight); }
static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he)); }
static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%*s", width, self->thread->comm); }
static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket); }