summaryrefslogtreecommitdiffstats
path: root/include/sched_trace.h
blob: 04d5743332692819c67bd70e5fda7ed5f3b4a5bd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef __SCHED_TRACE_H_
#define __SCHED_TRACE_H_

#include <stdint.h>

typedef uint8_t  u8;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint64_t u64;

/* 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.      */
};

#define ST_NAME_LEN 16
struct st_name_data {
	char	cmd[ST_NAME_LEN];/* The name of the executable of this process. */
};

struct st_param_data {		/* regular params */
	u32	wcet;
	u32	period;
	u32	phase;
	u8	partition;
	u8	__unused[3];
};

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?		 */
};

struct st_assigned_data {	/* A job was asigned to a CPU. 		 */
	u64	when;
	u8	target;		/* Where should it execute?	         */
	u8	__unused[3];
};

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.          */

};

struct st_switch_away_data {	/* A process was switched away from on a given CPU. */
	u64	when;
	u64	exec_time;
};

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];
};

struct st_block_data {		/* A task blocks. */
	u64	when;
	u64	__unused;
};

struct st_resume_data {		/* A task resumes. */
	u64	when;
	u64	__unused;
};

struct st_sys_release_data {
	u64	when;
	u64	release;
};

#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_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(sys_release);

	} data;
};

#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