# tracefs_iterate_raw_events

## NAME



           tracefs_iterate_raw_events, tracefs_iterate_stop,
           tracefs_follow_event, tracefs_follow_missed_events,
           tracefs_follow_event_clear, tracefs_follow_missed_events_clear,
           tracefs_iterate_snapshot_events - Iterate over events in the ring
           buffer
    


## SYNOPSIS



           **#include <tracefs.h>**
    
           int **tracefs_iterate_raw_events**(struct tep_handle *_tep_ , struct tracefs_instance *_instance_ ,
                                            cpu_set_t *_cpus_ , int _cpu_size_ ,
                                            int (*_callback_)(struct tep_event *, struct tep_record *, int, void *),
                                            void *_callback_context_);
           void **tracefs_iterate_stop**(struct tracefs_instance *_instance_);
    
           int **tracefs_follow_event**(struct tep_handle *_tep_ , struct tracefs_instance *_instance_ ,
                                     const char *_system_ , const char *_event_name_ ,
                                     int (*_callback_)(struct tep_event *,
                                                     struct tep_record *,
                                                     int, void *),
                                     void *_callback_data_);
           int **tracefs_follow_missed_events**(struct tracefs_instance *_instance_ ,
                                     int (*_callback_)(struct tep_event *,
                                                     struct tep_record *,
                                                     int, void *),
                                     void *_callback_data_);
    
           int **tracefs_follow_event_clear**(struct tracefs_instance *_instance_ ,
                                     const char *_system_ , const char *_event_name_);
           int **tracefs_follow_missed_events_clear**(struct tracefs_instance *_instance_);
    
           int **tracefs_iterate_snapshot_events**(struct tep_handle *_tep_ , struct tracefs_instance *_instance_ ,
                                            cpu_set_t *_cpus_ , int _cpu_size_ ,
                                            int (*_callback_)(struct tep_event *, struct tep_record *, int, void *),
                                            void *_callback_context_);
    


## DESCRIPTION



           Trace iterator over raw events.
    
           The **tracefs_iterate_raw_events()** function will read the tracefs
           raw data buffers and call the specified _callback_ function for
           every event it encounters. Events are iterated in sorted order:
           oldest first. An initialized _tep_ handler is required (See
           tracefs_local_events(3)). If _instance_ is NULL, then the toplevel
           tracefs buffer is used, otherwise the buffer for the corresponding
           _instance_ is read. To filter only on a subset of CPUs, _cpus_ and
           _cpu_size_ may be set to only call _callback_ with events that
           occurred on the CPUs specified, otherwise if _cpus_ is NULL then the
           _callback_ function will be called for all events, and _cpu_size_ is
           ignored. The _callback_ function will be called with the following
           parameters: A pointer to a struct tep_event that corresponds to
           the type of event the record is; The record representing the
           event; The CPU that the event occurred on; and a pointer to user
           specified _callback_context_. If the _callback_ returns non-zero, the
           iteration stops.
    
           The **tracefs_iterate_snapshot_events()** works the same as
           **tracefs_iterate_raw_events()** except that it works on the snapshot
           buffer.
    
           Use **tracefs_iterate_stop()** to force a executing
           **tracefs_iterate_raw_events()** to halt. This can be called from
           either a callback that is called by the iterator (even though a
           return of non-zero will stop it), or from another thread.
    
           The **tracefs_follow_event()** is used with
           **tracefs_iterate_raw_events()** but intead of the callback being
           called for every event, it is only called for the specified _system_
           / _event_name_ given to the function. The _callback_ is the same as
           for **tracefs_iterate_raw_events()** , and the passed in
           _callback_context_ will be passed to the _callback_ as well. Note, if
           it returns something other than 0, it will stop the loop before
           the _callback_ of **tracefs_iterate_raw_events()** is called.
    
           The **tracefs_follow_missed_events()** will call the _callback_ when
           missed events are detected. It will set the _record_ parameter of
           the callback to the record that came after the missed events and
           _event_ will be of the type of event _record_ is. _cpu_ will be set to
           the CPU that missed the events, and _callback_data_ will be the
           content that was passed in to the function.
    
           The **tracefs_follow_event_clear()** will remove followers from
           _instance_ that match _system_ and _event_name_. If _system_ and
           _event_name_ are both NULL, then it will remove all event followers
           associated to _instance_. If just _system_ is NULL, then it will
           remove all followers that follow events that match _event_name_. If
           just _event_name_ is NULL, then it will remove all followers that
           are attached to events that are apart of a system that matches
           _system_.
    
           The **tracefs_follow_missed_events_clear()** will remove all followers
           for missed events.
    


