Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163744
b: refs/heads/master
c: 4653881
h: refs/heads/master
v: v3
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Sep 13, 2009
1 parent d64db90 commit 0bc517c
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bcd3279f465cdcc1e0454b5f605f021c4ff4dbb5
refs/heads/master: 46538818023e8ea94f656acfa1e38297e2df20e2
101 changes: 76 additions & 25 deletions trunk/tools/perf/builtin-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,30 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
return 0;
}


struct raw_event_sample {
u32 size;
char data[0];
};

#define FILL_FIELD(ptr, field, event, data) \
ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data)

#define FILL_ARRAY(ptr, array, event, data) \
do { \
void *__array = raw_field_ptr(event, #array, data); \
memcpy(ptr.array, __array, sizeof(ptr.array)); \
} while(0)

#define FILL_COMMON_FIELDS(ptr, event, data) \
do { \
FILL_FIELD(ptr, common_type, event, data); \
FILL_FIELD(ptr, common_flags, event, data); \
FILL_FIELD(ptr, common_preempt_count, event, data); \
FILL_FIELD(ptr, common_pid, event, data); \
FILL_FIELD(ptr, common_tgid, event, data); \
} while (0)

struct trace_wakeup_event {
u32 size;

Expand All @@ -671,22 +695,32 @@ struct trace_wakeup_event {
};

static void
process_sched_wakeup_event(struct trace_wakeup_event *wakeup_event, struct event *event,
process_sched_wakeup_event(struct raw_event_sample *raw, struct event *event,
int cpu __used, u64 timestamp __used, struct thread *thread __used)
{
struct task_desc *waker, *wakee;
struct trace_wakeup_event wakeup_event;

FILL_COMMON_FIELDS(wakeup_event, event, raw->data);

FILL_ARRAY(wakeup_event, comm, event, raw->data);
FILL_FIELD(wakeup_event, pid, event, raw->data);
FILL_FIELD(wakeup_event, prio, event, raw->data);
FILL_FIELD(wakeup_event, success, event, raw->data);
FILL_FIELD(wakeup_event, cpu, event, raw->data);


if (verbose) {
printf("sched_wakeup event %p\n", event);

printf(" ... pid %d woke up %s/%d\n",
wakeup_event->common_pid,
wakeup_event->comm,
wakeup_event->pid);
wakeup_event.common_pid,
wakeup_event.comm,
wakeup_event.pid);
}

waker = register_pid(wakeup_event->common_pid, "<unknown>");
wakee = register_pid(wakeup_event->pid, wakeup_event->comm);
waker = register_pid(wakeup_event.common_pid, "<unknown>");
wakee = register_pid(wakeup_event.pid, wakeup_event.comm);

add_sched_event_wakeup(waker, timestamp, wakee);
}
Expand Down Expand Up @@ -714,13 +748,24 @@ struct trace_switch_event {
unsigned long cpu_last_switched[MAX_CPUS];

static void
process_sched_switch_event(struct trace_switch_event *switch_event, struct event *event,
process_sched_switch_event(struct raw_event_sample *raw, struct event *event,
int cpu __used, u64 timestamp __used, struct thread *thread __used)
{
struct trace_switch_event switch_event;
struct task_desc *prev, *next;
u64 timestamp0;
s64 delta;

FILL_COMMON_FIELDS(switch_event, event, raw->data);

FILL_ARRAY(switch_event, prev_comm, event, raw->data);
FILL_FIELD(switch_event, prev_pid, event, raw->data);
FILL_FIELD(switch_event, prev_prio, event, raw->data);
FILL_FIELD(switch_event, prev_state, event, raw->data);
FILL_ARRAY(switch_event, next_comm, event, raw->data);
FILL_FIELD(switch_event, next_pid, event, raw->data);
FILL_FIELD(switch_event, next_prio, event, raw->data);

if (verbose)
printf("sched_switch event %p\n", event);

Expand All @@ -738,18 +783,18 @@ process_sched_switch_event(struct trace_switch_event *switch_event, struct event

if (verbose) {
printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n",
switch_event->prev_comm, switch_event->prev_pid,
switch_event->next_comm, switch_event->next_pid,
switch_event.prev_comm, switch_event.prev_pid,
switch_event.next_comm, switch_event.next_pid,
delta);
}

prev = register_pid(switch_event->prev_pid, switch_event->prev_comm);
next = register_pid(switch_event->next_pid, switch_event->next_comm);
prev = register_pid(switch_event.prev_pid, switch_event.prev_comm);
next = register_pid(switch_event.next_pid, switch_event.next_comm);

cpu_last_switched[cpu] = timestamp;

add_sched_event_run(prev, timestamp, delta);
add_sched_event_sleep(prev, timestamp, switch_event->prev_state);
add_sched_event_sleep(prev, timestamp, switch_event.prev_state);
}

struct trace_fork_event {
Expand All @@ -768,16 +813,25 @@ struct trace_fork_event {
};

static void
process_sched_fork_event(struct trace_fork_event *fork_event, struct event *event,
process_sched_fork_event(struct raw_event_sample *raw, struct event *event,
int cpu __used, u64 timestamp __used, struct thread *thread __used)
{
struct trace_fork_event fork_event;

FILL_COMMON_FIELDS(fork_event, event, raw->data);

FILL_ARRAY(fork_event, parent_comm, event, raw->data);
FILL_FIELD(fork_event, parent_pid, event, raw->data);
FILL_ARRAY(fork_event, child_comm, event, raw->data);
FILL_FIELD(fork_event, child_pid, event, raw->data);

if (verbose) {
printf("sched_fork event %p\n", event);
printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid);
printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid);
printf("... parent: %s/%d\n", fork_event.parent_comm, fork_event.parent_pid);
printf("... child: %s/%d\n", fork_event.child_comm, fork_event.child_pid);
}
register_pid(fork_event->parent_pid, fork_event->parent_comm);
register_pid(fork_event->child_pid, fork_event->child_comm);
register_pid(fork_event.parent_pid, fork_event.parent_comm);
register_pid(fork_event.child_pid, fork_event.child_comm);
}

static void process_sched_exit_event(struct event *event,
Expand All @@ -791,24 +845,21 @@ static void
process_raw_event(event_t *raw_event __used, void *more_data,
int cpu, u64 timestamp, struct thread *thread)
{
struct {
u32 size;
char data[0];
} *raw = more_data;
struct raw_event_sample *raw = more_data;
struct event *event;
int type;

type = trace_parse_common_type(raw->data);
event = trace_find_event(type);

if (!strcmp(event->name, "sched_switch"))
process_sched_switch_event(more_data, event, cpu, timestamp, thread);
process_sched_switch_event(raw, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_wakeup"))
process_sched_wakeup_event(more_data, event, cpu, timestamp, thread);
process_sched_wakeup_event(raw, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_wakeup_new"))
process_sched_wakeup_event(more_data, event, cpu, timestamp, thread);
process_sched_wakeup_event(raw, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_process_fork"))
process_sched_fork_event(more_data, event, cpu, timestamp, thread);
process_sched_fork_event(raw, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_process_exit"))
process_sched_exit_event(event, cpu, timestamp, thread);
}
Expand Down
23 changes: 23 additions & 0 deletions trunk/tools/perf/util/trace-event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,29 @@ static unsigned long long read_size(void *ptr, int size)
}
}

unsigned long long
raw_field_value(struct event *event, const char *name, void *data)
{
struct format_field *field;

field = find_any_field(event, name);
if (!field)
return 0ULL;

return read_size(data + field->offset, field->size);
}

void *raw_field_ptr(struct event *event, const char *name, void *data)
{
struct format_field *field;

field = find_any_field(event, name);
if (!field)
return NULL;

return data + field->offset;
}

static int get_common_info(const char *type, int *offset, int *size)
{
struct event *event;
Expand Down
3 changes: 3 additions & 0 deletions trunk/tools/perf/util/trace-event.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ extern int header_page_data_size;
int parse_header_page(char *buf, unsigned long size);
int trace_parse_common_type(void *data);
struct event *trace_find_event(int id);
unsigned long long
raw_field_value(struct event *event, const char *name, void *data);
void *raw_field_ptr(struct event *event, const char *name, void *data);

void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters);

Expand Down

0 comments on commit 0bc517c

Please sign in to comment.