@@ -159,13 +159,18 @@ static struct traceeval_type task_delta_vals[] = {
.type = TRACEEVAL_TYPE_STRING,
.name = "COMM",
},
+ {
+ .type = TRACEEVAL_TYPE_NUMBER,
+ .name = "Prio",
+ },
};
-static void assign_task_delta_vals(struct traceeval_data vals[2],
- int state, const char *comm)
+static void assign_task_delta_vals(struct traceeval_data vals[3],
+ int state, const char *comm, int prio)
{
TRACEEVAL_SET_NUMBER(vals[0], state);
TRACEEVAL_SET_CSTRING(vals[1], comm);
+ TRACEEVAL_SET_NUMBER(vals[2], prio);
}
static struct traceeval_type task_keys[] = {
@@ -214,13 +219,18 @@ static struct traceeval_type thread_keys[] = {
.type = TRACEEVAL_TYPE_NUMBER,
.name = "Schedule state",
},
+ {
+ .type = TRACEEVAL_TYPE_NUMBER,
+ .name = "Prio",
+ },
};
-static void assign_thread_keys(struct traceeval_data keys[2],
- int tid, int state)
+static void assign_thread_keys(struct traceeval_data keys[3],
+ int tid, int state, int prio)
{
TRACEEVAL_SET_NUMBER(keys[0], tid);
TRACEEVAL_SET_NUMBER(keys[1], state);
+ TRACEEVAL_SET_NUMBER(keys[2], prio);
}
static struct traceeval_type thread_vals[] = {
@@ -404,35 +414,36 @@ static void update_cpu_to_running(struct task_data *tdata, struct tep_record *re
}
static void update_thread(struct task_data *tdata, int pid, const char *comm,
- enum sched_state state, unsigned long long delta,
+ enum sched_state state, int prio, unsigned long long delta,
unsigned long long ts)
{
- struct traceeval_data keys[2];
+ struct traceeval_data task_keys[2];
+ struct traceeval_data thread_keys[3];
struct traceeval_data pvals[2];
struct traceeval_data vals[1];
struct process_data *pdata;
pdata = get_process_data(tdata, comm);
- assign_thread_keys(keys, pid, state);
+ assign_thread_keys(thread_keys, pid, state, prio);
assign_thread_vals(vals, delta, ts);
- traceeval_insert(pdata->teval_threads, keys, vals);
+ traceeval_insert(pdata->teval_threads, thread_keys, vals);
/* Also update the process */
- assign_task_keys(keys, comm, state);
+ assign_task_keys(task_keys, comm, state);
assign_task_vals(pvals, pdata, delta, ts);
- traceeval_insert(tdata->teval_tasks, keys, pvals);
+ traceeval_insert(tdata->teval_tasks, task_keys, pvals);
}
static void start_running_thread(struct task_data *tdata,
struct tep_record *record,
- const char *comm, int pid)
+ const char *comm, int pid, int prio)
{
const struct traceeval_data *results;
struct traceeval_data delta_keys[1];
- struct traceeval_data vals[2];
+ struct traceeval_data vals[3];
unsigned long long delta;
unsigned long long val;
int ret;
@@ -447,11 +458,11 @@ static void start_running_thread(struct task_data *tdata,
if (state == RUNNING)
die("State %d is running! %lld -> %lld", pid, val, record->ts);
- update_thread(tdata, pid, comm, state, delta, record->ts);
+ update_thread(tdata, pid, comm, state, prio, delta, record->ts);
traceeval_results_release(tdata->teval_tasks, results);
}
- assign_task_delta_vals(vals, RUNNING, comm);
+ assign_task_delta_vals(vals, RUNNING, comm, prio);
traceeval_delta_start(tdata->teval_tasks, delta_keys, vals, record->ts);
}
@@ -468,11 +479,14 @@ static int get_stop_state(unsigned long long val)
static void sched_out(struct task_data *tdata, const char *comm,
struct tep_event *event,
struct tep_record *record, struct tep_format_field *prev_pid,
- struct tep_format_field *prev_state)
+ struct tep_format_field *prev_state,
+ struct tep_format_field *prev_prio)
{
struct traceeval_data delta_keys[1];
struct traceeval_data task_keys[2];
+ struct traceeval_data task_delta_vals[3];
struct traceeval_data task_vals[2];
+ struct traceeval_data thread_keys[3];
struct traceeval_data vals[1];
struct process_data *pdata;
const struct traceeval_data *results;
@@ -480,6 +494,7 @@ static void sched_out(struct task_data *tdata, const char *comm,
unsigned long long val;
int state;
int old_state;
+ int prio;
int pid;
int ret;
@@ -492,6 +507,11 @@ static void sched_out(struct task_data *tdata, const char *comm,
if (!pid)
return;
+ ret = tep_read_number_field(prev_prio, record->data, &val);
+ if (ret < 0)
+ die("Could not read sched_switch prev_prio for record");
+ prio = val;
+
ret = tep_read_number_field(prev_state, record->data, &val);
if (ret < 0)
die("Could not read sched_switch next_pid for record");
@@ -502,13 +522,13 @@ static void sched_out(struct task_data *tdata, const char *comm,
ret = traceeval_delta_stop(tdata->teval_tasks, delta_keys, &results,
record->ts, &delta, &val);
- assign_task_delta_vals(task_vals, state, comm);
+ assign_task_delta_vals(task_delta_vals, state, comm, prio);
if (ret > 0)
old_state = results[0].number;
/* Start recording why this task is off the CPU */
- traceeval_delta_start(tdata->teval_tasks, delta_keys, task_vals, record->ts);
+ traceeval_delta_start(tdata->teval_tasks, delta_keys, task_delta_vals, record->ts);
if (ret <= 0)
return;
@@ -524,10 +544,10 @@ static void sched_out(struct task_data *tdata, const char *comm,
traceeval_insert(tdata->teval_tasks, task_keys, task_vals);
- assign_thread_keys(task_keys, pid, RUNNING);
+ assign_thread_keys(thread_keys, pid, RUNNING, prio);
assign_thread_vals(vals, delta, record->ts);
- traceeval_insert(pdata->teval_threads, task_keys, vals);
+ traceeval_insert(pdata->teval_threads, thread_keys, vals);
assign_cpu_keys(task_keys, record->cpu, RUNNING);
@@ -536,11 +556,14 @@ static void sched_out(struct task_data *tdata, const char *comm,
static void sched_in(struct task_data *tdata, const char *comm,
struct tep_event *event,
- struct tep_record *record, struct tep_format_field *next_pid)
+ struct tep_record *record,
+ struct tep_format_field *next_pid,
+ struct tep_format_field *next_prio)
{
unsigned long long val;
- int ret;
+ int prio;
int pid;
+ int ret;
ret = tep_read_number_field(next_pid, record->data, &val);
if (ret < 0)
@@ -553,9 +576,14 @@ static void sched_in(struct task_data *tdata, const char *comm,
return;
}
+ ret = tep_read_number_field(next_prio, record->data, &val);
+ if (ret < 0)
+ die("Could not read sched_switch next_prio for record");
+ prio = val;
+
/* Continue measuring CPU running time */
update_cpu_to_running(tdata, record);
- start_running_thread(tdata, record, comm, pid);
+ start_running_thread(tdata, record, comm, pid, prio);
}
static struct tep_format_field *get_field(struct tep_event *event, const char *name)
@@ -576,8 +604,10 @@ static int switch_func(struct tracecmd_input *handle, struct tep_event *event,
static struct tep_format_field *prev_comm;
static struct tep_format_field *prev_pid;
static struct tep_format_field *prev_state;
+ static struct tep_format_field *prev_prio;
static struct tep_format_field *next_comm;
static struct tep_format_field *next_pid;
+ static struct tep_format_field *next_prio;
struct task_data *tdata = data;
const char *comm;
@@ -585,18 +615,20 @@ static int switch_func(struct tracecmd_input *handle, struct tep_event *event,
prev_comm = get_field(event, "prev_comm");
prev_pid = get_field(event, "prev_pid");
prev_state = get_field(event, "prev_state");
+ prev_prio = get_field(event, "prev_prio");
next_comm = get_field(event, "next_comm");
next_pid = get_field(event, "next_pid");
+ next_prio = get_field(event, "next_prio");
}
comm = record->data + prev_comm->offset;
if (!tdata->comm || strcmp(comm, tdata->comm) == 0)
- sched_out(tdata, comm, event, record, prev_pid, prev_state);
+ sched_out(tdata, comm, event, record, prev_pid, prev_state, prev_prio);
comm = record->data + next_comm->offset;
if (!tdata->comm || strcmp(comm, tdata->comm) == 0)
- sched_in(tdata, comm, event, record, next_pid);
+ sched_in(tdata, comm, event, record, next_pid, next_prio);
return 0;
}
@@ -740,22 +772,35 @@ static void display_threads(struct traceeval *teval)
const struct traceeval_data *keys;
struct traceeval_stat *stat;
int last_tid = -1;
+ int last_prio = -1;
+ /* PID */
traceeval_iterator_sort(iter, thread_keys[0].name, 0, true);
- traceeval_iterator_sort(iter, thread_keys[1].name, 1, true);
+
+ /* PRIO */
+ traceeval_iterator_sort(iter, thread_keys[2].name, 1, true);
+
+ /* STATE */
+ traceeval_iterator_sort(iter, thread_keys[1].name, 2, true);
while (traceeval_iterator_next(iter, &keys) > 0) {
- int state = keys[1].number;
int tid = keys[0].number;
+ int state = keys[1].number;
+ int prio = keys[2].number;
stat = traceeval_iterator_stat(iter, DELTA_NAME);
if (!stat)
continue; // die?
- if (last_tid != keys[0].number)
- printf("\n thread id: %d\n", tid);
+ if (last_tid != tid || last_prio != prio) {
+ if (prio < 120)
+ printf("\n thread id: %d [ prio: %d ]\n", tid, prio);
+ else
+ printf("\n thread id: %d\n", tid);
+ }
last_tid = tid;
+ last_prio = prio;
display_state_times(state, traceeval_stat_total(stat));
}
@@ -888,6 +933,7 @@ static void finish_leftovers(struct task_data *data)
unsigned long long delta;
enum sched_state state;
const char *comm;
+ int prio;
int pid;
iter = traceeval_iterator_delta_start_get(data->teval_tasks);
@@ -899,8 +945,9 @@ static void finish_leftovers(struct task_data *data)
state = results[0].number;
comm = results[1].cstring;
+ prio = results[2].number;
- update_thread(data, pid, comm, state, delta, data->last_ts);
+ update_thread(data, pid, comm, state, prio, delta, data->last_ts);
}
traceeval_iterator_put(iter);