xref: /aosp_15_r20/external/libtracefs/Documentation/libtracefs-cpu.txt (revision 287e80b3a36113050663245e7f2c00d274188f18)
1libtracefs(3)
2=============
3
4NAME
5----
6tracefs_cpu_read_size, tracefs_cpu_read, tracefs_cpu_buffered_read, tracefs_cpu_write,
7tracefs_cpu_stop, tracefs_cpu_flush, tracefs_cpu_flush_write, tracefs_cpu_pipe
8- Reading trace_pipe_raw data
9
10SYNOPSIS
11--------
12[verse]
13--
14*#include <tracefs.h>*
15
16int *tracefs_cpu_read_size*(struct tracefs_cpu pass:[*]_tcpu_);
17int *tracefs_cpu_read*(struct tracefs_cpu pass:[*]_tcpu_, void pass:[*]_buffer_, bool _nonblock_);
18int *tracefs_cpu_buffered_read*(struct tracefs_cpu pass:[*]_tcpu_, void pass:[*]_buffer_, bool _nonblock_);
19int *tracefs_cpu_write*(struct tracefs_cpu pass:[*]_tcpu_, int _wfd_, bool _nonblock_);
20int *tracefs_cpu_stop*(struct tracefs_cpu pass:[*]_tcpu_);
21int *tracefs_cpu_flush*(struct tracefs_cpu pass:[*]_tcpu_, void pass:[*]_buffer_);
22int *tracefs_cpu_flush_write*(struct tracefs_cpu pass:[*]_tcpu_, int _wfd_);
23int *tracefs_cpu_pipe*(struct tracefs_cpu pass:[*]_tcpu_, int _wfd_, bool _nonblock_);
24--
25
26DESCRIPTION
27-----------
28This set of APIs can be used to read the raw data from the trace_pipe_raw
29files in the tracefs file system.
30
31The *tracefs_cpu_read_size()* returns the subbuffer size of the trace_pipe_raw. This
32returns the minimum size of the buffer that is passed to the below functions.
33
34The *tracefs_cpu_read()* reads the trace_pipe_raw files associated to _tcpu_ into _buffer_.
35_buffer_ must be at least the size of the sub buffer of the ring buffer,
36which is returned by *tracefs_cpu_read_size()*. If _nonblock_ is set, and
37there's no data available, it will return immediately. Otherwise depending
38on how _tcpu_ was opened, it will block. If _tcpu_ was opened with nonblock
39set, then this _nonblock_ will make no difference.
40
41The *tracefs_cpu_buffered_read()* is basically the same as *tracefs_cpu_read()*
42except that it uses a pipe through splice to buffer reads. This will batch
43reads keeping the reading from the ring buffer less intrusive to the system,
44as just reading all the time can cause quite a disturbance. Note, one
45difference between this and *tracefs_cpu_read()* is that it will read only in
46sub buffer pages. If the ring buffer has not filled a page, then it will not
47return anything, even with _nonblock_ set.  Calls to *tracefs_cpu_flush()*
48should be done to read the rest of the file at the end of the trace.
49
50The *tracefs_cpu_write()* will pipe the data from the trace_pipe_raw
51file associated with _tcpu_ into the _wfd_ file descriptor. If _nonblock_ is set,
52then it will not block on if there's nothing to write. Note, it will only write
53sub buffer size data to _wfd_. Calls to tracefs_cpu_flush_write() are needed to
54write out the rest.
55
56The *tracefs_cpu_stop()* will attempt to unblock a task blocked on _tcpu_ reading it.
57On older kernels, it may not do anything for the pipe reads, as older kernels do not
58wake up tasks waiting on the ring buffer. Returns 0 if it definitely woke up any possible
59waiters, but returns 1 if it is not sure it worked and waiters may need to have a signal
60sent to them.
61
62The *tracefs_cpu_flush()* reads the trace_pipe_raw file associated by the _tcpu_ and puts it
63into _buffer_, which must be the size of the sub buffer which is retrieved.
64by *tracefs_cpu_read_size()*. This should be called at the end of tracing
65to get the rest of the data. This call will convert the file descriptor of
66trace_pipe_raw into non-blocking mode.
67
68The *tracefs_cpu_flush_write()* same as *trace_cpu_flush()* except it takes a file
69descriptor _wfd_ to flush the data into.
70
71The *tracefs_cpu_pipe()* is similar to *tracefs_cpu_write()* but the _wfd_ file descriptor
72must be a pipe. This call is an optimization of *tracefs_cpu_write()* that uses two calls
73to *splice*(2) in order to connect the trace_pipe_raw file descriptor with the write file
74descriptor. *splice*(2) requires that one of the passed in file descriptors is a pipe.
75If the application wants to pass the data to an existing pipe, there's no reason for
76there to be two *splice*(2) system calls and *tracefs_cpu_pipe()* can simply use a single
77call to _wfd_.
78
79RETURN VALUE
80------------
81The *tracefs_cpu_open()* returns a struct tracefs_cpu descriptor that can be
82used by the other functions or NULL on error.
83
84The *tracefs_cpu_read_size()* returns the minimum size of the buffers to be
85used with *tracefs_cpu_read()*, *tracefs_cpu_buffered_read()* and *tracefs_cpu_flush()*.
86Returns negative on error.
87
88The *tracefs_cpu_read()* returns the number of bytes read, or negative on error.
89
90The *tracefs_cpu_buffered_read()* returns the number of bytes read or negative on error.
91
92The *tracefs_cpu_write()* returns the number of bytes written to the file
93or negative on error.
94
95The *tracefs_cpu_stop()* returns zero if any waiters were guaranteed to be
96woken up from waiting on input, or returns one if this is an older kernel
97that does not supply that guarantee, and a signal may need to be sent to
98any waiters. Returns negative on error.
99
100The *tracefs_cpu_flush()* returns the number of bytes read or negative on error.
101
102The *tracefs_cpu_flush_write()* returns the number of bytes written to the
103file  or negative on error.
104
105EXAMPLE
106-------
107[source,c]
108--
109#define _LARGEFILE64_SOURCE
110#include <stdlib.h>
111#include <ctype.h>
112#include <pthread.h>
113#include <unistd.h>
114#include <tracefs.h>
115
116struct thread_data {
117	struct tracefs_cpu	*tcpu;
118	int			done;
119	int			fd;
120};
121
122static void *thread_run(void *arg)
123{
124	struct thread_data *data = arg;
125	struct tracefs_cpu *tcpu = data->tcpu;
126	int fd = data->fd;
127	int ret;
128
129	while (!data->done) {
130		ret = tracefs_cpu_write(tcpu, fd, false);
131		printf("wrote %d\n", ret);
132	}
133	return NULL;
134}
135
136int main (int argc, char **argv)
137{
138	struct tracefs_instance *instance;
139	struct thread_data data;
140	pthread_t thread;
141	char *file;
142	int secs = 10;
143	int cpu;
144	int ret;
145
146	if (argc < 3 || !isdigit(argv[1][0])) {
147		printf("usage: %s cpu file_destination [sleep secs]\n\n", argv[0]);
148		exit(-1);
149	}
150
151	cpu = atoi(argv[1]);
152	file = argv[2];
153
154	if (argc > 3)
155		secs = atoi(argv[3]);
156
157	instance = tracefs_instance_create("cpu_write");
158	if (!instance) {
159		perror("create instance");
160		exit(-1);
161	}
162
163	memset(&data, 0, sizeof(data));
164
165	data.tcpu = tracefs_cpu_open(instance, cpu, 0);
166	if (!data.tcpu) {
167		perror("Open instance");
168		exit(-1);
169	}
170
171	data.fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
172	if (data.fd < 0) {
173		perror(file);
174		exit(-1);
175	}
176
177	pthread_create(&thread, NULL, thread_run, &data);
178
179	sleep(secs);
180
181	data.done = 1;
182	printf("stopping\n");
183	ret = tracefs_cpu_stop(data.tcpu);
184
185	printf("joining %d\n", ret);
186	pthread_join(thread, NULL);
187
188	tracefs_trace_off(instance);
189	do {
190		ret = tracefs_cpu_flush_write(data.tcpu, data.fd);
191		printf("flushed %d\n", ret);
192	} while (ret > 0);
193	tracefs_trace_on(instance);
194
195	tracefs_cpu_close(data.tcpu);
196	close(data.fd);
197
198	return 0;
199}
200--
201FILES
202-----
203[verse]
204--
205*tracefs.h*
206	Header file to include in order to have access to the library APIs.
207*-ltracefs*
208	Linker switch to add when building a program that uses the library.
209--
210
211SEE ALSO
212--------
213*tracefs_cpu_open*(3)
214*tracefs_cpu_close*(3)
215*libtracefs*(3),
216*libtraceevent*(3),
217*trace-cmd*(1)
218
219AUTHOR
220------
221[verse]
222--
223*Steven Rostedt* <[email protected]>
224--
225REPORTING BUGS
226--------------
227Report bugs to  <[email protected]>
228
229LICENSE
230-------
231libtracefs is Free Software licensed under the GNU LGPL 2.1
232
233RESOURCES
234---------
235https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
236
237COPYING
238-------
239Copyright \(C) 2022 Google, Inc. Free use of this software is granted under
240the terms of the GNU Public License (GPL).
241