## RETURN VALUE



           The **tracefs_iterate_raw_events()** function returns -1 in case of an
           error or 0 otherwise.
    
           Both **tracefs_follow_event_clear()** and
           **tracefs_follow_missed_events_clear()** return 0 on success and -1 on
           error, or if it found no followers that match and should be
           removed.
    


## EXAMPLE



               #include <unistd.h>
               #include <tracefs.h>
               #include <stdbool.h>
               #include <signal.h>
    
               struct my_struct {
                       bool            stopped;
               };
    
               #define MAX_COUNT 500000
               static int counter;
    
               static int callback(struct tep_event *event, struct tep_record *record,
                                   int cpu, void *data)
               {
                       struct my_struct *my_data = data;
                       static struct trace_seq seq;
    
                       if (counter++ > MAX_COUNT) {
                               my_data->stopped = true;
                               return 1;
                       }
    
                       if (!seq.buffer)
                               trace_seq_init(&seq);
    
                       tep_print_event(event->tep, &seq, record, "%16s-%-5d [%03d] %6.1000d %s: %s\n",
                                       TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU,
                                       TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO);
                       trace_seq_terminate(&seq);
                       trace_seq_do_printf(&seq);
                       trace_seq_reset(&seq);
                       return 0;
               }
    
               static int sched_callback(struct tep_event *event, struct tep_record *record,
                                         int cpu, void *data)
               {
                       static struct tep_format_field *prev_pid;
                       static struct tep_format_field *next_pid;
                       unsigned long long pid;
                       int this_pid = *(int *)data;
    
                       if (!prev_pid) {
                               prev_pid = tep_find_field(event, "prev_pid");
                               next_pid = tep_find_field(event, "next_pid");
                               if (!prev_pid || !next_pid) {
                                       fprintf(stderr, "No pid fields??\n");
                                       return -1;
                               }
                       }
    
                       tep_read_number_field(prev_pid, record->data, &pid);
                       if (pid == this_pid)
                               printf("WE ARE LEAVING!\n");
                       tep_read_number_field(next_pid, record->data, &pid);
                       if (pid == this_pid)
                               printf("WE ARE ARRIVING!\n");
                       return 0;
               }
    
               static int missed_callback(struct tep_event *event, struct tep_record *record,
                                          int cpu, void *data)
               {
                       printf("OOPS! cpu %d dropped ", cpu);
                       if (record->missed_events > 0)
                               printf("%lld ", record->missed_events);
                       printf("events\n");
                       return 0;
               }
    
               static struct tracefs_instance *instance;
               static struct my_struct my_data;
    
               static void sig(int s)
               {
                       tracefs_iterate_stop(instance);
                       my_data.stopped = true;
               }
    
               int main (int argc, char **argv, char **env)
               {
                       struct tep_handle *tep;
                       int this_pid = getpid();
    
                       instance = tracefs_instance_create("my-buffer");
                       if (!instance)
                               return -1;
    
                       signal(SIGINT, sig);
    
                       tracefs_event_enable(instance, NULL, NULL);
                       sleep(1);
                       tracefs_event_disable(instance, NULL, NULL);
                       tep = tracefs_local_events(NULL);
                       tep_load_plugins(tep);
                       tracefs_follow_missed_events(instance, missed_callback, NULL);
                       tracefs_follow_event(tep, instance, "sched", "sched_switch", sched_callback, &this_pid);
                       tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, &my_data);
    
                       /* Note, the clear here is to show how to clear all followers
                        * in case tracefs_iterate_raw_events() is called again, but
                        * does not want to include the followers. It's not needed
                        * here because tracefs_instance_free() will clean them up.
                        */
                       tracefs_follow_event_clear(instance, NULL, NULL);
                       tracefs_follow_missed_events_clear(instance);
    
                       tracefs_instance_destroy(instance);
                       tracefs_instance_free(instance);
    
                       if (my_data.stopped) {
                               if (counter > MAX_COUNT)
                                       printf("Finished max count\n");
                               else
                                       printf("Finished via signal\n");
                       }
    
                       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) 2020 VMware, 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. tz.stoyanov@gmail.com
               mailto:tz.stoyanov@gmail.com
    
            3. linux-trace-devel@vger.kernel.org
               mailto:linux-trace-devel@vger.kernel.org
    


* * *