tracefs_cpu_read_size(3) — Linux manual page

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUE | EXAMPLE | FILES | SEE ALSO | AUTHOR | REPORTING BUGS | LICENSE | RESOURCES | COPYING | NOTES | COLOPHON

LIBTRACEFS(3)               libtracefs Manual               LIBTRACEFS(3)

NAME         top

       tracefs_cpu_read_size, tracefs_cpu_read,
       tracefs_cpu_buffered_read, tracefs_cpu_write, tracefs_cpu_stop,
       tracefs_cpu_flush, tracefs_cpu_flush_write, tracefs_cpu_pipe -
       Reading trace_pipe_raw data

SYNOPSIS         top

       #include <tracefs.h>

       int tracefs_cpu_read_size(struct tracefs_cpu *tcpu);
       int tracefs_cpu_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
       int tracefs_cpu_buffered_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
       int tracefs_cpu_write(struct tracefs_cpu *tcpu, int wfd, bool nonblock);
       int tracefs_cpu_stop(struct tracefs_cpu *tcpu);
       int tracefs_cpu_flush(struct tracefs_cpu *tcpu, void *buffer);
       int tracefs_cpu_flush_write(struct tracefs_cpu *tcpu, int wfd);
       int tracefs_cpu_pipe(struct tracefs_cpu *tcpu, int wfd, bool nonblock);

DESCRIPTION         top

       This set of APIs can be used to read the raw data from the
       trace_pipe_raw files in the tracefs file system.

       The tracefs_cpu_read_size() returns the subbuffer size of the
       trace_pipe_raw. This returns the minimum size of the buffer that
       is passed to the below functions.

       The tracefs_cpu_read() reads the trace_pipe_raw files associated
       to tcpu into buffer. buffer must be at least the size of the sub
       buffer of the ring buffer, which is returned by
       tracefs_cpu_read_size(). If nonblock is set, and there’s no data
       available, it will return immediately. Otherwise depending on how
       tcpu was opened, it will block. If tcpu was opened with nonblock
       set, then this nonblock will make no difference.

       The tracefs_cpu_buffered_read() is basically the same as
       tracefs_cpu_read() except that it uses a pipe through splice to
       buffer reads. This will batch reads keeping the reading from the
       ring buffer less intrusive to the system, as just reading all the
       time can cause quite a disturbance. Note, one difference between
       this and tracefs_cpu_read() is that it will read only in sub
       buffer pages. If the ring buffer has not filled a page, then it
       will not return anything, even with nonblock set. Calls to
       tracefs_cpu_flush() should be done to read the rest of the file at
       the end of the trace.

       The tracefs_cpu_write() will pipe the data from the trace_pipe_raw
       file associated with tcpu into the wfd file descriptor. If
       nonblock is set, then it will not block on if there’s nothing to
       write. Note, it will only write sub buffer size data to wfd. Calls
       to tracefs_cpu_flush_write() are needed to write out the rest.

       The tracefs_cpu_stop() will attempt to unblock a task blocked on
       tcpu reading it. On older kernels, it may not do anything for the
       pipe reads, as older kernels do not wake up tasks waiting on the
       ring buffer. Returns 0 if it definitely woke up any possible
       waiters, but returns 1 if it is not sure it worked and waiters may
       need to have a signal sent to them.

       The tracefs_cpu_flush() reads the trace_pipe_raw file associated
       by the tcpu and puts it into buffer, which must be the size of the
       sub buffer which is retrieved. by tracefs_cpu_read_size(). This
       should be called at the end of tracing to get the rest of the
       data. This call will convert the file descriptor of trace_pipe_raw
       into non-blocking mode.

       The tracefs_cpu_flush_write() same as trace_cpu_flush() except it
       takes a file descriptor wfd to flush the data into.

       The tracefs_cpu_pipe() is similar to tracefs_cpu_write() but the
       wfd file descriptor must be a pipe. This call is an optimization
       of tracefs_cpu_write() that uses two calls to splice(2) in order
       to connect the trace_pipe_raw file descriptor with the write file
       descriptor. splice(2) requires that one of the passed in file
       descriptors is a pipe. If the application wants to pass the data
       to an existing pipe, there’s no reason for there to be two
       splice(2) system calls and tracefs_cpu_pipe() can simply use a
       single call to wfd.

RETURN VALUE         top

       The tracefs_cpu_open() returns a struct tracefs_cpu descriptor
       that can be used by the other functions or NULL on error.

       The tracefs_cpu_read_size() returns the minimum size of the
       buffers to be used with tracefs_cpu_read(),
       tracefs_cpu_buffered_read() and tracefs_cpu_flush(). Returns
       negative on error.

       The tracefs_cpu_read() returns the number of bytes read, or
       negative on error.

       The tracefs_cpu_buffered_read() returns the number of bytes read
       or negative on error.

       The tracefs_cpu_write() returns the number of bytes written to the
       file or negative on error.

       The tracefs_cpu_stop() returns zero if any waiters were guaranteed
       to be woken up from waiting on input, or returns one if this is an
       older kernel that does not supply that guarantee, and a signal may
       need to be sent to any waiters. Returns negative on error.

       The tracefs_cpu_flush() returns the number of bytes read or
       negative on error.

       The tracefs_cpu_flush_write() returns the number of bytes written
       to the file or negative on error.

