# tracefs_cpu_read_size

## NAME



           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



           **#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



           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



           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



               #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



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


## LICENSE



           libtracefs is Free Software licensed under the GNU LGPL 2.1
    


## RESOURCES



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


## COPYING



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


## NOTES



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


* * *