[go: up one dir, main page]

File: perf.h

package info (click to toggle)
uftrace 0.18.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,356 kB
  • sloc: ansic: 49,770; python: 11,181; asm: 837; makefile: 769; sh: 637; cpp: 627; javascript: 191
file content (140 lines) | stat: -rw-r--r-- 2,906 bytes parent folder | download | duplicates (3)
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
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef UFTRACE_PERF_H
#define UFTRACE_PERF_H

#include <linux/perf_event.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#define PERF_MMAP_SIZE (132 * 1024) /* 32 + 1 pages */
#define PERF_WATERMARK (8 * 1024) /* 2 pages */

#define COMM_LEN 16

struct uftrace_perf_writer {
	int *event_fd;
	void **page;
	uint64_t *data_pos;
	FILE **fp;
	int nr_event;
};

struct sample_id {
	uint32_t pid;
	uint32_t tid;
	uint64_t time;
};

struct perf_task_event {
	/*
	 * type: PERF_RECORD_FORK (7) or PERF_RECORD_EXIT (4)
	 */
	uint32_t pid, ppid;
	uint32_t tid, ptid;
	uint64_t time;
	struct sample_id sample_id;
};

struct perf_comm_event {
	/*
	 * type: PERF_RECORD_COMM (3)
	 */
	uint32_t pid, tid;
	/* variable length (aligned to 8) */
	char comm[COMM_LEN];
	/* needs to be read separately */
	struct sample_id sample_id;
};

struct perf_context_switch_event {
	/*
	 * type: PERF_RECORD_SWITCH (14)
	 * misc: PERF_RECORD_MISC_SWITCH_OUT (0x2000)
	 * size: 24
	 */
	struct sample_id sample_id;
};

struct uftrace_ctxsw_event {
	bool out;
	bool preempt;
};

struct uftrace_task_event {
	int pid;
	int ppid;
};

struct uftrace_comm_event {
	int pid;
	bool exec;
	char comm[COMM_LEN];
};

#ifdef HAVE_PERF_CLOCKID

int setup_perf_record(struct uftrace_perf_writer *perf, int nr_cpu, int pid, const char *dirname,
		      int use_ctxsw);
void finish_perf_record(struct uftrace_perf_writer *perf);
void record_perf_data(struct uftrace_perf_writer *perf, int cpu, int sock);

#else /* !HAVE_PERF_CLOCKID */

static inline int setup_perf_record(struct uftrace_perf_writer *perf, int nr_cpu, int pid,
				    const char *dirname, int use_ctxsw)
{
	return -1;
}

static inline void finish_perf_record(struct uftrace_perf_writer *perf)
{
}
static inline void record_perf_data(struct uftrace_perf_writer *perf, int cpu, int sock)
{
}

#endif /* HAVE_PERF_CLOCKID */

#ifndef PERF_RECORD_MISC_COMM_EXEC
#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
#endif

#ifdef HAVE_PERF_CTXSW
#define PERF_CTXSW_AVAILABLE 1

#else /* !HAVE_PERF_CTXSW */
#define PERF_CTXSW_AVAILABLE 0

#define PERF_RECORD_SWITCH 14
#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)

#endif /* HAVE_PERF_CTXSW */

#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)

struct uftrace_perf_reader {
	FILE *fp;
	bool valid;
	bool done;
	int type;
	int tid;
	uint64_t time;
	union {
		struct uftrace_ctxsw_event ctxsw;
		struct uftrace_task_event task;
		struct uftrace_comm_event comm;
	} u;
};

struct uftrace_data;
struct uftrace_record;

int setup_perf_data(struct uftrace_data *handle);
void finish_perf_data(struct uftrace_data *handle);
int read_perf_data(struct uftrace_data *handle);
struct uftrace_record *get_perf_record(struct uftrace_data *handle,
				       struct uftrace_perf_reader *perf);
void update_perf_task_comm(struct uftrace_data *handle);
void process_perf_event(struct uftrace_data *handle);

#endif /* UFTRACE_PERF_H */