#ifndef __SCHED_TRACE_H_ #define __SCHED_TRACE_H_ #include typedef uint8_t u8; typedef uint32_t u32; typedef uint16_t u16; typedef uint64_t u64; #ifndef DMAX_TASKS #define DMAX_TASKS 1000 #endif /* A couple of notes about the format: * * - make sure it is in sync with the kernel * - all times in nanoseconds * - endianess issues are the problem of the app */ struct st_trace_header { u8 type; /* Of what type is this record? */ u8 cpu; /* On which CPU was it recorded? */ u16 pid; /* PID of the task. */ u32 job; /* The job sequence number. */ } __attribute__((packed)); #define ST_NAME_LEN 16 struct st_name_data { char cmd[ST_NAME_LEN];/* The name of the executable of this process. */ } __attribute__((packed)); struct st_param_data { /* regular params */ u32 wcet; u32 period; u32 phase; u8 partition; u8 _class; u8 __unused[2]; } __attribute__((packed)); struct st_release_data { /* A job is was/is going to be released. */ u64 release; /* What's the release time? */ u64 deadline; /* By when must it finish? */ } __attribute__((packed)); struct st_assigned_data { /* A job was asigned to a CPU. */ u64 when; u8 target; /* Where should it execute? */ u8 __unused[7]; } __attribute__((packed)); struct st_switch_to_data { /* A process was switched to on a given CPU. */ u64 when; /* When did this occur? */ u32 exec_time; /* Time the current job has executed. */ u8 __unused[4]; } __attribute__((packed)); struct st_switch_away_data { /* A process was switched away from on a given CPU. */ u64 when; u64 exec_time; } __attribute__((packed)); struct st_completion_data { /* A job completed. */ u64 when; u8 forced:1; /* Set to 1 if job overran and kernel advanced to the * next task automatically; set to 0 otherwise. */ u8 __uflags:7; u8 __unused[3]; } __attribute__((packed)); struct st_block_data { /* A task blocks. */ u64 when; u64 __unused; } __attribute__((packed)); struct st_resume_data { /* A task resumes. */ u64 when; u64 __unused; } __attribute__((packed)); struct st_action_data { u64 when; u8 action; u8 __unused[7]; } __attribute__((packed)); struct st_sys_release_data { u64 when; u64 release; } __attribute__((packed)); struct st_tasklet_release_data { u64 when; u64 __unused; } __attribute__((packed)); struct st_tasklet_begin_data { u64 when; u16 exp_pid; u8 __unused[6]; } __attribute__((packed)); struct st_tasklet_end_data { u64 when; u16 exe_pid; u8 flushed; u8 __unused[5]; } __attribute__((packed)); struct st_work_release_data { u64 when; u64 __unused; } __attribute__((packed)); struct st_work_begin_data { u64 when; u16 exe_pid; u8 __unused[6]; } __attribute__((packed)); struct st_work_end_data { u64 when; u16 exe_pid; u8 flushed; u8 __unused[5]; } __attribute__((packed)); struct st_effective_priority_change_data { u64 when; u16 inh_pid; u8 __unused[6]; } __attribute__((packed)); struct st_nv_interrupt_begin_data { u64 when; u32 device; u8 __unused[4]; } __attribute__((packed)); struct st_nv_interrupt_end_data { u64 when; u32 device; u8 __unused[4]; } __attribute__((packed)); #define DATA(x) struct st_ ## x ## _data x; typedef enum { ST_NAME = 1, /* Start at one, so that we can spot * uninitialized records. */ ST_PARAM, ST_RELEASE, ST_ASSIGNED, ST_SWITCH_TO, ST_SWITCH_AWAY, ST_COMPLETION, ST_BLOCK, ST_RESUME, ST_ACTION, ST_SYS_RELEASE, ST_TASKLET_RELEASE, ST_TASKLET_BEGIN, ST_TASKLET_END, ST_WORK_RELEASE, ST_WORK_BEGIN, ST_WORK_END, ST_EFF_PRIO_CHANGE, ST_NV_INTERRUPT_BEGIN, ST_NV_INTERRUPT_END, } st_event_record_type_t; struct st_event_record { struct st_trace_header hdr; union { u64 raw[2]; DATA(name); DATA(param); DATA(release); DATA(assigned); DATA(switch_to); DATA(switch_away); DATA(completion); DATA(block); DATA(resume); DATA(action); DATA(sys_release); DATA(tasklet_release); DATA(tasklet_begin); DATA(tasklet_end); DATA(work_release); DATA(work_begin); DATA(work_end); DATA(effective_priority_change); DATA(nv_interrupt_begin); DATA(nv_interrupt_end); } data; } __attribute__((packed)); #undef DATA const char* event2name(unsigned int id); u64 event_time(struct st_event_record* rec); void print_event(struct st_event_record *rec); void print_all(struct st_event_record *rec, unsigned int count); #endif