|
@@ -15,95 +15,6 @@ char * field_sep;
|
|
|
|
|
|
LIST_HEAD(hist_entry__sort_list);
|
|
LIST_HEAD(hist_entry__sort_list);
|
|
|
|
|
|
-static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
|
|
|
|
- size_t size, unsigned int width);
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_thread = {
|
|
|
|
- .se_header = "Command: Pid",
|
|
|
|
- .se_cmp = sort__thread_cmp,
|
|
|
|
- .se_snprintf = hist_entry__thread_snprintf,
|
|
|
|
- .se_width_idx = HISTC_THREAD,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_comm = {
|
|
|
|
- .se_header = "Command",
|
|
|
|
- .se_cmp = sort__comm_cmp,
|
|
|
|
- .se_collapse = sort__comm_collapse,
|
|
|
|
- .se_snprintf = hist_entry__comm_snprintf,
|
|
|
|
- .se_width_idx = HISTC_COMM,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_dso = {
|
|
|
|
- .se_header = "Shared Object",
|
|
|
|
- .se_cmp = sort__dso_cmp,
|
|
|
|
- .se_snprintf = hist_entry__dso_snprintf,
|
|
|
|
- .se_width_idx = HISTC_DSO,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_sym = {
|
|
|
|
- .se_header = "Symbol",
|
|
|
|
- .se_cmp = sort__sym_cmp,
|
|
|
|
- .se_snprintf = hist_entry__sym_snprintf,
|
|
|
|
- .se_width_idx = HISTC_SYMBOL,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_parent = {
|
|
|
|
- .se_header = "Parent symbol",
|
|
|
|
- .se_cmp = sort__parent_cmp,
|
|
|
|
- .se_snprintf = hist_entry__parent_snprintf,
|
|
|
|
- .se_width_idx = HISTC_PARENT,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_entry sort_cpu = {
|
|
|
|
- .se_header = "CPU",
|
|
|
|
- .se_cmp = sort__cpu_cmp,
|
|
|
|
- .se_snprintf = hist_entry__cpu_snprintf,
|
|
|
|
- .se_width_idx = HISTC_CPU,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct sort_dimension {
|
|
|
|
- const char *name;
|
|
|
|
- struct sort_entry *entry;
|
|
|
|
- int taken;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static struct sort_dimension sort_dimensions[] = {
|
|
|
|
- { .name = "pid", .entry = &sort_thread, },
|
|
|
|
- { .name = "comm", .entry = &sort_comm, },
|
|
|
|
- { .name = "dso", .entry = &sort_dso, },
|
|
|
|
- { .name = "symbol", .entry = &sort_sym, },
|
|
|
|
- { .name = "parent", .entry = &sort_parent, },
|
|
|
|
- { .name = "cpu", .entry = &sort_cpu, },
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-int64_t cmp_null(void *l, void *r)
|
|
|
|
-{
|
|
|
|
- if (!l && !r)
|
|
|
|
- return 0;
|
|
|
|
- else if (!l)
|
|
|
|
- return -1;
|
|
|
|
- else
|
|
|
|
- return 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* --sort pid */
|
|
|
|
-
|
|
|
|
-int64_t
|
|
|
|
-sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
-{
|
|
|
|
- return right->thread->pid - left->thread->pid;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
|
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
|
{
|
|
{
|
|
int n;
|
|
int n;
|
|
@@ -125,6 +36,24 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
|
return n;
|
|
return n;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int64_t cmp_null(void *l, void *r)
|
|
|
|
+{
|
|
|
|
+ if (!l && !r)
|
|
|
|
+ return 0;
|
|
|
|
+ else if (!l)
|
|
|
|
+ return -1;
|
|
|
|
+ else
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* --sort pid */
|
|
|
|
+
|
|
|
|
+static int64_t
|
|
|
|
+sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
+{
|
|
|
|
+ return right->thread->pid - left->thread->pid;
|
|
|
|
+}
|
|
|
|
+
|
|
static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
|
static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
|
size_t size, unsigned int width)
|
|
size_t size, unsigned int width)
|
|
{
|
|
{
|
|
@@ -132,15 +61,50 @@ static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
|
self->thread->comm ?: "", self->thread->pid);
|
|
self->thread->comm ?: "", self->thread->pid);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct sort_entry sort_thread = {
|
|
|
|
+ .se_header = "Command: Pid",
|
|
|
|
+ .se_cmp = sort__thread_cmp,
|
|
|
|
+ .se_snprintf = hist_entry__thread_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_THREAD,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* --sort comm */
|
|
|
|
+
|
|
|
|
+static int64_t
|
|
|
|
+sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
+{
|
|
|
|
+ return right->thread->pid - left->thread->pid;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int64_t
|
|
|
|
+sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
+{
|
|
|
|
+ char *comm_l = left->thread->comm;
|
|
|
|
+ char *comm_r = right->thread->comm;
|
|
|
|
+
|
|
|
|
+ if (!comm_l || !comm_r)
|
|
|
|
+ return cmp_null(comm_l, comm_r);
|
|
|
|
+
|
|
|
|
+ return strcmp(comm_l, comm_r);
|
|
|
|
+}
|
|
|
|
+
|
|
static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
|
|
static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
|
|
size_t size, unsigned int width)
|
|
size_t size, unsigned int width)
|
|
{
|
|
{
|
|
return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
|
|
return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct sort_entry sort_comm = {
|
|
|
|
+ .se_header = "Command",
|
|
|
|
+ .se_cmp = sort__comm_cmp,
|
|
|
|
+ .se_collapse = sort__comm_collapse,
|
|
|
|
+ .se_snprintf = hist_entry__comm_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_COMM,
|
|
|
|
+};
|
|
|
|
+
|
|
/* --sort dso */
|
|
/* --sort dso */
|
|
|
|
|
|
-int64_t
|
|
|
|
|
|
+static int64_t
|
|
sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
{
|
|
{
|
|
struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
|
|
struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
|
|
@@ -173,9 +137,16 @@ static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
|
|
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
|
|
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct sort_entry sort_dso = {
|
|
|
|
+ .se_header = "Shared Object",
|
|
|
|
+ .se_cmp = sort__dso_cmp,
|
|
|
|
+ .se_snprintf = hist_entry__dso_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_DSO,
|
|
|
|
+};
|
|
|
|
+
|
|
/* --sort symbol */
|
|
/* --sort symbol */
|
|
|
|
|
|
-int64_t
|
|
|
|
|
|
+static int64_t
|
|
sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
{
|
|
{
|
|
u64 ip_l, ip_r;
|
|
u64 ip_l, ip_r;
|
|
@@ -211,29 +182,16 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-/* --sort comm */
|
|
|
|
-
|
|
|
|
-int64_t
|
|
|
|
-sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
-{
|
|
|
|
- return right->thread->pid - left->thread->pid;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int64_t
|
|
|
|
-sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
|
|
|
|
-{
|
|
|
|
- char *comm_l = left->thread->comm;
|
|
|
|
- char *comm_r = right->thread->comm;
|
|
|
|
-
|
|
|
|
- if (!comm_l || !comm_r)
|
|
|
|
- return cmp_null(comm_l, comm_r);
|
|
|
|
-
|
|
|
|
- return strcmp(comm_l, comm_r);
|
|
|
|
-}
|
|
|
|
|
|
+struct sort_entry sort_sym = {
|
|
|
|
+ .se_header = "Symbol",
|
|
|
|
+ .se_cmp = sort__sym_cmp,
|
|
|
|
+ .se_snprintf = hist_entry__sym_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_SYMBOL,
|
|
|
|
+};
|
|
|
|
|
|
/* --sort parent */
|
|
/* --sort parent */
|
|
|
|
|
|
-int64_t
|
|
|
|
|
|
+static int64_t
|
|
sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
{
|
|
{
|
|
struct symbol *sym_l = left->parent;
|
|
struct symbol *sym_l = left->parent;
|
|
@@ -252,9 +210,16 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
|
|
self->parent ? self->parent->name : "[other]");
|
|
self->parent ? self->parent->name : "[other]");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct sort_entry sort_parent = {
|
|
|
|
+ .se_header = "Parent symbol",
|
|
|
|
+ .se_cmp = sort__parent_cmp,
|
|
|
|
+ .se_snprintf = hist_entry__parent_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_PARENT,
|
|
|
|
+};
|
|
|
|
+
|
|
/* --sort cpu */
|
|
/* --sort cpu */
|
|
|
|
|
|
-int64_t
|
|
|
|
|
|
+static int64_t
|
|
sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
{
|
|
{
|
|
return right->cpu - left->cpu;
|
|
return right->cpu - left->cpu;
|
|
@@ -266,6 +231,28 @@ static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
|
|
return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
|
|
return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct sort_entry sort_cpu = {
|
|
|
|
+ .se_header = "CPU",
|
|
|
|
+ .se_cmp = sort__cpu_cmp,
|
|
|
|
+ .se_snprintf = hist_entry__cpu_snprintf,
|
|
|
|
+ .se_width_idx = HISTC_CPU,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct sort_dimension {
|
|
|
|
+ const char *name;
|
|
|
|
+ struct sort_entry *entry;
|
|
|
|
+ int taken;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct sort_dimension sort_dimensions[] = {
|
|
|
|
+ { .name = "pid", .entry = &sort_thread, },
|
|
|
|
+ { .name = "comm", .entry = &sort_comm, },
|
|
|
|
+ { .name = "dso", .entry = &sort_dso, },
|
|
|
|
+ { .name = "symbol", .entry = &sort_sym, },
|
|
|
|
+ { .name = "parent", .entry = &sort_parent, },
|
|
|
|
+ { .name = "cpu", .entry = &sort_cpu, },
|
|
|
|
+};
|
|
|
|
+
|
|
int sort_dimension__add(const char *tok)
|
|
int sort_dimension__add(const char *tok)
|
|
{
|
|
{
|
|
unsigned int i;
|
|
unsigned int i;
|