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) 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
       2023-12-22.  (At that time, the date of the most recent commit
       that was found in the repository was 2023-07-05.)  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.7.0               12/22/2023                  LIBTRACEFS(3)

Pages that refer to this page: tracefs_cpu_open(3)