Skip to content

Parallel Libtrace HOWTO: Start Callback

Shane Alcock edited this page Sep 21, 2015 · 4 revisions

Since we're going to need some thread local storage to keep track of the packets each thread has seen, we are going to begin by defining what our storage looks like and write the code to create and initialise this storage as soon as the thread starts.

We do this by defining what is called a "start callback", i.e. a function that is called when a thread starts for the first time (before any packets are read by that thread). Most non-trivial parallel libtrace programs will probably need some sort of local storage so you will generally require a start callback for your processing threads.

The code for our start callback is given below:

#include <libtrace_parallel.h>

/* Structure for storing our counters */
struct counters {
    uint64_t packets;
    uint64_t payload;
};

/* The start callback function */
static void *start_processing(libtrace_t *trace, libtrace_thread_t *thread,
        void *global) {
    
    /* Create and initialise a counter struct */
    struct counters *c = (struct counters *)malloc(sizeof(struct counters));
    c->packets = 0;
    c->payload = 0;

    /* Return our counter struct; it will now be available as one of the
     * arguments for all of the other processing callbacks.
     */
    return c;
}

Important things to note about this code:

  • All parallel libtrace programs must include the libtrace_parallel.h header file to gain access to the parallel API. All future code examples should be assumed to have included this header.
  • A start callback must take 3 parameters: an input trace, a libtrace thread and a void pointer to "global" data. A start callback always returns a void pointer, which is treated as local storage for the thread. In this example, we ignore all three parameters which is not uncommon; they're mostly just there in case you do need them.
  • The trace parameter is a reference back to the input trace that is being processed by this thread.
  • The thread parameter is a reference to the thread itself.
  • The global parameter is a pointer to global storage for the input trace that is shared across all of the threads associated with that trace. Simply cast this pointer to the appropriate type for whatever is stored at this address to access the global storage. Because global storage is shared across multiple threads, you should never modify the global storage inside a callback without locking it. Read operations without a lock are fine.

Now that we've got somewhere to keep track of our analysis, we can write our packet callback.

Clone this wiki locally