EXAMPLE         top

           #define _LARGEFILE64_SOURCE
           #include <stdlib.h>
           #include <ctype.h>
           #include <pthread.h>
           #include <unistd.h>
           #include <tracefs.h>

           struct thread_data {
                   struct tracefs_cpu      *tcpu;
                   int                     done;
                   int                     fd;
           };

           static void *thread_run(void *arg)
           {
                   struct thread_data *data = arg;
                   struct tracefs_cpu *tcpu = data->tcpu;
                   int fd = data->fd;
                   int ret;

                   while (!data->done) {
                           ret = tracefs_cpu_write(tcpu, fd, false);
                           printf("wrote %d\n", ret);
                   }
                   return NULL;
           }

           int main (int argc, char **argv)
           {
                   struct tracefs_instance *instance;
                   struct thread_data data;
                   pthread_t thread;
                   char *file;
                   int secs = 10;
                   int cpu;
                   int ret;

                   if (argc < 3 || !isdigit(argv[1][0])) {
                           printf("usage: %s cpu file_destination [sleep secs]\n\n", argv[0]);
                           exit(-1);
                   }

                   cpu = atoi(argv[1]);
                   file = argv[2];

                   if (argc > 3)
                           secs = atoi(argv[3]);

                   instance = tracefs_instance_create("cpu_write");
                   if (!instance) {
                           perror("create instance");
                           exit(-1);
                   }

                   memset(&data, 0, sizeof(data));

                   data.tcpu = tracefs_cpu_open(instance, cpu, 0);
                   if (!data.tcpu) {
                           perror("Open instance");
                           exit(-1);
                   }

                   data.fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
                   if (data.fd < 0) {
                           perror(file);
                           exit(-1);
                   }

                   pthread_create(&thread, NULL, thread_run, &data);

                   sleep(secs);

                   data.done = 1;
                   printf("stopping\n");
                   ret = tracefs_cpu_stop(data.tcpu);

                   printf("joining %d\n", ret);
                   pthread_join(thread, NULL);

                   tracefs_trace_off(instance);
                   do {
                           ret = tracefs_cpu_flush_write(data.tcpu, data.fd);
                           printf("flushed %d\n", ret);
                   } while (ret > 0);
                   tracefs_trace_on(instance);

                   tracefs_cpu_close(data.tcpu);
                   close(data.fd);

                   return 0;
           }

FILES         top

           tracefs.h
                   Header file to include in order to have access to the library APIs.
           -ltracefs
                   Linker switch to add when building a program that uses the library.

SEE ALSO         top

       tracefs_cpu_open(3) tracefs_cpu_close(3) tracefs_cpu_read_buf(3)
       tracefs_cpu_buffered_read_buf(3) tracefs_cpu_flush_buf(3)
       libtracefs(3), libtraceevent(3), trace-cmd(1)

AUTHOR         top

           Steven Rostedt <rostedt@goodmis.org[1]>

REPORTING BUGS         top

       Report bugs to <linux-trace-devel@vger.kernel.org[2]>

LICENSE         top

       libtracefs is Free Software licensed under the GNU LGPL 2.1

RESOURCES         top

       https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 

COPYING         top

       Copyright (C) 2022 Google, Inc. Free use of this software is
       granted under the terms of the GNU Public License (GPL).

NOTES         top

        1. rostedt@goodmis.org
           mailto:rostedt@goodmis.org

        2. linux-trace-devel@vger.kernel.org
           mailto:linux-trace-devel@vger.kernel.org

COLOPHON         top

       This page is part of the libtracefs (Linux kernel trace file
       system library) project.  Information about the project can be
       found at ⟨https://www.trace-cmd.org/⟩.  If you have a bug report
       for this manual page, see ⟨https://www.trace-cmd.org/⟩.  This page
       was obtained from the project's upstream Git repository
       ⟨https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git⟩ on
       2025-02-02.  (At that time, the date of the most recent commit
       that was found in the repository was 2024-11-22.)  If you discover
       any rendering problems in this HTML version of the page, or you
       believe there is a better or more up-to-date source for the page,
       or you have corrections or improvements to the information in this
       COLOPHON (which is not part of the original manual page), send a
       mail to man-pages@man7.org

libtracefs 1.8.1                01/02/2025                  LIBTRACEFS(3)

Pages that refer to this page: tracefs_cpu_open(3)tracefs_cpu_open_mapped(3)tracefs_cpu_read_buf(3)tracefs_instance_get_name(3)