]> git.lttng.org Git - lttv.git/commitdiff
Make the synchronization module interfaces more generic
authorBenjamin Poirier <benjamin.poirier@polymtl.ca>
Thu, 8 Oct 2009 20:03:07 +0000 (16:03 -0400)
committerBenjamin Poirier <benjamin.poirier@polymtl.ca>
Fri, 18 Dec 2009 19:03:24 +0000 (14:03 -0500)
Instead of taking NetEvents and Packets, public interfaces take Events,
Messages and Exchanges. These are specialized into other structures for TCP.
This is to support the eventual integration of algorithms based on other event
types, like UDP.

Signed-off-by: Benjamin Poirier <benjamin.poirier@polymtl.ca>
34 files changed:
lttv/lttv/Makefile.am
lttv/lttv/sync/Makefile.am
lttv/lttv/sync/data_structures.c [new file with mode: 0644]
lttv/lttv/sync/data_structures.h [new file with mode: 0644]
lttv/lttv/sync/data_structures_tcp.c [deleted file]
lttv/lttv/sync/data_structures_tcp.h [deleted file]
lttv/lttv/sync/event_analysis.h
lttv/lttv/sync/event_analysis_chull.c
lttv/lttv/sync/event_analysis_chull.h
lttv/lttv/sync/event_analysis_linreg.c
lttv/lttv/sync/event_analysis_linreg.h
lttv/lttv/sync/event_matching.h
lttv/lttv/sync/event_matching_tcp.c
lttv/lttv/sync/event_matching_tcp.h
lttv/lttv/sync/event_processing.h
lttv/lttv/sync/event_processing_lttng_common.c [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttng_common.h [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttng_null.c [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttng_null.h [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttng_standard.c [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttng_standard.h [new file with mode: 0644]
lttv/lttv/sync/event_processing_lttv_common.c [deleted file]
lttv/lttv/sync/event_processing_lttv_common.h [deleted file]
lttv/lttv/sync/event_processing_lttv_null.c [deleted file]
lttv/lttv/sync/event_processing_lttv_null.h [deleted file]
lttv/lttv/sync/event_processing_lttv_standard.c [deleted file]
lttv/lttv/sync/event_processing_lttv_standard.h [deleted file]
lttv/lttv/sync/sync_chain.c [deleted file]
lttv/lttv/sync/sync_chain.h [deleted file]
lttv/lttv/sync/sync_chain_lttv.c [new file with mode: 0644]
lttv/lttv/sync/sync_chain_lttv.h [new file with mode: 0644]
lttv/lttv/sync/unittest.c
lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
lttv/modules/text/batchAnalysis.c

index 58fd59586badbaeda401fa484faef95e0d240d0f..3738b81209dcfd0cae83a7e2f6a5d3d6e4d9dc91 100644 (file)
@@ -55,11 +55,11 @@ lttv_real_SOURCES = \
        traceset.c\
        filter.c\
        print.c\
-       sync/sync_chain.c\
-       sync/data_structures_tcp.c\
-       sync/event_processing_lttv_common.c\
-       sync/event_processing_lttv_standard.c\
-       sync/event_processing_lttv_null.c\
+       sync/sync_chain_lttv.c\
+       sync/data_structures.c\
+       sync/event_processing_lttng_common.c\
+       sync/event_processing_lttng_standard.c\
+       sync/event_processing_lttng_null.c\
        sync/event_matching_tcp.c\
        sync/event_analysis_linreg.c\
        sync/event_analysis_chull.c
index 9a5c8b6c24c953f14a57d59323e0d3d479ca0ee0..dbe9ed59db4b88b7cc14609835771d4cbfe76bcc 100644 (file)
@@ -5,7 +5,7 @@ check_PROGRAMS = unittest
 
 unittest_SOURCES = \
        unittest.c\
-       data_structures_tcp.c\
+       data_structures.c\
        event_matching_tcp.c\
        event_analysis_linreg.c\
        event_analysis_chull.c
diff --git a/lttv/lttv/sync/data_structures.c b/lttv/lttv/sync/data_structures.c
new file mode 100644 (file)
index 0000000..6206969
--- /dev/null
@@ -0,0 +1,455 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <arpa/inet.h>
+#include <glib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include "lookup3.h"
+
+#include "data_structures.h"
+
+
+#ifndef g_info
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#endif
+
+// TCP sequence numbers use clock arithmetic, these comparison functions take
+// that into account
+#define SEQ_LT(a,b)     ((int32_t)((a)-(b)) < 0)
+#define SEQ_LEQ(a,b)    ((int32_t)((a)-(b)) <= 0)
+#define SEQ_GT(a,b)     ((int32_t)((a)-(b)) > 0)
+#define SEQ_GEQ(a,b)    ((int32_t)((a)-(b)) >= 0)
+
+
+/*
+ * Compare two ConnectionKey structures
+ *
+ * Returns:
+ *   true if each field of the structure is equal
+ *   false otherwise
+ */
+bool connectionKeyEqual(const ConnectionKey* const a, const
+       ConnectionKey* const b)
+{
+       if (a->saddr == b->saddr && a->daddr == b->daddr && a->source == b->source
+               && a->dest == b->dest)
+       {
+               return true;
+       }
+       else
+       {
+               return false;
+       }
+}
+
+
+/*
+ * Check if a packet is an acknowledge of another packet.
+ *
+ * Args:
+ *   ackSegment    packet that is the confirmation
+ *   ackedSegment  packet that contains the original data, both packets have to
+ *                 come from the same direction of the same connection. Both
+ *                 messages have to contain TCP events.
+ */
+bool isAcking(const Message* const ackSegment, const Message* const
+       ackedSegment)
+{
+       g_assert(ackSegment->inE->type == TCP);
+       g_assert(ackSegment->outE->type == TCP);
+
+       if (SEQ_GT(ackSegment->inE->event.tcpEvent->segmentKey->ack_seq,
+                       ackedSegment->inE->event.tcpEvent->segmentKey->seq))
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+/*
+ * Convert an IP address from 32 bit form to dotted quad
+ *
+ * Args:
+ *   str:          A preallocated string of length >= 17
+ *   addr:         Address
+ */
+void convertIP(char* const str, const uint32_t addr)
+{
+       struct in_addr iaddr;
+
+       iaddr.s_addr= htonl(addr);
+       strcpy(str, inet_ntoa(iaddr));
+}
+
+
+/*
+ * Print the content of a TCP Message structure
+ */
+void printTCPSegment(const Message* const segment)
+{
+       char saddr[17], daddr[17];
+       SegmentKey* segmentKey;
+
+       g_assert(segment->inE->type == TCP);
+       g_assert(segment->inE->event.tcpEvent->segmentKey ==
+               segment->outE->event.tcpEvent->segmentKey);
+
+       segmentKey= segment->inE->event.tcpEvent->segmentKey;
+
+       convertIP(saddr, segmentKey->connectionKey.saddr);
+       convertIP(daddr, segmentKey->connectionKey.daddr);
+       g_debug("%s:%u to %s:%u tot_len: %u ihl: %u seq: %u ack_seq: %u doff: %u "
+               "ack: %u rst: %u syn: %u fin: %u", saddr,
+               segmentKey->connectionKey.source, daddr, segmentKey->connectionKey.dest,
+               segmentKey->tot_len, segmentKey->ihl, segmentKey->seq,
+               segmentKey->ack_seq, segmentKey->doff, segmentKey->ack, segmentKey->rst,
+               segmentKey->syn, segmentKey->fin);
+}
+
+
+/*
+ * A GHashFunc for g_hash_table_new()
+ *
+ * This function is for indexing TCPEvents in unMatched lists. All fields of
+ * the corresponding SegmentKey must match for two keys to be equal.
+ *
+ * Args:
+ *   key           SegmentKey*
+ *
+ * Returns:
+ *   A hash of all fields in the SegmentKey
+ */
+guint ghfSegmentKeyHash(gconstpointer key)
+{
+       const SegmentKey* p;
+       uint32_t a, b, c;
+
+       p= (SegmentKey*) key;
+
+       a= p->connectionKey.source + (p->connectionKey.dest << 16);
+       b= p->connectionKey.saddr;
+       c= p->connectionKey.daddr;
+       mix(a, b, c);
+
+       a+= p->ihl + (p->tot_len << 8) + (p->doff << 24);
+       b+= p->seq;
+       c+= p->ack_seq;
+       mix(a, b, c);
+
+       a+= p->ack + (p->rst << 8) + (p->syn << 16) + (p->fin << 24);
+       final(a, b, c);
+
+       g_debug("segment key hash %p: %u", p, c);
+
+       return c;
+}
+
+
+/*
+ * A GEqualFunc for g_hash_table_new()
+ *
+ * This function is for indexing TCPEvents in unMatched lists. All fields of
+ * the corresponding SegmentKey must match for two keys to be equal.
+ *
+ * Args:
+ *   a, b          SegmentKey*
+ *
+ * Returns:
+ *   TRUE if both values are equal
+ */
+gboolean gefSegmentKeyEqual(gconstpointer a, gconstpointer b)
+{
+       const SegmentKey* sA, * sB;
+
+       sA= (SegmentKey*) a;
+       sB= (SegmentKey*) b;
+
+       if (connectionKeyEqual(&sA->connectionKey, &sB->connectionKey) &&
+               sA->ihl == sB->ihl &&
+               sA->tot_len == sB->tot_len &&
+               sA->seq == sB->seq &&
+               sA->ack_seq == sB->ack_seq &&
+               sA->doff == sB->doff &&
+               sA->ack == sB->ack &&
+               sA->rst == sB->rst &&
+               sA->syn == sB->syn &&
+               sA->fin == sB->fin)
+       {
+               g_debug("segment key equal %p %p: TRUE", sA, sB);
+               return TRUE;
+       }
+       else
+       {
+               g_debug("segment key equal %p %p: FALSE", sA, sB);
+               return FALSE;
+       }
+}
+
+
+/*
+ * A GDestroyNotify function for g_hash_table_new_full()
+ *
+ * Args:
+ *   data:         Event*
+ */
+void gdnDestroyEvent(gpointer data)
+{
+       Event* event= data;
+
+       event->destroy(event);
+}
+
+
+/*
+ * A GDestroyNotify function for g_hash_table_new_full()
+ *
+ * Args:
+ *   data:         GQueue* list[Packet]
+ */
+void gdnTCPSegmentListDestroy(gpointer data)
+{
+       GQueue* list;
+
+       list= (GQueue*) data;
+
+       g_debug("XXXX gdnTCPSegmentListDestroy\n");
+
+       g_queue_foreach(list, &gfTCPSegmentDestroy, NULL);
+       g_queue_free(list);
+}
+
+
+/*
+ * A GFunc for g_queue_foreach()
+ *
+ * Args:
+ *   data          Message*, TCP message to destroy
+ *   user_data     NULL
+ */
+void gfTCPSegmentDestroy(gpointer data, gpointer user_data)
+{
+       g_debug("XXXX gfTCPSegmentDestroy\n");
+       destroyTCPSegment((Message*) data);
+}
+
+
+/*
+ * Free the memory used by a TCP Message and the memory of all its associated
+ * resources
+ *
+ * Args:
+ *   segment       TCP Message to destroy
+ */
+void destroyTCPSegment(Message* const segment)
+{
+       TCPEvent* inE, *outE;
+
+       g_debug("XXXX destroyTCPSegment");
+       segment->print(segment);
+
+       g_assert(segment->inE != NULL && segment->outE != NULL);
+       g_assert(segment->inE->type == TCP && segment->outE->type == TCP);
+       inE= segment->inE->event.tcpEvent;
+       outE= segment->outE->event.tcpEvent;
+       g_assert(inE->segmentKey == outE->segmentKey);
+
+       outE->segmentKey= NULL;
+
+       destroyTCPEvent(segment->inE);
+       destroyTCPEvent(segment->outE);
+
+       free(segment);
+}
+
+
+/*
+ * Free the memory used by a TCP Exchange and the memory of SOME of its
+ * associated resources. The message is not destroyed. Use destroyTCPSegment()
+ * to free it.
+ *
+ * Args:
+ *   exchange      TCP Exchange to destroy. The .message must be NULL
+ */
+void destroyTCPExchange(Exchange* const exchange)
+{
+       g_assert(exchange->message == NULL);
+
+       if (exchange->acks != NULL)
+       {
+               g_queue_foreach(exchange->acks, &gfTCPSegmentDestroy, NULL);
+               g_queue_free(exchange->acks);
+       }
+
+       free(exchange);
+}
+
+
+/*
+ * Free the memory used by a TCP Event and its associated resources
+ */
+void destroyTCPEvent(Event* const event)
+{
+       g_assert(event->type == TCP);
+
+       if (event->event.tcpEvent->segmentKey != NULL)
+       {
+               free(event->event.tcpEvent->segmentKey);
+       }
+       free(event->event.tcpEvent);
+       event->event.tcpEvent= NULL;
+       destroyEvent(event);
+}
+
+/*
+ * Free the memory used by a base Event
+ */
+void destroyEvent(Event* const event)
+{
+       g_assert(event->event.tcpEvent == NULL);
+
+       free(event);
+}
+
+
+/*
+ * Free the memory used by a UDP Event and its associated resources
+ */
+void destroyUDPEvent(Event* const event)
+{
+       g_assert(event->type == UDP);
+
+       if (event->event.udpEvent->datagramKey != NULL)
+       {
+               free(event->event.udpEvent->datagramKey);
+       }
+       free(event->event.udpEvent);
+       event->event.udpEvent= NULL;
+       destroyEvent(event);
+}
+
+
+/*
+ * A GCompareFunc for g_queue_find_custom()
+ *
+ * Args:
+ *   a          Message* acked packet
+ *   b          Message* ack packet
+ *
+ * Returns:
+ *   0 if b acks a
+ */
+gint gcfTCPSegmentAckCompare(gconstpointer a, gconstpointer b)
+{
+       if (isAcking((const Message*) b, (const Message*) a))
+       {
+               return 0;
+       }
+       else
+       {
+               return 1;
+       }
+}
+
+
+/*
+ * A GHashFunc for g_hash_table_new()
+ *
+ * Hash TCP connection keys. Here are a few possible implementations:
+ *
+ * 2.4 kernels used tcp_hashfn()
+ *
+ * I've seen something about an XOR hash:
+ * http://tservice.net.ru/~s0mbre/blog/2006/05/14#2006_05_14:
+ * unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+ * h ^= h >> 16;
+ * h ^= h >> 8;
+ * return h;
+ *
+ * In 2.6 kernels, inet_ehashfn() handles connection hashing with the help of
+ * Jenkins hashing, jhash.h
+ *
+ * This function uses jenkins hashing. The hash is not the same for packets in
+ * opposite directions of the same connection. (Hence the name
+ * connection*key*hash)
+ *
+ * Args:
+ *    key        ConnectionKey*
+ */
+guint ghfConnectionKeyHash(gconstpointer key)
+{
+       ConnectionKey* connectionKey;
+       uint32_t a, b, c;
+
+       connectionKey= (ConnectionKey*) key;
+
+       a= connectionKey->source + (connectionKey->dest << 16);
+       b= connectionKey->saddr;
+       c= connectionKey->daddr;
+       final(a, b, c);
+
+       return c;
+}
+
+
+/*
+ * A GEqualFunc for g_hash_table_new()
+ *
+ * Args:
+ *   a, b          ConnectionKey*
+ *
+ * Returns:
+ *   TRUE if both values are equal
+ */
+gboolean gefConnectionKeyEqual(gconstpointer a, gconstpointer b)
+{
+       // Two packets in the same direction
+       if (connectionKeyEqual((const ConnectionKey*) a, (const ConnectionKey*) b))
+       {
+               return TRUE;
+       }
+       else
+       {
+               return FALSE;
+       }
+}
+
+
+/*
+ * A GDestroyNotify function for g_hash_table_new_full()
+ *
+ * Args:
+ *   data:         ConnectionKey*
+ */
+void gdnConnectionKeyDestroy(gpointer data)
+{
+       free((ConnectionKey*) data);
+}
diff --git a/lttv/lttv/sync/data_structures.h b/lttv/lttv/sync/data_structures.h
new file mode 100644 (file)
index 0000000..082bbdf
--- /dev/null
@@ -0,0 +1,147 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef DATA_STRUCTURES_H
+#define DATA_STRUCTURES_H
+
+#include <glib.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <ltt/ltt.h>
+
+// Stage 1 to 2: These structures are passed from processing to matching modules
+// TCP events
+typedef struct
+{
+       uint32_t saddr, daddr;
+       uint16_t source, dest;
+} ConnectionKey;
+
+typedef struct
+{
+       ConnectionKey connectionKey;
+       uint8_t ihl;
+       uint16_t tot_len;
+       uint32_t seq, ack_seq;
+       uint8_t doff;
+       uint8_t ack, rst, syn, fin;
+} SegmentKey;
+
+enum Direction
+{
+       OUT,
+       IN,
+};
+
+typedef struct
+{
+       enum Direction direction;
+       SegmentKey* segmentKey;
+} TCPEvent;
+
+// UDP events
+typedef struct
+{
+       uint32_t saddr, daddr;
+       uint8_t dataKey[8];
+} DatagramKey;
+
+typedef struct
+{
+       enum Direction direction;
+       DatagramKey* datagramKey;
+       bool unicast;
+} UDPEvent;
+
+typedef struct _Event
+{
+       unsigned long traceNum;
+       uint64_t time;
+
+       // specific event structures and functions could be in separate files and
+       // type could be an int
+       enum {TCP, UDP} type;
+       // event could be a void*, this union is to avoid having to cast
+       union {
+               TCPEvent* tcpEvent;
+               UDPEvent* udpEvent;
+       } event;
+
+       void (*destroy)(struct _Event* const event);
+} Event;
+
+// Stage 2 to 3: These structures are passed from matching to analysis modules
+typedef struct _Message
+{
+       Event* inE, * outE;
+
+       void (*print)(const struct _Message* const message);
+} Message;
+
+typedef struct
+{
+       Message* message;
+       GQueue* acks;
+} Exchange;
+
+typedef struct
+{
+       GQueue* events;
+} Broadcast;
+
+// One set of factors for each trace, this is the result of synchronization
+typedef struct
+{
+       double drift, offset;
+} Factors;
+
+
+// ConnectionKey-related functions
+guint ghfConnectionKeyHash(gconstpointer key);
+
+gboolean gefConnectionKeyEqual(gconstpointer a, gconstpointer b);
+bool connectionKeyEqual(const ConnectionKey* const a, const ConnectionKey*
+       const b);
+
+void gdnConnectionKeyDestroy(gpointer data);
+
+// SegmentKey-related functions
+guint ghfSegmentKeyHash(gconstpointer key);
+gboolean gefSegmentKeyEqual(gconstpointer a, gconstpointer b);
+
+// Event-related functions
+void gdnDestroyEvent(gpointer data);
+void destroyEvent(Event* const event);
+void destroyTCPEvent(Event* const event);
+void destroyUDPEvent(Event* const event);
+
+// Message-related functions
+void printTCPSegment(const Message* const segment);
+void convertIP(char* const str, const uint32_t addr);
+
+gint gcfTCPSegmentAckCompare(gconstpointer a, gconstpointer b);
+bool isAcking(const Message* const ackSegment, const Message* const ackedSegment);
+
+void gdnTCPSegmentListDestroy(gpointer data);
+void gfTCPSegmentDestroy(gpointer data, gpointer user_data);
+void destroyTCPSegment(Message* const segment);
+
+// Exchange-related functions
+void destroyTCPExchange(Exchange* const exchange);
+#endif
diff --git a/lttv/lttv/sync/data_structures_tcp.c b/lttv/lttv/sync/data_structures_tcp.c
deleted file mode 100644 (file)
index 4db0309..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <arpa/inet.h>
-#include <glib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <unistd.h>
-
-#include "lookup3.h"
-
-#include "data_structures_tcp.h"
-
-
-#ifndef g_info
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-// TCP sequence numbers use clock arithmetic, these comparison functions take
-// that into account
-#define SEQ_LT(a,b)     ((int32_t)((a)-(b)) < 0)
-#define SEQ_LEQ(a,b)    ((int32_t)((a)-(b)) <= 0)
-#define SEQ_GT(a,b)     ((int32_t)((a)-(b)) > 0)
-#define SEQ_GEQ(a,b)    ((int32_t)((a)-(b)) >= 0)
-
-
-/*
- * Compare two ConnectionKey structures
- *
- * Returns:
- *   true if each field of the structure is equal
- *   false otherwise
- */
-bool connectionKeyEqual(const ConnectionKey* const a, const
-       ConnectionKey* const b)
-{
-       if (a->saddr == b->saddr && a->daddr == b->daddr && a->source == b->source
-               && a->dest == b->dest)
-       {
-               return true;
-       }
-       else
-       {
-               return false;
-       }
-}
-
-
-/*
- * Check if a packet is an acknowledge of another packet.
- *
- * Args:
- *   ackPacket     packet that is the confirmation
- *   ackedPacket   packet that contains the original data, both packets have to
- *                 come from the same direction of the same connection
- */
-bool isAcking(const Packet* const ackPacket, const Packet* const
-       ackedPacket)
-{
-       if (SEQ_GT(ackPacket->inE->packetKey->ack_seq,
-                       ackedPacket->inE->packetKey->seq))
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-
-/*
- * Convert an IP address from 32 bit form to dotted quad
- *
- * Args:
- *   str:          A preallocated string of length >= 17
- *   addr:         Address
- */
-void convertIP(char* const str, const uint32_t addr)
-{
-       struct in_addr iaddr;
-
-       iaddr.s_addr= htonl(addr);
-       strcpy(str, inet_ntoa(iaddr));
-}
-
-
-/*
- * Print the content of a Packet structure
- */
-void printPacket(const Packet* const packet)
-{
-       char saddr[17], daddr[17];
-       PacketKey* packetKey;
-
-       packetKey= packet->inE->packetKey;
-
-       convertIP(saddr, packetKey->connectionKey.saddr);
-       convertIP(daddr, packetKey->connectionKey.daddr);
-       g_debug("%s:%u to %s:%u tot_len: %u ihl: %u seq: %u ack_seq: %u doff: %u "
-               "ack: %u rst: %u syn: %u fin: %u", saddr,
-               packetKey->connectionKey.source, daddr, packetKey->connectionKey.dest,
-               packetKey->tot_len, packetKey->ihl, packetKey->seq,
-               packetKey->ack_seq, packetKey->doff, packetKey->ack, packetKey->rst,
-               packetKey->syn, packetKey->fin);
-}
-
-
-/*
- * A GHashFunc for g_hash_table_new()
- *
- * This function is for indexing netEvents in unMatched lists. All fields of
- * the corresponding packet must match for two keys to be equal.
- *
- * Args:
- *    key        PacketKey*
- */
-guint ghfPacketKeyHash(gconstpointer key)
-{
-       const PacketKey* p;
-       uint32_t a, b, c;
-
-       p= (PacketKey*) key;
-
-       a= p->connectionKey.source + (p->connectionKey.dest << 16);
-       b= p->connectionKey.saddr;
-       c= p->connectionKey.daddr;
-       mix(a, b, c);
-
-       a+= p->ihl + (p->tot_len << 8) + (p->doff << 24);
-       b+= p->seq;
-       c+= p->ack_seq;
-       mix(a, b, c);
-
-       a+= p->ack + (p->rst << 8) + (p->syn << 16) + (p->fin << 24);
-       final(a, b, c);
-
-       return c;
-}
-
-
-/*
- * A GEqualFunc for g_hash_table_new()
- *
- * This function is for indexing netEvents in unMatched lists. All fields of
- * the corresponding packet must match for two keys to be equal.
- *
- * Args:
- *   a, b          PacketKey*
- *
- * Returns:
- *   TRUE if both values are equal
- */
-gboolean gefPacketKeyEqual(gconstpointer a, gconstpointer b)
-{
-       const PacketKey* pA, * pB;
-
-       pA= ((PacketKey*) a);
-       pB= ((PacketKey*) b);
-
-       if (connectionKeyEqual(&pA->connectionKey, &pB->connectionKey) &&
-               pA->ihl == pB->ihl &&
-               pA->tot_len == pB->tot_len &&
-               pA->seq == pB->seq &&
-               pA->ack_seq == pB->ack_seq &&
-               pA->doff == pB->doff &&
-               pA->ack == pB->ack &&
-               pA->rst == pB->rst &&
-               pA->syn == pB->syn &&
-               pA->fin == pB->fin)
-       {
-               return TRUE;
-       }
-       else
-       {
-               return FALSE;
-       }
-}
-
-
-/*
- * A GDestroyNotify function for g_hash_table_new_full()
- *
- * Args:
- *   data:         NetEvent*
- */
-void gdnDestroyNetEvent(gpointer data)
-{
-       destroyNetEvent((NetEvent*) data);
-}
-
-
-/*
- * A GDestroyNotify function for g_hash_table_new_full()
- *
- * Args:
- *   data:         GQueue* list[Packet]
- */
-void gdnPacketListDestroy(gpointer data)
-{
-       GQueue* list;
-
-       list= (GQueue*) data;
-
-       g_debug("XXXX gdnPacketListDestroy\n");
-
-       g_queue_foreach(list, &gfPacketDestroy, NULL);
-       g_queue_free(list);
-}
-
-
-/*
- * A GFunc for g_queue_foreach()
- *
- * Args:
- *   data          Packet*, packet to destroy
- *   user_data     NULL
- */
-void gfPacketDestroy(gpointer data, gpointer user_data)
-{
-       g_debug("XXXX gfPacketDestroy\n");
-       destroyPacket((Packet*) data);
-}
-
-
-/*
- * Free the memory used by a Packet and the memory of all its associated
- * resources
- */
-void destroyPacket(Packet* const packet)
-{
-       g_debug("XXXX destroyPacket ");
-       printPacket(packet);
-       g_debug("\n");
-
-       g_assert(packet->inE != NULL && packet->outE != NULL &&
-               packet->inE->packetKey == packet->outE->packetKey);
-
-       packet->outE->packetKey= NULL;
-
-       destroyNetEvent(packet->inE);
-       destroyNetEvent(packet->outE);
-
-       if (packet->acks != NULL)
-       {
-               g_queue_foreach(packet->acks, &gfPacketDestroy, NULL);
-               g_queue_free(packet->acks);
-       }
-
-       free(packet);
-}
-
-
-/*
- * Free the memory used by a NetEvent
- */
-void destroyNetEvent(NetEvent* const event)
-{
-       g_debug("XXXX destroyNetEvent\n");
-
-       if (event->packetKey != NULL)
-       {
-               free(event->packetKey);
-       }
-       free(event);
-}
-
-
-/*
- * A GCompareFunc for g_queue_find_custom()
- *
- * Args:
- *   a          Packet* acked packet
- *   b          Packet* ack packet
- *
- * Returns:
- *   0 if b acks a
- */
-gint gcfPacketAckCompare(gconstpointer a, gconstpointer b)
-{
-       if (isAcking((const Packet*) b, (const Packet*) a))
-       {
-               return 0;
-       }
-       else
-       {
-               return 1;
-       }
-}
-
-
-/*
- * A GHashFunc for g_hash_table_new()
- *
- * Hash TCP connection keys. Here are a few possible implementations:
- *
- * 2.4 kernels used tcp_hashfn()
- *
- * I've seen something about an XOR hash:
- * http://tservice.net.ru/~s0mbre/blog/2006/05/14#2006_05_14:
- * unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
- * h ^= h >> 16;
- * h ^= h >> 8;
- * return h;
- *
- * In 2.6 kernels, inet_ehashfn() handles connection hashing with the help of
- * Jenkins hashing, jhash.h
- *
- * This function uses jenkins hashing. The hash is not the same for packets in
- * opposite directions of the same connection. (Hence the name
- * connection*key*hash)
- *
- * Args:
- *    key        ConnectionKey*
- */
-guint ghfConnectionKeyHash(gconstpointer key)
-{
-       ConnectionKey* connectionKey;
-       uint32_t a, b, c;
-
-       connectionKey= (ConnectionKey*) key;
-
-       a= connectionKey->source + (connectionKey->dest << 16);
-       b= connectionKey->saddr;
-       c= connectionKey->daddr;
-       final(a, b, c);
-
-       return c;
-}
-
-
-/*
- * A GEqualFunc for g_hash_table_new()
- *
- * Args:
- *   a, b          ConnectionKey*
- *
- * Returns:
- *   TRUE if both values are equal
- */
-gboolean gefConnectionKeyEqual(gconstpointer a, gconstpointer b)
-{
-       // Two packets in the same direction
-       if (connectionKeyEqual((const ConnectionKey*) a, (const ConnectionKey*) b))
-       {
-               return TRUE;
-       }
-       else
-       {
-               return FALSE;
-       }
-}
-
-
-/*
- * A GDestroyNotify function for g_hash_table_new_full()
- *
- * Args:
- *   data:         ConnectionKey*
- */
-void gdnConnectionKeyDestroy(gpointer data)
-{
-       free((ConnectionKey*) data);
-}
diff --git a/lttv/lttv/sync/data_structures_tcp.h b/lttv/lttv/sync/data_structures_tcp.h
deleted file mode 100644 (file)
index 0689353..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef DATA_STRUCTURES_TCP_H
-#define DATA_STRUCTURES_TCP_H
-
-#include <glib.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <ltt/ltt.h>
-
-typedef struct
-{
-       uint32_t saddr, daddr;
-       uint16_t source, dest;
-} ConnectionKey;
-
-typedef struct
-{
-       ConnectionKey connectionKey;
-       uint8_t ihl;
-       uint16_t tot_len;
-       uint32_t seq, ack_seq;
-       uint8_t doff;
-       uint8_t ack, rst, syn, fin;
-} PacketKey;
-
-typedef struct
-{
-       // lttng metainformation
-       unsigned long traceNum;
-       LttCycleCount tsc;
-
-       // kernel metainformation
-       void* skb;
-
-       // packet header fields
-       PacketKey* packetKey;
-} NetEvent;
-
-typedef struct
-{
-       NetEvent* inE, * outE;
-       GQueue* acks;
-} Packet;
-
-typedef struct
-{
-       double drift, offset;
-} Factors;
-
-typedef enum
-{
-       OUT,
-       IN
-} EventType;
-
-
-void convertIP(char* const str, const uint32_t addr);
-void printPacket(const Packet* const packet);
-
-// ConnectionKey-related functions
-bool connectionKeyEqual(const ConnectionKey* const a, const ConnectionKey*
-       const b);
-
-// NetEvent-related functions
-void destroyNetEvent(NetEvent* const event);
-
-// Packet-related functions
-bool isAcking(const Packet* const ackPacket, const Packet* const ackedPacket);
-void destroyPacket(Packet* const packet);
-
-// ConnectionKey-related Glib functions
-guint ghfConnectionKeyHash(gconstpointer key);
-gboolean gefConnectionKeyEqual(gconstpointer a, gconstpointer b);
-void gdnConnectionKeyDestroy(gpointer data);
-
-// PacketKey-related Glib functions
-guint ghfPacketKeyHash(gconstpointer key);
-gboolean gefPacketKeyEqual(gconstpointer a, gconstpointer b);
-
-// NetEvent-related Glib functions
-void gdnDestroyNetEvent(gpointer data);
-
-// Packet-related Glib functions
-void gdnPacketListDestroy(gpointer data);
-void gfPacketDestroy(gpointer data, gpointer user_data);
-gint gcfPacketAckCompare(gconstpointer a, gconstpointer b);
-
-#endif
index 76658b4ec54f29d17ec1886d1c05e344135144d8..0838f28c1ad45c545f280fd2549aef5444036177 100644 (file)
@@ -22,7 +22,7 @@
 #include <glib.h>
 #include <stdio.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 struct _SyncState;
@@ -34,10 +34,12 @@ typedef struct
        void (*initAnalysis)(struct _SyncState* const syncState);
        void (*destroyAnalysis)(struct _SyncState* const syncState);
 
-       void (*analyzePacket)(struct _SyncState* const syncState, Packet* const
-               packet);
-       void (*analyzeExchange)(struct _SyncState* const syncState, Packet* const
-               packet);
+       void (*analyzeMessage)(struct _SyncState* const syncState, Message* const
+               message);
+       void (*analyzeExchange)(struct _SyncState* const syncState, Exchange* const
+               exchange);
+       void (*analyzeBroadcast)(struct _SyncState* const syncState, Broadcast* const
+               broadcast);
        GArray* (*finalizeAnalysis)(struct _SyncState* const syncState);
        void (*printAnalysisStats)(struct _SyncState* const syncState);
        void (*writeAnalysisGraphsPlots)(FILE* stream, struct _SyncState* const
index 367b97cf340406e57cff953e863e8626a6fc1819..34630941a23b6f85e829cf3a048541fe12454945 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
 
 #include "event_analysis_chull.h"
 
@@ -56,7 +56,8 @@ typedef enum
 static void initAnalysisCHull(SyncState* const syncState);
 static void destroyAnalysisCHull(SyncState* const syncState);
 
-static void analyzePacketCHull(SyncState* const syncState, Packet* const packet);
+static void analyzeMessageCHull(SyncState* const syncState, Message* const
+       message);
 static GArray* finalizeAnalysisCHull(SyncState* const syncState);
 static void printAnalysisStatsCHull(SyncState* const syncState);
 static void writeAnalysisGraphsPlotsCHull(FILE* stream, SyncState* const
@@ -106,8 +107,9 @@ static AnalysisModule analysisModuleCHull= {
        .name= "chull",
        .initAnalysis= &initAnalysisCHull,
        .destroyAnalysis= &destroyAnalysisCHull,
-       .analyzePacket= &analyzePacketCHull,
+       .analyzeMessage= &analyzeMessageCHull,
        .analyzeExchange= NULL,
+       .analyzeBroadcast= NULL,
        .finalizeAnalysis= &finalizeAnalysisCHull,
        .printAnalysisStats= &printAnalysisStatsCHull,
        .writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsCHull,
@@ -380,9 +382,9 @@ static void destroyAnalysisCHull(SyncState* const syncState)
  *
  * Args:
  *   syncState     container for synchronization data
- *   packet        structure containing the events
+ *   message       structure containing the events
  */
-static void analyzePacketCHull(SyncState* const syncState, Packet* const packet)
+static void analyzeMessageCHull(SyncState* const syncState, Message* const message)
 {
        AnalysisDataCHull* analysisData;
        Point* newPoint;
@@ -392,29 +394,29 @@ static void analyzePacketCHull(SyncState* const syncState, Packet* const packet)
        analysisData= (AnalysisDataCHull*) syncState->analysisData;
 
        newPoint= malloc(sizeof(Point));
-       if (packet->inE->traceNum < packet->outE->traceNum)
+       if (message->inE->traceNum < message->outE->traceNum)
        {
                // CA is inE->traceNum
-               newPoint->x= packet->inE->tsc;
-               newPoint->y= packet->outE->tsc;
+               newPoint->x= message->inE->time;
+               newPoint->y= message->outE->time;
                hullType= UPPER;
-               g_debug("Reception point hullArray[%lu][%lu] x= inE->tsc= %llu y= outE->tsc= %llu",
-                       packet->inE->traceNum, packet->outE->traceNum, newPoint->x,
+               g_debug("Reception point hullArray[%lu][%lu] x= inE->time= %llu y= outE->time= %llu",
+                       message->inE->traceNum, message->outE->traceNum, newPoint->x,
                        newPoint->y);
        }
        else
        {
                // CA is outE->traceNum
-               newPoint->x= packet->outE->tsc;
-               newPoint->y= packet->inE->tsc;
+               newPoint->x= message->outE->time;
+               newPoint->y= message->inE->time;
                hullType= LOWER;
-               g_debug("Send point hullArray[%lu][%lu] x= inE->tsc= %llu y= outE->tsc= %llu",
-                       packet->inE->traceNum, packet->outE->traceNum, newPoint->x,
+               g_debug("Send point hullArray[%lu][%lu] x= inE->time= %llu y= outE->time= %llu",
+                       message->inE->traceNum, message->outE->traceNum, newPoint->x,
                        newPoint->y);
        }
 
        hull=
-               analysisData->hullArray[packet->inE->traceNum][packet->outE->traceNum];
+               analysisData->hullArray[message->inE->traceNum][message->outE->traceNum];
 
        if (hull->length >= 1 && newPoint->x < ((Point*)
                        g_queue_peek_tail(hull))->x)
index ed4284d880892dda5a63c2b09ab114256134e042..3059cf50228a056d4d0c408eaecac3539fe4e02e 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <glib.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 typedef struct
index 41a32aeb892e89f46fb659c0b7f13d5faeb946ac..10dc8d78de9af947d6fb2c06dd057f14a9b9e11e 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
 
 #include "event_analysis_linreg.h"
 
@@ -41,7 +41,7 @@
 static void initAnalysisLinReg(SyncState* const syncState);
 static void destroyAnalysisLinReg(SyncState* const syncState);
 
-static void analyzeExchangeLinReg(SyncState* const syncState, Packet* const packet);
+static void analyzeExchangeLinReg(SyncState* const syncState, Exchange* const exchange);
 static GArray* finalizeAnalysisLinReg(SyncState* const syncState);
 static void printAnalysisStatsLinReg(SyncState* const syncState);
 static void writeAnalysisGraphsPlotsLinReg(FILE* stream, SyncState* const
@@ -71,8 +71,9 @@ static AnalysisModule analysisModuleLinReg= {
        .name= "linreg",
        .initAnalysis= &initAnalysisLinReg,
        .destroyAnalysis= &destroyAnalysisLinReg,
-       .analyzePacket= NULL,
+       .analyzeMessage= NULL,
        .analyzeExchange= &analyzeExchangeLinReg,
+       .analyzeBroadcast= NULL,
        .finalizeAnalysis= &finalizeAnalysisLinReg,
        .printAnalysisStats= &printAnalysisStatsLinReg,
        .writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsLinReg,
@@ -170,47 +171,38 @@ static void destroyAnalysisLinReg(SyncState* const syncState)
 /*
  * Perform analysis on a series of event pairs.
  *
- * If one event pair is a packet, an exchange is composed of at least two
- * packets, one in each direction. There should be a non-negative minimum
- * "round trip time" (RTT) between the first and last event of the exchange.
- * This RTT should be as small as possible so these packets should be closely
- * related in time like a data packet and an acknowledgement packet. If the
- * events analyzed are such that the minimum RTT can be zero, there's nothing
- * gained in analyzing exchanges beyond what can already be figured out by
- * analyzing packets.
- *
- * An exchange can also consist of more than two packets, in case one packet
- * single handedly acknowledges many data packets.
- *
  * Args:
  *   syncState     container for synchronization data
- *   packet        structure containing the many events
+ *   exchange      structure containing the many events
  */
-static void analyzeExchangeLinReg(SyncState* const syncState, Packet* const packet)
+static void analyzeExchangeLinReg(SyncState* const syncState, Exchange* const exchange)
 {
        unsigned int ni, nj;
        double dji, eji;
        double timoy;
        Fit* fit;
-       Packet* ackedPacket;
+       Message* ackedMessage;
        AnalysisDataLinReg* analysisData;
 
        g_debug("Synchronization calculation, ");
        g_debug("%d acked packets - using last one, ",
-               g_queue_get_length(packet->acks));
+               g_queue_get_length(exchange->acks));
 
        analysisData= (AnalysisDataLinReg*) syncState->analysisData;
-       ackedPacket= g_queue_peek_tail(packet->acks);
+       ackedMessage= g_queue_peek_tail(exchange->acks);
 
        // Calculate the intermediate values for the
        // least-squares analysis
-       dji= ((double) ackedPacket->inE->tsc - (double) ackedPacket->outE->tsc +
-               (double) packet->outE->tsc - (double) packet->inE->tsc) / 2;
-       eji= fabs((double) ackedPacket->inE->tsc - (double) ackedPacket->outE->tsc
-               - (double) packet->outE->tsc + (double) packet->inE->tsc) / 2;
-       timoy= ((double) ackedPacket->outE->tsc + (double) packet->inE->tsc) / 2;
-       ni= ackedPacket->outE->traceNum;
-       nj= ackedPacket->inE->traceNum;
+       dji= ((double) ackedMessage->inE->time - (double) ackedMessage->outE->time
+               + (double) exchange->message->outE->time - (double)
+               exchange->message->inE->time) / 2;
+       eji= fabs((double) ackedMessage->inE->time - (double)
+               ackedMessage->outE->time - (double) exchange->message->outE->time +
+               (double) exchange->message->inE->time) / 2;
+       timoy= ((double) ackedMessage->outE->time + (double)
+               exchange->message->inE->time) / 2;
+       ni= ackedMessage->outE->traceNum;
+       nj= ackedMessage->inE->traceNum;
        fit= &analysisData->fitArray[nj][ni];
 
        fit->n++;
index eb94eaa63e34fce5d98e50290d375d8aebd1b061..60002e3ecfddcabc80db49fd673ff0a2321a0b63 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <glib.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 typedef struct
index 0c3fe2d1c82c335509e2c238c5de57a2a9d32eda..55c42243f5711d484a7750da28becd2d80deab89 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <glib.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 struct _SyncState;
@@ -33,8 +33,8 @@ typedef struct
        void (*initMatching)(struct _SyncState* const syncState);
        void (*destroyMatching)(struct _SyncState* const syncState);
 
-       void (*matchEvent)(struct _SyncState* const syncState, NetEvent* const event,
-               EventType eventType);
+       void (*matchEvent)(struct _SyncState* const syncState, Event* const
+               event);
        GArray* (*finalizeMatching)(struct _SyncState* const syncState);
        void (*printMatchingStats)(struct _SyncState* const syncState);
        void (*writeMatchingGraphsPlots)(FILE* stream, struct _SyncState* const
index 5c0e3b6907e01a7150b08d14768b81613d431e2a..25e39858fb8b36c76c19c11bcd0efe5d64a5ba09 100644 (file)
@@ -26,7 +26,7 @@
 #include <unistd.h>
 
 #include "event_analysis.h"
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
 
 #include "event_matching_tcp.h"
 
@@ -40,8 +40,7 @@
 static void initMatchingTCP(SyncState* const syncState);
 static void destroyMatchingTCP(SyncState* const syncState);
 
-static void matchEventTCP(SyncState* const syncState, NetEvent* const event,
-       EventType eventType);
+static void matchEventTCP(SyncState* const syncState, Event* const event);
 static GArray* finalizeMatchingTCP(SyncState* const syncState);
 static void printMatchingStatsTCP(SyncState* const syncState);
 static void writeMatchingGraphsPlotsTCP(FILE* stream, SyncState* const
@@ -52,20 +51,20 @@ static void writeMatchingGraphsOptionsTCP(FILE* stream, SyncState* const
 // Functions specific to this module
 static void registerMatchingTCP() __attribute__((constructor (101)));
 
-static void matchEvents(SyncState* const syncState, NetEvent* const event,
+static void matchEvents(SyncState* const syncState, Event* const event,
        GHashTable* const unMatchedList, GHashTable* const
        unMatchedOppositeList, const size_t fieldOffset, const size_t
        oppositeFieldOffset);
 static void partialDestroyMatchingTCP(SyncState* const syncState);
 
-static bool isAck(const Packet* const packet);
-static bool needsAck(const Packet* const packet);
+static bool isAck(const Message* const message);
+static bool needsAck(const Message* const message);
 static void buildReversedConnectionKey(ConnectionKey* const
        reversedConnectionKey, const ConnectionKey* const connectionKey);
 
 static void openGraphDataFiles(SyncState* const syncState);
 static void closeGraphDataFiles(SyncState* const syncState);
-static void writeMessagePoint(FILE* stream, const Packet* const packet);
+static void writeMessagePoint(FILE* stream, const Message* const message);
 
 
 static MatchingModule matchingModuleTCP = {
@@ -112,13 +111,13 @@ static void initMatchingTCP(SyncState* const syncState)
        matchingData= malloc(sizeof(MatchingDataTCP));
        syncState->matchingData= matchingData;
 
-       matchingData->unMatchedInE= g_hash_table_new_full(&ghfPacketKeyHash,
-               &gefPacketKeyEqual, NULL, &gdnDestroyNetEvent);
-       matchingData->unMatchedOutE= g_hash_table_new_full(&ghfPacketKeyHash,
-               &gefPacketKeyEqual, NULL, &gdnDestroyNetEvent);
+       matchingData->unMatchedInE= g_hash_table_new_full(&ghfSegmentKeyHash,
+               &gefSegmentKeyEqual, NULL, &gdnDestroyEvent);
+       matchingData->unMatchedOutE= g_hash_table_new_full(&ghfSegmentKeyHash,
+               &gefSegmentKeyEqual, NULL, &gdnDestroyEvent);
        matchingData->unAcked= g_hash_table_new_full(&ghfConnectionKeyHash,
                &gefConnectionKeyEqual, &gdnConnectionKeyDestroy,
-               &gdnPacketListDestroy);
+               &gdnTCPSegmentListDestroy);
 
        if (syncState->stats)
        {
@@ -234,23 +233,23 @@ static void partialDestroyMatchingTCP(SyncState* const syncState)
  *   event         new event to match
  *   eventType     type of event to match
  */
-static void matchEventTCP(SyncState* const syncState, NetEvent* const event, EventType eventType)
+static void matchEventTCP(SyncState* const syncState, Event* const event)
 {
        MatchingDataTCP* matchingData;
 
        matchingData= (MatchingDataTCP*) syncState->matchingData;
 
-       if (eventType == IN)
+       if (event->event.tcpEvent->direction == IN)
        {
                matchEvents(syncState, event, matchingData->unMatchedInE,
-                       matchingData->unMatchedOutE, offsetof(Packet, inE),
-                       offsetof(Packet, outE));
+                       matchingData->unMatchedOutE, offsetof(Message, inE),
+                       offsetof(Message, outE));
        }
        else
        {
                matchEvents(syncState, event, matchingData->unMatchedOutE,
-                       matchingData->unMatchedInE, offsetof(Packet, outE),
-                       offsetof(Packet, inE));
+                       matchingData->unMatchedInE, offsetof(Message, outE),
+                       offsetof(Message, inE));
        }
 }
 
@@ -328,41 +327,41 @@ static void printMatchingStatsTCP(SyncState* const syncState)
  * Implementation of a packet matching algorithm for TCP
  *
  * Args:
- *   netEvent:     new event to match
+ *   event:        new event to match
  *   unMatchedList: list of unmatched events of the same type (send or
- *                 receive) as netEvent
+ *                 receive) as event
  *   unMatchedOppositeList: list of unmatched events of the opposite type of
- *                 netEvent
- *   fieldOffset:  offset of the NetEvent field in the Packet struct for the
- *                 field of the type of netEvent
- *   oppositeFieldOffset: offset of the NetEvent field in the Packet struct
- *                 for the field of the opposite type of netEvent
+ *                 event
+ *   fieldOffset:  offset of the Event field in the Message struct for the
+ *                 field of the type of event
+ *   oppositeFieldOffset: offset of the Event field in the Message struct
+ *                 for the field of the opposite type of event
  */
-static void matchEvents(SyncState* const syncState, NetEvent* const event,
+static void matchEvents(SyncState* const syncState, Event* const event,
        GHashTable* const unMatchedList, GHashTable* const unMatchedOppositeList,
        const size_t fieldOffset, const size_t oppositeFieldOffset)
 {
-       NetEvent* companionEvent;
-       Packet* packet;
+       Event* companionEvent;
+       Message* packet;
        MatchingDataTCP* matchingData;
        GQueue* conUnAcked;
 
        matchingData= (MatchingDataTCP*) syncState->matchingData;
 
-       companionEvent= g_hash_table_lookup(unMatchedOppositeList, event->packetKey);
+       companionEvent= g_hash_table_lookup(unMatchedOppositeList, event->event.tcpEvent->segmentKey);
        if (companionEvent != NULL)
        {
                g_debug("Found matching companion event, ");
 
-               // If it's there, remove it and create a Packet
-               g_hash_table_steal(unMatchedOppositeList, event->packetKey);
-               packet= malloc(sizeof(Packet));
-               *((NetEvent**) ((void*) packet + fieldOffset))= event;
-               *((NetEvent**) ((void*) packet + oppositeFieldOffset))= companionEvent;
-               // Both events can now share the same packetKey
-               free(packet->outE->packetKey);
-               packet->outE->packetKey= packet->inE->packetKey;
-               packet->acks= NULL;
+               // If it's there, remove it and create a Message
+               g_hash_table_steal(unMatchedOppositeList, event->event.tcpEvent->segmentKey);
+               packet= malloc(sizeof(Message));
+               *((Event**) ((void*) packet + fieldOffset))= event;
+               *((Event**) ((void*) packet + oppositeFieldOffset))= companionEvent;
+               packet->print= &printTCPSegment;
+               // Both events can now share the same segmentKey
+               free(packet->outE->event.tcpEvent->segmentKey);
+               packet->outE->event.tcpEvent->segmentKey= packet->inE->event.tcpEvent->segmentKey;
 
                if (syncState->stats)
                {
@@ -373,7 +372,7 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                // Discard loopback traffic
                if (packet->inE->traceNum == packet->outE->traceNum)
                {
-                       destroyPacket(packet);
+                       destroyTCPSegment(packet);
                        return;
                }
 
@@ -383,16 +382,16 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                                packet);
                }
 
-               if (syncState->analysisModule->analyzePacket != NULL)
+               if (syncState->analysisModule->analyzeMessage != NULL)
                {
-                       syncState->analysisModule->analyzePacket(syncState, packet);
+                       syncState->analysisModule->analyzeMessage(syncState, packet);
                }
 
                // We can skip the rest of the algorithm if the analysis module is not
                // interested in exchanges
                if (syncState->analysisModule->analyzeExchange == NULL)
                {
-                       destroyPacket(packet);
+                       destroyTCPSegment(packet);
                        return;
                }
 
@@ -402,15 +401,18 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                        ConnectionKey oppositeConnectionKey;
 
                        buildReversedConnectionKey(&oppositeConnectionKey,
-                               &event->packetKey->connectionKey);
+                               &event->event.tcpEvent->segmentKey->connectionKey);
                        conUnAcked= g_hash_table_lookup(matchingData->unAcked,
                                &oppositeConnectionKey);
                        if (conUnAcked != NULL)
                        {
-                               Packet* ackedPacket;
+                               Message* ackedPacket;
                                GList* result;
+                               Exchange* exchange;
 
-                               result= g_queue_find_custom(conUnAcked, packet, &gcfPacketAckCompare);
+                               exchange= NULL;
+
+                               result= g_queue_find_custom(conUnAcked, packet, &gcfTCPSegmentAckCompare);
 
                                while (result != NULL)
                                {
@@ -418,7 +420,7 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                                        // and keep it for later offset calculations
                                        g_debug("Found matching unAcked packet, ");
 
-                                       ackedPacket= (Packet*) result->data;
+                                       ackedPacket= (Message*) result->data;
                                        g_queue_delete_link(conUnAcked, result);
 
                                        if (syncState->stats)
@@ -426,28 +428,30 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                                                matchingData->stats->totExchangeEffective++;
                                        }
 
-                                       if (packet->acks == NULL)
+                                       if (exchange == NULL)
                                        {
-                                               packet->acks= g_queue_new();
+                                               exchange= malloc(sizeof(Exchange));
+                                               exchange->message= packet;
+                                               exchange->acks= g_queue_new();
                                        }
 
-                                       g_queue_push_tail(packet->acks, ackedPacket);
+                                       g_queue_push_tail(exchange->acks, ackedPacket);
 
                                        result= g_queue_find_custom(conUnAcked, packet,
-                                               &gcfPacketAckCompare);
+                                               &gcfTCPSegmentAckCompare);
                                }
 
                                // It might be possible to do an offset calculation
-                               if (packet->acks != NULL)
+                               if (exchange != NULL)
                                {
-                                       ackedPacket= g_queue_peek_tail(packet->acks);
+                                       ackedPacket= g_queue_peek_tail(exchange->acks);
                                        if (ackedPacket->outE->traceNum != packet->inE->traceNum
                                                || ackedPacket->inE->traceNum !=
                                                packet->outE->traceNum || packet->inE->traceNum ==
                                                packet->outE->traceNum)
                                        {
-                                               printPacket(ackedPacket);
-                                               printPacket(packet);
+                                               ackedPacket->print(ackedPacket);
+                                               packet->print(packet);
                                                g_error("Disorganized exchange encountered during "
                                                        "synchronization");
                                        }
@@ -459,8 +463,11 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                                                }
 
                                                syncState->analysisModule->analyzeExchange(syncState,
-                                                       packet);
+                                                       exchange);
                                        }
+
+                                       exchange->message= NULL;
+                                       destroyTCPExchange(exchange);
                                }
                        }
                }
@@ -475,13 +482,13 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                        // If this packet will generate an ack, add it to the unAcked list
                        g_debug("Adding to unAcked, ");
                        conUnAcked= g_hash_table_lookup(matchingData->unAcked,
-                               &event->packetKey->connectionKey);
+                               &event->event.tcpEvent->segmentKey->connectionKey);
                        if (conUnAcked == NULL)
                        {
                                ConnectionKey* connectionKey;
 
                                connectionKey= malloc(sizeof(ConnectionKey));
-                               memcpy(connectionKey, &event->packetKey->connectionKey,
+                               memcpy(connectionKey, &event->event.tcpEvent->segmentKey->connectionKey,
                                        sizeof(ConnectionKey));
                                g_hash_table_insert(matchingData->unAcked, connectionKey,
                                        conUnAcked= g_queue_new());
@@ -490,7 +497,7 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                }
                else
                {
-                       destroyPacket(packet);
+                       destroyTCPSegment(packet);
                }
        }
        else
@@ -498,7 +505,7 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
                // If there's no corresponding event, add the event to the unmatched
                // list for this type of event
                g_debug("Adding to unmatched event list, ");
-               g_hash_table_replace(unMatchedList, event->packetKey, event);
+               g_hash_table_replace(unMatchedList, event->event.tcpEvent->segmentKey, event);
        }
 }
 
@@ -506,13 +513,16 @@ static void matchEvents(SyncState* const syncState, NetEvent* const event,
 /*
  * Check if a packet is an acknowledge
  *
+ * Args:
+ *   packet        TCP Message
+ *
  * Returns:
  *   true if it is,
  *   false otherwise
  */
-static bool isAck(const Packet* const packet)
+static bool isAck(const Message* const packet)
 {
-       if (packet->inE->packetKey->ack == 1)
+       if (packet->inE->event.tcpEvent->segmentKey->ack == 1)
        {
                return true;
        }
@@ -527,15 +537,18 @@ static bool isAck(const Packet* const packet)
  * Check if a packet will increment the sequence number, thus needing an
  * acknowledge
  *
+ * Args:
+ *   packet        TCP Message
+ *
  * Returns:
  *   true if the packet will need an acknowledge
  *   false otherwise
  */
-static bool needsAck(const Packet* const packet)
+static bool needsAck(const Message* const packet)
 {
-       if (packet->inE->packetKey->syn || packet->inE->packetKey->fin ||
-               packet->inE->packetKey->tot_len - packet->inE->packetKey->ihl * 4 -
-               packet->inE->packetKey->doff * 4 > 0)
+       if (packet->inE->event.tcpEvent->segmentKey->syn || packet->inE->event.tcpEvent->segmentKey->fin ||
+               packet->inE->event.tcpEvent->segmentKey->tot_len - packet->inE->event.tcpEvent->segmentKey->ihl * 4 -
+               packet->inE->event.tcpEvent->segmentKey->doff * 4 > 0)
        {
                return true;
        }
@@ -620,24 +633,24 @@ static void openGraphDataFiles(SyncState* const syncState)
  * Write a message point to a file used to generate graphs
  *
  * Args:
- *   stream:           FILE*, file pointer where to write the point
- *   packet:       message for which to write the point
+ *   stream:       FILE*, file pointer where to write the point
+ *   message:       message for which to write the point
  */
-static void writeMessagePoint(FILE* stream, const Packet* const packet)
+static void writeMessagePoint(FILE* stream, const Message* const message)
 {
        LttCycleCount x, y;
 
-       if (packet->inE->traceNum < packet->outE->traceNum)
+       if (message->inE->traceNum < message->outE->traceNum)
        {
                // CA is inE->traceNum
-               x= packet->inE->tsc;
-               y= packet->outE->tsc;
+               x= message->inE->time;
+               y= message->outE->time;
        }
        else
        {
                // CA is outE->traceNum
-               x= packet->outE->tsc;
-               y= packet->inE->tsc;
+               x= message->outE->time;
+               y= message->inE->time;
        }
 
        fprintf(stream, "%20llu %20llu\n", x, y);
index f0ce62250b37dd07074b838d9bfc97b4e120cd3a..2687aa2117416cbc5d1b6047f102cbfe8c38402a 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <glib.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 typedef struct
index 6e8c3799cd245f6e62f815819be1d07f08c824dd..44a2c4cf43701150e8b1eab9c8059321a7f2e0d6 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <lttv/tracecontext.h>
 
-#include "data_structures_tcp.h"
+#include "data_structures.h"
 
 
 struct _SyncState;
diff --git a/lttv/lttv/sync/event_processing_lttng_common.c b/lttv/lttv/sync/event_processing_lttng_common.c
new file mode 100644 (file)
index 0000000..95f80c3
--- /dev/null
@@ -0,0 +1,226 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "event_processing_lttng_common.h"
+
+
+#ifndef g_info
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#endif
+
+
+/*
+ * Initialize the GQuarks needed to register the event hooks for
+ * synchronization
+ */
+void createQuarks()
+{
+       LTT_CHANNEL_NET= g_quark_from_static_string("net");
+       LTT_CHANNEL_NETIF_STATE= g_quark_from_static_string("netif_state");
+
+       LTT_EVENT_DEV_XMIT= g_quark_from_static_string("dev_xmit");
+       LTT_EVENT_DEV_RECEIVE= g_quark_from_static_string("dev_receive");
+       LTT_EVENT_TCPV4_RCV= g_quark_from_static_string("tcpv4_rcv");
+       LTT_EVENT_NETWORK_IPV4_INTERFACE=
+               g_quark_from_static_string("network_ipv4_interface");
+
+       LTT_FIELD_SKB= g_quark_from_static_string("skb");
+       LTT_FIELD_PROTOCOL= g_quark_from_static_string("protocol");
+       LTT_FIELD_NETWORK_PROTOCOL=
+               g_quark_from_static_string("network_protocol");
+       LTT_FIELD_TRANSPORT_PROTOCOL=
+               g_quark_from_static_string("transport_protocol");
+       LTT_FIELD_SADDR= g_quark_from_static_string("saddr");
+       LTT_FIELD_DADDR= g_quark_from_static_string("daddr");
+       LTT_FIELD_TOT_LEN= g_quark_from_static_string("tot_len");
+       LTT_FIELD_IHL= g_quark_from_static_string("ihl");
+       LTT_FIELD_SOURCE= g_quark_from_static_string("source");
+       LTT_FIELD_DEST= g_quark_from_static_string("dest");
+       LTT_FIELD_SEQ= g_quark_from_static_string("seq");
+       LTT_FIELD_ACK_SEQ= g_quark_from_static_string("ack_seq");
+       LTT_FIELD_DOFF= g_quark_from_static_string("doff");
+       LTT_FIELD_ACK= g_quark_from_static_string("ack");
+       LTT_FIELD_RST= g_quark_from_static_string("rst");
+       LTT_FIELD_SYN= g_quark_from_static_string("syn");
+       LTT_FIELD_FIN= g_quark_from_static_string("fin");
+       LTT_FIELD_NAME= g_quark_from_static_string("name");
+       LTT_FIELD_ADDRESS= g_quark_from_static_string("address");
+       LTT_FIELD_UP= g_quark_from_static_string("up");
+}
+
+
+/* Fill hookListList and add event hooks
+ *
+ * Note: possibilité de remettre le code avec lttv_trace_find_marker_ids (voir
+ * r328)
+ *
+ * Args:
+ *   hookListList: LttvTraceHook hookListList[traceNum][hookNum]
+ *   traceSetContext: LTTV traceset
+ *   hookFunction: call back function when event is encountered
+ *   hookData:     data that will be made accessible to hookFunction in
+ *                 arg0->hook_data
+ */
+void registerHooks(GArray* hookListList, LttvTracesetContext* const
+       traceSetContext, LttvHook hookFunction, gpointer hookData)
+{
+       unsigned int i, j, k;
+       unsigned int traceNb= lttv_traceset_number(traceSetContext->ts);
+       struct {
+               GQuark channelName;
+               GQuark eventName;
+               GQuark* fields;
+       } eventHookInfoList[] = {
+               {
+                       .channelName= LTT_CHANNEL_NET,
+                       .eventName= LTT_EVENT_DEV_XMIT,
+                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_NETWORK_PROTOCOL,
+                               LTT_FIELD_TRANSPORT_PROTOCOL, LTT_FIELD_SADDR,
+                               LTT_FIELD_DADDR, LTT_FIELD_TOT_LEN, LTT_FIELD_IHL,
+                               LTT_FIELD_SOURCE, LTT_FIELD_DEST, LTT_FIELD_SEQ,
+                               LTT_FIELD_ACK_SEQ, LTT_FIELD_DOFF, LTT_FIELD_ACK,
+                               LTT_FIELD_RST, LTT_FIELD_SYN, LTT_FIELD_FIN),
+               }, {
+                       .channelName= LTT_CHANNEL_NET,
+                       .eventName= LTT_EVENT_DEV_RECEIVE,
+                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_PROTOCOL),
+               }, {
+                       .channelName= LTT_CHANNEL_NET,
+                       .eventName= LTT_EVENT_TCPV4_RCV,
+                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_SADDR,
+                               LTT_FIELD_DADDR, LTT_FIELD_TOT_LEN, LTT_FIELD_IHL,
+                               LTT_FIELD_SOURCE, LTT_FIELD_DEST, LTT_FIELD_SEQ,
+                               LTT_FIELD_ACK_SEQ, LTT_FIELD_DOFF, LTT_FIELD_ACK,
+                               LTT_FIELD_RST, LTT_FIELD_SYN, LTT_FIELD_FIN),
+               }, {
+                       .channelName= LTT_CHANNEL_NETIF_STATE,
+                       .eventName= LTT_EVENT_NETWORK_IPV4_INTERFACE,
+                       .fields= FIELD_ARRAY(LTT_FIELD_NAME, LTT_FIELD_ADDRESS,
+                               LTT_FIELD_UP),
+               }
+       }; // This is called a compound literal
+       unsigned int hookNb= sizeof(eventHookInfoList) / sizeof(*eventHookInfoList);
+
+       for(i= 0; i < traceNb; i++)
+       {
+               LttvTraceContext* tc;
+               GArray* hookList;
+               int retval;
+
+               tc= traceSetContext->traces[i];
+               hookList= g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+               g_array_append_val(hookListList, hookList);
+
+               // Find the hooks
+               for (j= 0; j < hookNb; j++)
+               {
+                       guint old_len;
+
+                       old_len= hookList->len;
+                       retval= lttv_trace_find_hook(tc->t,
+                               eventHookInfoList[j].channelName,
+                               eventHookInfoList[j].eventName, eventHookInfoList[j].fields,
+                               hookFunction, hookData, &hookList);
+                       if (retval != 0)
+                       {
+                               g_warning("Trace %d contains no %s.%s marker\n", i,
+                                       g_quark_to_string(eventHookInfoList[j].channelName),
+                                       g_quark_to_string(eventHookInfoList[j].eventName));
+                       }
+                       else
+                       {
+                               g_assert(hookList->len - old_len == 1);
+                       }
+               }
+
+               // Add the hooks to each tracefile's event_by_id hook list
+               for(j= 0; j < tc->tracefiles->len; j++)
+               {
+                       LttvTracefileContext* tfc;
+
+                       tfc= g_array_index(tc->tracefiles, LttvTracefileContext*, j);
+
+                       for(k= 0; k < hookList->len; k++)
+                       {
+                               LttvTraceHook* traceHook;
+
+                               traceHook= &g_array_index(hookList, LttvTraceHook, k);
+                               if (traceHook->hook_data != hookData)
+                               {
+                                       g_assert_not_reached();
+                               }
+                               if (traceHook->mdata == tfc->tf->mdata)
+                               {
+                                       lttv_hooks_add(lttv_hooks_by_id_find(tfc->event_by_id,
+                                                       traceHook->id), traceHook->h, traceHook,
+                                               LTTV_PRIO_DEFAULT);
+                               }
+                       }
+               }
+       }
+}
+
+
+/* Remove event hooks and free hookListList
+ *
+ * Args:
+ *   hookListList: LttvTraceHook hookListList[traceNum][hookNum]
+ *   traceSetContext: LTTV traceset
+ */
+void unregisterHooks(GArray* hookListList, LttvTracesetContext* const
+       traceSetContext)
+{
+       unsigned int i, j, k;
+       unsigned int traceNb= lttv_traceset_number(traceSetContext->ts);
+
+       for(i= 0; i < traceNb; i++)
+       {
+               LttvTraceContext* tc;
+               GArray* hookList;
+
+               tc= traceSetContext->traces[i];
+               hookList= g_array_index(hookListList, GArray*, i);
+
+               // Remove the hooks from each tracefile's event_by_id hook list
+               for(j= 0; j < tc->tracefiles->len; j++)
+               {
+                       LttvTracefileContext* tfc;
+
+                       tfc= g_array_index(tc->tracefiles, LttvTracefileContext*, j);
+
+                       for(k= 0; k < hookList->len; k++)
+                       {
+                               LttvTraceHook* traceHook;
+
+                               traceHook= &g_array_index(hookList, LttvTraceHook, k);
+                               if (traceHook->mdata == tfc->tf->mdata)
+                               {
+                                       lttv_hooks_remove_data(lttv_hooks_by_id_find(tfc->event_by_id,
+                                                       traceHook->id), traceHook->h, traceHook);
+                               }
+                       }
+               }
+
+               g_array_free(hookList, TRUE);
+       }
+       g_array_free(hookListList, TRUE);
+}
diff --git a/lttv/lttv/sync/event_processing_lttng_common.h b/lttv/lttv/sync/event_processing_lttng_common.h
new file mode 100644 (file)
index 0000000..aa34cfc
--- /dev/null
@@ -0,0 +1,67 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef EVENT_PROCESSING_LTTNG_COMMON_H
+#define EVENT_PROCESSING_LTTNG_COMMON_H
+
+#include <glib.h>
+
+#include <lttv/tracecontext.h>
+
+
+GQuark
+       LTT_CHANNEL_NET,
+       LTT_CHANNEL_NETIF_STATE;
+
+GQuark
+       LTT_EVENT_DEV_XMIT,
+       LTT_EVENT_DEV_RECEIVE,
+       LTT_EVENT_TCPV4_RCV,
+       LTT_EVENT_NETWORK_IPV4_INTERFACE;
+
+GQuark
+       LTT_FIELD_SKB,
+       LTT_FIELD_PROTOCOL,
+       LTT_FIELD_NETWORK_PROTOCOL,
+       LTT_FIELD_TRANSPORT_PROTOCOL,
+       LTT_FIELD_SADDR,
+       LTT_FIELD_DADDR,
+       LTT_FIELD_TOT_LEN,
+       LTT_FIELD_IHL,
+       LTT_FIELD_SOURCE,
+       LTT_FIELD_DEST,
+       LTT_FIELD_SEQ,
+       LTT_FIELD_ACK_SEQ,
+       LTT_FIELD_DOFF,
+       LTT_FIELD_ACK,
+       LTT_FIELD_RST,
+       LTT_FIELD_SYN,
+       LTT_FIELD_FIN,
+       LTT_FIELD_NAME,
+    LTT_FIELD_ADDRESS,
+    LTT_FIELD_UP;
+
+
+void createQuarks();
+void registerHooks(GArray* hookListList, LttvTracesetContext* const
+       traceSetContext, LttvHook hookFunction, gpointer
+       hookData);
+void unregisterHooks(GArray* hookListList, LttvTracesetContext* const
+       traceSetContext);
+
+#endif
diff --git a/lttv/lttv/sync/event_processing_lttng_null.c b/lttv/lttv/sync/event_processing_lttng_null.c
new file mode 100644 (file)
index 0000000..170ebf1
--- /dev/null
@@ -0,0 +1,151 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "sync_chain_lttv.h"
+#include "event_processing_lttng_common.h"
+
+#include "event_processing_lttng_null.h"
+
+
+#ifndef g_info
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#endif
+
+
+// Functions common to all processing modules
+static void initProcessingLTTVNull(SyncState* const syncState,
+       LttvTracesetContext* const traceSetContext);
+static void destroyProcessingLTTVNull(SyncState* const syncState);
+
+static void finalizeProcessingLTTVNull(SyncState* const syncState);
+
+// Functions specific to this module
+static void registerProcessingLTTVNull() __attribute__((constructor (102)));
+static gboolean processEventLTTVNull(void* hookData, void* callData);
+
+
+static ProcessingModule processingModuleLTTVNull = {
+       .name= "LTTV-null",
+       .initProcessing= &initProcessingLTTVNull,
+       .destroyProcessing= &destroyProcessingLTTVNull,
+       .finalizeProcessing= &finalizeProcessingLTTVNull,
+       .printProcessingStats= NULL,
+       .writeProcessingGraphsPlots= NULL,
+       .writeProcessingGraphsOptions= NULL,
+};
+
+
+
+/*
+ * Processing Module registering function
+ */
+static void registerProcessingLTTVNull()
+{
+       g_queue_push_tail(&processingModules, &processingModuleLTTVNull);
+
+       createQuarks();
+}
+
+
+/*
+ * Allocate and initialize data structures for synchronizing a traceset.
+ * Register event hooks.
+ *
+ * Args:
+ *   syncState:    container for synchronization data.
+ *                 This function allocates these processingData members:
+ *                 hookListList
+ *   traceSetContext: set of LTTV traces
+ */
+static void initProcessingLTTVNull(SyncState* const syncState,
+       LttvTracesetContext* const traceSetContext)
+{
+       ProcessingDataLTTVNull* processingData;
+
+       processingData= malloc(sizeof(ProcessingDataLTTVNull));
+       syncState->processingData= processingData;
+       processingData->traceSetContext= traceSetContext;
+
+       processingData->hookListList= g_array_sized_new(FALSE, FALSE,
+               sizeof(GArray*), syncState->traceNb);
+
+       registerHooks(processingData->hookListList, traceSetContext,
+               &processEventLTTVNull, syncState);
+}
+
+
+/*
+ * Nothing to do
+ *
+ * Args:
+ *   syncState     container for synchronization data.
+ */
+static void finalizeProcessingLTTVNull(SyncState* const syncState)
+{
+       return;
+}
+
+
+/*
+ * Unregister event hooks. Deallocate processingData.
+ *
+ * Args:
+ *   syncState:    container for synchronization data.
+ *                 This function deallocates these members:
+ *                 hookListList
+ */
+static void destroyProcessingLTTVNull(SyncState* const syncState)
+{
+       ProcessingDataLTTVNull* processingData;
+
+       processingData= (ProcessingDataLTTVNull*) syncState->processingData;
+
+       if (processingData == NULL)
+       {
+               return;
+       }
+
+       unregisterHooks(processingData->hookListList,
+               processingData->traceSetContext);
+
+       free(syncState->processingData);
+       syncState->processingData= NULL;
+}
+
+
+/*
+ * Lttv hook function that will be called for network events
+ *
+ * Args:
+ *   hookData:     LttvTraceHook* for the type of event that generated the call
+ *   callData:     LttvTracefileContext* at the moment of the event
+ *
+ * Returns:
+ *   FALSE         Always returns FALSE, meaning to keep processing hooks for
+ *                 this event
+ */
+static gboolean processEventLTTVNull(void* hookData, void* callData)
+{
+       return FALSE;
+}
diff --git a/lttv/lttv/sync/event_processing_lttng_null.h b/lttv/lttv/sync/event_processing_lttng_null.h
new file mode 100644 (file)
index 0000000..090b6b8
--- /dev/null
@@ -0,0 +1,38 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef EVENT_PROCESSING_LTTV_NULL_H
+#define EVENT_PROCESSING_LTTV_NULL_H
+
+#include <glib.h>
+
+#include <lttv/tracecontext.h>
+
+
+typedef struct
+{
+       LttvTracesetContext* traceSetContext;
+
+       // hookListList conceptually is a two dimensionnal array of LttvTraceHook
+       // elements. It uses GArrays to interface with other lttv functions that
+       // do.
+       // LttvTraceHook hookListList[traceNum][hookNum]
+       GArray* hookListList;
+} ProcessingDataLTTVNull;
+
+#endif
diff --git a/lttv/lttv/sync/event_processing_lttng_standard.c b/lttv/lttv/sync/event_processing_lttng_standard.c
new file mode 100644 (file)
index 0000000..de2d86a
--- /dev/null
@@ -0,0 +1,649 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#define _ISOC99_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <linux/if_ether.h>
+#include <math.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "sync_chain_lttv.h"
+#include "event_processing_lttng_common.h"
+
+#include "event_processing_lttng_standard.h"
+
+
+#ifndef g_info
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#endif
+
+
+// Functions common to all processing modules
+static void initProcessingLTTVStandard(SyncState* const syncState,
+       LttvTracesetContext* const traceSetContext);
+static void destroyProcessingLTTVStandard(SyncState* const syncState);
+
+static void finalizeProcessingLTTVStandard(SyncState* const syncState);
+static void printProcessingStatsLTTVStandard(SyncState* const syncState);
+static void writeProcessingGraphsPlotsLTTVStandard(FILE* stream, SyncState*
+       const syncState, const unsigned int i, const unsigned int j);
+static void writeProcessingGraphsOptionsLTTVStandard(FILE* stream, SyncState*
+       const syncState, const unsigned int i, const unsigned int j);
+
+// Functions specific to this module
+static void registerProcessingLTTVStandard() __attribute__((constructor (102)));
+static gboolean processEventLTTVStandard(void* hookData, void* callData);
+static void partialDestroyProcessingLTTVStandard(SyncState* const syncState);
+
+
+static ProcessingModule processingModuleLTTVStandard = {
+       .name= "LTTV-standard",
+       .initProcessing= &initProcessingLTTVStandard,
+       .destroyProcessing= &destroyProcessingLTTVStandard,
+       .finalizeProcessing= &finalizeProcessingLTTVStandard,
+       .printProcessingStats= &printProcessingStatsLTTVStandard,
+       .writeProcessingGraphsPlots= &writeProcessingGraphsPlotsLTTVStandard,
+       .writeProcessingGraphsOptions= &writeProcessingGraphsOptionsLTTVStandard,
+};
+
+
+
+/*
+ * Processing Module registering function
+ */
+static void registerProcessingLTTVStandard()
+{
+       g_queue_push_tail(&processingModules, &processingModuleLTTVStandard);
+
+       createQuarks();
+}
+
+
+/*
+ * Allocate and initialize data structures for synchronizing a traceset.
+ * Register event hooks.
+ *
+ * Args:
+ *   syncState:    container for synchronization data.
+ *                 This function allocates these processingData members:
+ *                 traceNumTable
+ *                 pendingRecv
+ *                 hookListList
+ *                 stats
+ *   traceSetContext: set of LTTV traces
+ */
+static void initProcessingLTTVStandard(SyncState* const syncState, LttvTracesetContext*
+       const traceSetContext)
+{
+       unsigned int i;
+       ProcessingDataLTTVStandard* processingData;
+
+       processingData= malloc(sizeof(ProcessingDataLTTVStandard));
+       syncState->processingData= processingData;
+       processingData->traceSetContext= traceSetContext;
+
+       if (syncState->stats)
+       {
+               processingData->stats= calloc(1, sizeof(ProcessingStatsLTTVStandard));
+       }
+       else
+       {
+               processingData->stats= NULL;
+       }
+
+       processingData->traceNumTable= g_hash_table_new(&g_direct_hash, NULL);
+       processingData->hookListList= g_array_sized_new(FALSE, FALSE,
+               sizeof(GArray*), syncState->traceNb);
+       processingData->pendingRecv= malloc(sizeof(GHashTable*) *
+               syncState->traceNb);
+
+       for(i= 0; i < syncState->traceNb; i++)
+       {
+               g_hash_table_insert(processingData->traceNumTable,
+                       processingData->traceSetContext->traces[i]->t, (gpointer) i);
+       }
+
+       for(i= 0; i < syncState->traceNb; i++)
+       {
+               processingData->pendingRecv[i]= g_hash_table_new_full(&g_direct_hash,
+                       NULL, NULL, &gdnDestroyEvent);
+       }
+
+       registerHooks(processingData->hookListList, traceSetContext,
+               &processEventLTTVStandard, syncState);
+}
+
+
+/*
+ * Call the partial processing destroyer, obtain and adjust the factors from
+ * downstream
+ *
+ * Args:
+ *   syncState     container for synchronization data.
+ */
+static void finalizeProcessingLTTVStandard(SyncState* const syncState)
+{
+       unsigned int i;
+       GArray* factors;
+       double minOffset, minDrift;
+       unsigned int refFreqTrace;
+       ProcessingDataLTTVStandard* processingData;
+
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+
+       partialDestroyProcessingLTTVStandard(syncState);
+
+       factors= syncState->matchingModule->finalizeMatching(syncState);
+
+       /* The offsets are adjusted so the lowest one is 0. This is done because
+        * of a Lttv specific limitation: events cannot have negative times. By
+        * having non-negative offsets, events cannot be moved backwards to
+        * negative times.
+        */
+       minOffset= 0;
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               minOffset= MIN(g_array_index(factors, Factors, i).offset, minOffset);
+       }
+
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               g_array_index(factors, Factors, i).offset-= minOffset;
+       }
+
+       /* Because the timestamps are corrected at the TSC level (not at the
+        * LttTime level) all trace frequencies must be made equal. We choose to
+        * use the frequency of the system with the lowest drift
+        */
+       minDrift= INFINITY;
+       refFreqTrace= 0;
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               if (g_array_index(factors, Factors, i).drift < minDrift)
+               {
+                       minDrift= g_array_index(factors, Factors, i).drift;
+                       refFreqTrace= i;
+               }
+       }
+       g_assert(syncState->traceNb == 0 || minDrift != INFINITY);
+
+       // Write the factors to the LttTrace structures
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               LttTrace* t;
+               Factors* traceFactors;
+
+               t= processingData->traceSetContext->traces[i]->t;
+               traceFactors= &g_array_index(factors, Factors, i);
+
+               t->drift= traceFactors->drift;
+               t->offset= traceFactors->offset;
+               t->start_freq=
+                       processingData->traceSetContext->traces[refFreqTrace]->t->start_freq;
+               t->freq_scale=
+                       processingData->traceSetContext->traces[refFreqTrace]->t->freq_scale;
+               t->start_time_from_tsc =
+                       ltt_time_from_uint64(tsc_to_uint64(t->freq_scale, t->start_freq,
+                                       t->drift * t->start_tsc + t->offset));
+       }
+
+       g_array_free(factors, TRUE);
+
+       lttv_traceset_context_compute_time_span(processingData->traceSetContext,
+               &processingData->traceSetContext->time_span);
+
+       g_debug("traceset start %ld.%09ld end %ld.%09ld\n",
+               processingData->traceSetContext->time_span.start_time.tv_sec,
+               processingData->traceSetContext->time_span.start_time.tv_nsec,
+               processingData->traceSetContext->time_span.end_time.tv_sec,
+               processingData->traceSetContext->time_span.end_time.tv_nsec);
+}
+
+
+/*
+ * Print statistics related to processing and downstream modules. Must be
+ * called after finalizeProcessing.
+ *
+ * Args:
+ *   syncState     container for synchronization data.
+ */
+static void printProcessingStatsLTTVStandard(SyncState* const syncState)
+{
+       unsigned int i;
+       ProcessingDataLTTVStandard* processingData;
+
+       if (!syncState->stats)
+       {
+               return;
+       }
+
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+
+       printf("LTTV processing stats:\n");
+       printf("\treceived frames: %d\n", processingData->stats->totRecv);
+       printf("\treceived frames that are IP: %d\n",
+               processingData->stats->totRecvIp);
+       printf("\treceived and processed packets that are TCP: %d\n",
+               processingData->stats->totInE);
+       printf("\tsent packets that are TCP: %d\n",
+               processingData->stats->totOutE);
+
+       if (syncState->matchingModule->printMatchingStats != NULL)
+       {
+               syncState->matchingModule->printMatchingStats(syncState);
+       }
+
+       printf("Resulting synchronization factors:\n");
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               LttTrace* t;
+
+               t= processingData->traceSetContext->traces[i]->t;
+
+               printf("\ttrace %u drift= %g offset= %g (%f) start time= %ld.%09ld\n",
+                       i, t->drift, t->offset, (double) tsc_to_uint64(t->freq_scale,
+                               t->start_freq, t->offset) / NANOSECONDS_PER_SECOND,
+                       t->start_time_from_tsc.tv_sec, t->start_time_from_tsc.tv_nsec);
+       }
+}
+
+
+/*
+ * Unregister event hooks. Deallocate processingData.
+ *
+ * Args:
+ *   syncState:    container for synchronization data.
+ *                 This function deallocates these processingData members:
+ *                 stats
+ */
+static void destroyProcessingLTTVStandard(SyncState* const syncState)
+{
+       ProcessingDataLTTVStandard* processingData;
+
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+
+       if (processingData == NULL)
+       {
+               return;
+       }
+
+       partialDestroyProcessingLTTVStandard(syncState);
+
+       if (syncState->stats)
+       {
+               free(processingData->stats);
+       }
+
+       free(syncState->processingData);
+       syncState->processingData= NULL;
+}
+
+
+/*
+ * Unregister event hooks. Deallocate some of processingData.
+ *
+ * This function can be called right after the events have been processed to
+ * free some data structures that are not needed for finalization.
+ *
+ * Args:
+ *   syncState:    container for synchronization data.
+ *                 This function deallocates these members:
+ *                 traceNumTable
+ *                 hookListList
+ *                 pendingRecv
+ */
+static void partialDestroyProcessingLTTVStandard(SyncState* const syncState)
+{
+       unsigned int i;
+       ProcessingDataLTTVStandard* processingData;
+
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+
+       if (processingData == NULL || processingData->traceNumTable == NULL)
+       {
+               return;
+       }
+
+       g_hash_table_destroy(processingData->traceNumTable);
+       processingData->traceNumTable= NULL;
+
+       for(i= 0; i < syncState->traceNb; i++)
+       {
+
+               g_debug("Cleaning up pendingRecv list\n");
+               g_hash_table_destroy(processingData->pendingRecv[i]);
+       }
+       free(processingData->pendingRecv);
+
+       unregisterHooks(processingData->hookListList,
+               processingData->traceSetContext);
+}
+
+
+/*
+ * Lttv hook function that will be called for network events
+ *
+ * Args:
+ *   hookData:     LttvTraceHook* for the type of event that generated the call
+ *   callData:     LttvTracefileContext* at the moment of the event
+ *
+ * Returns:
+ *   FALSE         Always returns FALSE, meaning to keep processing hooks for
+ *                 this event
+ */
+static gboolean processEventLTTVStandard(void* hookData, void* callData)
+{
+       LttvTraceHook* traceHook;
+       LttvTracefileContext* tfc;
+       LttEvent* event;
+       LttTime time;
+       LttCycleCount tsc;
+       LttTrace* trace;
+       unsigned long traceNum;
+       struct marker_info* info;
+       SyncState* syncState;
+       ProcessingDataLTTVStandard* processingData;
+
+       traceHook= (LttvTraceHook*) hookData;
+       tfc= (LttvTracefileContext*) callData;
+       syncState= (SyncState*) traceHook->hook_data;
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+       event= ltt_tracefile_get_event(tfc->tf);
+       time= ltt_event_time(event);
+       tsc= ltt_event_cycle_count(event);
+       trace= tfc->t_context->t;
+       info= marker_get_info_from_id(tfc->tf->mdata, event->event_id);
+
+       g_assert(g_hash_table_lookup_extended(processingData->traceNumTable,
+                       trace, NULL, (gpointer*) &traceNum));
+
+       g_debug("XXXX process event: time: %ld.%09ld trace: %ld (%p) name: %s ",
+               (long) time.tv_sec, time.tv_nsec, traceNum, trace,
+               g_quark_to_string(info->name));
+
+       if (info->name == LTT_EVENT_DEV_XMIT)
+       {
+               Event* outE;
+
+               if (!ltt_event_get_unsigned(event,
+                               lttv_trace_get_hook_field(traceHook, 1)) == ETH_P_IP ||
+                       !ltt_event_get_unsigned(event,
+                               lttv_trace_get_hook_field(traceHook, 2)) == IPPROTO_TCP)
+               {
+                       return FALSE;
+               }
+
+               if (syncState->stats)
+               {
+                       processingData->stats->totOutE++;
+               }
+
+               outE= malloc(sizeof(Event));
+               outE->traceNum= traceNum;
+               outE->time= tsc;
+               outE->type= TCP;
+               outE->destroy= &destroyTCPEvent;
+               outE->event.tcpEvent= malloc(sizeof(TCPEvent));
+               outE->event.tcpEvent->direction= OUT;
+               outE->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
+               outE->event.tcpEvent->segmentKey->connectionKey.saddr=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       3));
+               outE->event.tcpEvent->segmentKey->connectionKey.daddr=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       4));
+               outE->event.tcpEvent->segmentKey->tot_len=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       5));
+               outE->event.tcpEvent->segmentKey->ihl= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 6));
+               outE->event.tcpEvent->segmentKey->connectionKey.source=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       7));
+               outE->event.tcpEvent->segmentKey->connectionKey.dest=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       8));
+               outE->event.tcpEvent->segmentKey->seq= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 9));
+               outE->event.tcpEvent->segmentKey->ack_seq=
+                       ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
+                                       10));
+               outE->event.tcpEvent->segmentKey->doff= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 11));
+               outE->event.tcpEvent->segmentKey->ack= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 12));
+               outE->event.tcpEvent->segmentKey->rst= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 13));
+               outE->event.tcpEvent->segmentKey->syn= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 14));
+               outE->event.tcpEvent->segmentKey->fin= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 15));
+
+               syncState->matchingModule->matchEvent(syncState, outE);
+
+               g_debug("Output event done\n");
+       }
+       else if (info->name == LTT_EVENT_DEV_RECEIVE)
+       {
+               guint32 protocol;
+
+               if (syncState->stats)
+               {
+                       processingData->stats->totRecv++;
+               }
+
+               protocol= ltt_event_get_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 1));
+
+               if (protocol == ETH_P_IP)
+               {
+                       Event* inE;
+                       void* skb;
+
+                       if (syncState->stats)
+                       {
+                               processingData->stats->totRecvIp++;
+                       }
+
+                       inE= malloc(sizeof(Event));
+                       inE->traceNum= traceNum;
+                       inE->time= tsc;
+                       inE->event.tcpEvent= NULL;
+                       inE->destroy= &destroyEvent;
+
+                       skb= (void*) (long) ltt_event_get_long_unsigned(event,
+                               lttv_trace_get_hook_field(traceHook, 0));
+                       g_hash_table_replace(processingData->pendingRecv[traceNum], skb,
+                               inE);
+
+                       g_debug("Adding inE %p for skb %p to pendingRecv\n", inE, skb);
+               }
+               else
+               {
+                       g_debug("\n");
+               }
+       }
+       else if (info->name == LTT_EVENT_TCPV4_RCV)
+       {
+               Event* inE;
+               void* skb;
+
+               // Search pendingRecv for an event with the same skb
+               skb= (void*) (long) ltt_event_get_long_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 0));
+
+               inE= (Event*)
+                       g_hash_table_lookup(processingData->pendingRecv[traceNum], skb);
+               if (inE == NULL)
+               {
+                       // This should only happen in case of lost events
+                       g_debug("No matching pending receive event found\n");
+               }
+               else
+               {
+                       if (syncState->stats)
+                       {
+                               processingData->stats->totInE++;
+                       }
+
+                       // If it's there, remove it and proceed with a receive event
+                       g_hash_table_steal(processingData->pendingRecv[traceNum], skb);
+
+                       inE->type= TCP;
+                       inE->event.tcpEvent= malloc(sizeof(TCPEvent));
+                       inE->destroy= &destroyTCPEvent;
+                       inE->event.tcpEvent->direction= IN;
+                       inE->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
+                       inE->event.tcpEvent->segmentKey->connectionKey.saddr=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 1));
+                       inE->event.tcpEvent->segmentKey->connectionKey.daddr=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 2));
+                       inE->event.tcpEvent->segmentKey->tot_len=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 3));
+                       inE->event.tcpEvent->segmentKey->ihl=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 4));
+                       inE->event.tcpEvent->segmentKey->connectionKey.source=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 5));
+                       inE->event.tcpEvent->segmentKey->connectionKey.dest=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 6));
+                       inE->event.tcpEvent->segmentKey->seq=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 7));
+                       inE->event.tcpEvent->segmentKey->ack_seq=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 8));
+                       inE->event.tcpEvent->segmentKey->doff=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 9));
+                       inE->event.tcpEvent->segmentKey->ack=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 10));
+                       inE->event.tcpEvent->segmentKey->rst=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 11));
+                       inE->event.tcpEvent->segmentKey->syn=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 12));
+                       inE->event.tcpEvent->segmentKey->fin=
+                               ltt_event_get_unsigned(event,
+                                       lttv_trace_get_hook_field(traceHook, 13));
+
+                       syncState->matchingModule->matchEvent(syncState, inE);
+
+                       g_debug("Input event %p for skb %p done\n", inE, skb);
+               }
+       }
+       else if (info->name == LTT_EVENT_NETWORK_IPV4_INTERFACE)
+       {
+               char* name;
+               guint64 address;
+               gint64 up;
+               char addressString[17];
+
+               address= ltt_event_get_long_unsigned(event,
+                       lttv_trace_get_hook_field(traceHook, 1));
+               up= ltt_event_get_long_int(event, lttv_trace_get_hook_field(traceHook,
+                               2));
+               /* name must be the last field to get or else copy the string, see the
+                * doc for ltt_event_get_string()
+                */
+               name= ltt_event_get_string(event, lttv_trace_get_hook_field(traceHook,
+                               0));
+
+               convertIP(addressString, address);
+
+               g_debug("name \"%s\" address %s up %lld\n", name, addressString, up);
+       }
+       else
+       {
+               g_assert_not_reached();
+       }
+
+       return FALSE;
+}
+
+
+/*
+ * Write the processing-specific graph lines in the gnuplot script (none at
+ * the moment). Call the downstream module's graph function.
+ *
+ * Args:
+ *   stream:       stream where to write the data
+ *   syncState:    container for synchronization data
+ *   i:            first trace number
+ *   j:            second trace number, garanteed to be larger than i
+ */
+static void writeProcessingGraphsPlotsLTTVStandard(FILE* stream, SyncState*
+       const syncState, const unsigned int i, const unsigned int j)
+{
+       if (syncState->matchingModule->writeMatchingGraphsPlots != NULL)
+       {
+               syncState->matchingModule->writeMatchingGraphsPlots(stream, syncState,
+                       i, j);
+       }
+}
+
+
+/*
+ * Write the processing-specific options in the gnuplot script. Call the
+ * downstream module's options function.
+ *
+ * Args:
+ *   stream:       stream where to write the data
+ *   syncState:    container for synchronization data
+ *   i:            first trace number
+ *   j:            second trace number, garanteed to be larger than i
+ */
+static void writeProcessingGraphsOptionsLTTVStandard(FILE* stream, SyncState*
+       const syncState, const unsigned int i, const unsigned int j)
+{
+       ProcessingDataLTTVStandard* processingData;
+       LttTrace* traceI, * traceJ;
+
+       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
+
+       traceI= processingData->traceSetContext->traces[i]->t;
+       traceJ= processingData->traceSetContext->traces[j]->t;
+
+       fprintf(stream,
+               "set x2label \"Clock %1$d (s)\"\n"
+               "set x2range [GPVAL_X_MIN / %2$.1f : GPVAL_X_MAX / %2$.1f]\n"
+               "set x2tics\n"
+               "set y2label \"Clock %3$d (s)\"\n"
+               "set y2range [GPVAL_Y_MIN / %4$.1f : GPVAL_Y_MAX / %4$.1f]\n"
+               "set y2tics\n", i, (double) traceI->start_freq / traceI->freq_scale,
+               j, (double) traceJ->start_freq / traceJ->freq_scale);
+
+       if (syncState->matchingModule->writeMatchingGraphsOptions != NULL)
+       {
+               syncState->matchingModule->writeMatchingGraphsOptions(stream,
+                       syncState, i, j);
+       }
+}
diff --git a/lttv/lttv/sync/event_processing_lttng_standard.h b/lttv/lttv/sync/event_processing_lttng_standard.h
new file mode 100644 (file)
index 0000000..15139ec
--- /dev/null
@@ -0,0 +1,55 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef EVENT_PROCESSING_LTTV_STANDARD_H
+#define EVENT_PROCESSING_LTTV_STANDARD_H
+
+#include <glib.h>
+
+#include <lttv/tracecontext.h>
+
+#include "event_processing.h"
+
+typedef struct
+{
+       int totRecv,
+               totRecvIp,
+               totInE,
+               totOutE;
+} ProcessingStatsLTTVStandard;
+
+typedef struct
+{
+       LttvTracesetContext* traceSetContext;
+
+       // unsigned int traceNumTable[trace*]
+       GHashTable* traceNumTable;
+
+       // hookListList conceptually is a two dimensionnal array of LttvTraceHook
+       // elements. It uses GArrays to interface with other lttv functions that
+       // do.
+       // LttvTraceHook hookListList[traceNum][hookNum]
+       GArray* hookListList;
+
+       // inE* pendingRecv[traceNb]
+       GHashTable** pendingRecv;
+
+       ProcessingStatsLTTVStandard* stats;
+} ProcessingDataLTTVStandard;
+
+#endif
diff --git a/lttv/lttv/sync/event_processing_lttv_common.c b/lttv/lttv/sync/event_processing_lttv_common.c
deleted file mode 100644 (file)
index b0d26c9..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "event_processing_lttv_common.h"
-
-
-#ifndef g_info
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-
-/*
- * Initialize the GQuarks needed to register the event hooks for
- * synchronization
- */
-void createQuarks()
-{
-       LTT_CHANNEL_NET= g_quark_from_static_string("net");
-       LTT_CHANNEL_NETIF_STATE= g_quark_from_static_string("netif_state");
-
-       LTT_EVENT_DEV_XMIT= g_quark_from_static_string("dev_xmit");
-       LTT_EVENT_DEV_RECEIVE= g_quark_from_static_string("dev_receive");
-       LTT_EVENT_TCPV4_RCV= g_quark_from_static_string("tcpv4_rcv");
-       LTT_EVENT_NETWORK_IPV4_INTERFACE=
-               g_quark_from_static_string("network_ipv4_interface");
-
-       LTT_FIELD_SKB= g_quark_from_static_string("skb");
-       LTT_FIELD_PROTOCOL= g_quark_from_static_string("protocol");
-       LTT_FIELD_NETWORK_PROTOCOL=
-               g_quark_from_static_string("network_protocol");
-       LTT_FIELD_TRANSPORT_PROTOCOL=
-               g_quark_from_static_string("transport_protocol");
-       LTT_FIELD_SADDR= g_quark_from_static_string("saddr");
-       LTT_FIELD_DADDR= g_quark_from_static_string("daddr");
-       LTT_FIELD_TOT_LEN= g_quark_from_static_string("tot_len");
-       LTT_FIELD_IHL= g_quark_from_static_string("ihl");
-       LTT_FIELD_SOURCE= g_quark_from_static_string("source");
-       LTT_FIELD_DEST= g_quark_from_static_string("dest");
-       LTT_FIELD_SEQ= g_quark_from_static_string("seq");
-       LTT_FIELD_ACK_SEQ= g_quark_from_static_string("ack_seq");
-       LTT_FIELD_DOFF= g_quark_from_static_string("doff");
-       LTT_FIELD_ACK= g_quark_from_static_string("ack");
-       LTT_FIELD_RST= g_quark_from_static_string("rst");
-       LTT_FIELD_SYN= g_quark_from_static_string("syn");
-       LTT_FIELD_FIN= g_quark_from_static_string("fin");
-       LTT_FIELD_NAME= g_quark_from_static_string("name");
-       LTT_FIELD_ADDRESS= g_quark_from_static_string("address");
-       LTT_FIELD_UP= g_quark_from_static_string("up");
-}
-
-
-/* Fill hookListList and add event hooks
- *
- * Note: possibilité de remettre le code avec lttv_trace_find_marker_ids (voir
- * r328)
- *
- * Args:
- *   hookListList: LttvTraceHook hookListList[traceNum][hookNum]
- *   traceSetContext: LTTV traceset
- *   hookFunction: call back function when event is encountered
- *   hookData:     data that will be made accessible to hookFunction in
- *                 arg0->hook_data
- */
-void registerHooks(GArray* hookListList, LttvTracesetContext* const
-       traceSetContext, LttvHook hookFunction, gpointer hookData)
-{
-       unsigned int i, j, k;
-       unsigned int traceNb= lttv_traceset_number(traceSetContext->ts);
-       struct {
-               GQuark channelName;
-               GQuark eventName;
-               GQuark* fields;
-       } eventHookInfoList[] = {
-               {
-                       .channelName= LTT_CHANNEL_NET,
-                       .eventName= LTT_EVENT_DEV_XMIT,
-                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_NETWORK_PROTOCOL,
-                               LTT_FIELD_TRANSPORT_PROTOCOL, LTT_FIELD_SADDR,
-                               LTT_FIELD_DADDR, LTT_FIELD_TOT_LEN, LTT_FIELD_IHL,
-                               LTT_FIELD_SOURCE, LTT_FIELD_DEST, LTT_FIELD_SEQ,
-                               LTT_FIELD_ACK_SEQ, LTT_FIELD_DOFF, LTT_FIELD_ACK,
-                               LTT_FIELD_RST, LTT_FIELD_SYN, LTT_FIELD_FIN),
-               }, {
-                       .channelName= LTT_CHANNEL_NET,
-                       .eventName= LTT_EVENT_DEV_RECEIVE,
-                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_PROTOCOL),
-               }, {
-                       .channelName= LTT_CHANNEL_NET,
-                       .eventName= LTT_EVENT_TCPV4_RCV,
-                       .fields= FIELD_ARRAY(LTT_FIELD_SKB, LTT_FIELD_SADDR,
-                               LTT_FIELD_DADDR, LTT_FIELD_TOT_LEN, LTT_FIELD_IHL,
-                               LTT_FIELD_SOURCE, LTT_FIELD_DEST, LTT_FIELD_SEQ,
-                               LTT_FIELD_ACK_SEQ, LTT_FIELD_DOFF, LTT_FIELD_ACK,
-                               LTT_FIELD_RST, LTT_FIELD_SYN, LTT_FIELD_FIN),
-               }, {
-                       .channelName= LTT_CHANNEL_NETIF_STATE,
-                       .eventName= LTT_EVENT_NETWORK_IPV4_INTERFACE,
-                       .fields= FIELD_ARRAY(LTT_FIELD_NAME, LTT_FIELD_ADDRESS,
-                               LTT_FIELD_UP),
-               }
-       }; // This is called a compound literal
-       unsigned int hookNb= sizeof(eventHookInfoList) / sizeof(*eventHookInfoList);
-
-       for(i= 0; i < traceNb; i++)
-       {
-               LttvTraceContext* tc;
-               GArray* hookList;
-               int retval;
-
-               tc= traceSetContext->traces[i];
-               hookList= g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
-               g_array_append_val(hookListList, hookList);
-
-               // Find the hooks
-               for (j= 0; j < hookNb; j++)
-               {
-                       guint old_len;
-
-                       old_len= hookList->len;
-                       retval= lttv_trace_find_hook(tc->t,
-                               eventHookInfoList[j].channelName,
-                               eventHookInfoList[j].eventName, eventHookInfoList[j].fields,
-                               hookFunction, hookData, &hookList);
-                       if (retval != 0)
-                       {
-                               g_warning("Trace %d contains no %s.%s marker\n", i,
-                                       g_quark_to_string(eventHookInfoList[j].channelName),
-                                       g_quark_to_string(eventHookInfoList[j].eventName));
-                       }
-                       else
-                       {
-                               g_assert(hookList->len - old_len == 1);
-                       }
-               }
-
-               // Add the hooks to each tracefile's event_by_id hook list
-               for(j= 0; j < tc->tracefiles->len; j++)
-               {
-                       LttvTracefileContext* tfc;
-
-                       tfc= g_array_index(tc->tracefiles, LttvTracefileContext*, j);
-
-                       for(k= 0; k < hookList->len; k++)
-                       {
-                               LttvTraceHook* traceHook;
-
-                               traceHook= &g_array_index(hookList, LttvTraceHook, k);
-                               if (traceHook->hook_data != hookData)
-                               {
-                                       g_assert_not_reached();
-                               }
-                               if (traceHook->mdata == tfc->tf->mdata)
-                               {
-                                       lttv_hooks_add(lttv_hooks_by_id_find(tfc->event_by_id,
-                                                       traceHook->id), traceHook->h, traceHook,
-                                               LTTV_PRIO_DEFAULT);
-                               }
-                       }
-               }
-       }
-}
-
-
-/* Remove event hooks and free hookListList
- *
- * Args:
- *   hookListList: LttvTraceHook hookListList[traceNum][hookNum]
- *   traceSetContext: LTTV traceset
- */
-void unregisterHooks(GArray* hookListList, LttvTracesetContext* const
-       traceSetContext)
-{
-       unsigned int i, j, k;
-       unsigned int traceNb= lttv_traceset_number(traceSetContext->ts);
-
-       for(i= 0; i < traceNb; i++)
-       {
-               LttvTraceContext* tc;
-               GArray* hookList;
-
-               tc= traceSetContext->traces[i];
-               hookList= g_array_index(hookListList, GArray*, i);
-
-               // Remove the hooks from each tracefile's event_by_id hook list
-               for(j= 0; j < tc->tracefiles->len; j++)
-               {
-                       LttvTracefileContext* tfc;
-
-                       tfc= g_array_index(tc->tracefiles, LttvTracefileContext*, j);
-
-                       for(k= 0; k < hookList->len; k++)
-                       {
-                               LttvTraceHook* traceHook;
-
-                               traceHook= &g_array_index(hookList, LttvTraceHook, k);
-                               if (traceHook->mdata == tfc->tf->mdata)
-                               {
-                                       lttv_hooks_remove_data(lttv_hooks_by_id_find(tfc->event_by_id,
-                                                       traceHook->id), traceHook->h, traceHook);
-                               }
-                       }
-               }
-
-               g_array_free(hookList, TRUE);
-       }
-       g_array_free(hookListList, TRUE);
-}
diff --git a/lttv/lttv/sync/event_processing_lttv_common.h b/lttv/lttv/sync/event_processing_lttv_common.h
deleted file mode 100644 (file)
index aa34cfc..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef EVENT_PROCESSING_LTTNG_COMMON_H
-#define EVENT_PROCESSING_LTTNG_COMMON_H
-
-#include <glib.h>
-
-#include <lttv/tracecontext.h>
-
-
-GQuark
-       LTT_CHANNEL_NET,
-       LTT_CHANNEL_NETIF_STATE;
-
-GQuark
-       LTT_EVENT_DEV_XMIT,
-       LTT_EVENT_DEV_RECEIVE,
-       LTT_EVENT_TCPV4_RCV,
-       LTT_EVENT_NETWORK_IPV4_INTERFACE;
-
-GQuark
-       LTT_FIELD_SKB,
-       LTT_FIELD_PROTOCOL,
-       LTT_FIELD_NETWORK_PROTOCOL,
-       LTT_FIELD_TRANSPORT_PROTOCOL,
-       LTT_FIELD_SADDR,
-       LTT_FIELD_DADDR,
-       LTT_FIELD_TOT_LEN,
-       LTT_FIELD_IHL,
-       LTT_FIELD_SOURCE,
-       LTT_FIELD_DEST,
-       LTT_FIELD_SEQ,
-       LTT_FIELD_ACK_SEQ,
-       LTT_FIELD_DOFF,
-       LTT_FIELD_ACK,
-       LTT_FIELD_RST,
-       LTT_FIELD_SYN,
-       LTT_FIELD_FIN,
-       LTT_FIELD_NAME,
-    LTT_FIELD_ADDRESS,
-    LTT_FIELD_UP;
-
-
-void createQuarks();
-void registerHooks(GArray* hookListList, LttvTracesetContext* const
-       traceSetContext, LttvHook hookFunction, gpointer
-       hookData);
-void unregisterHooks(GArray* hookListList, LttvTracesetContext* const
-       traceSetContext);
-
-#endif
diff --git a/lttv/lttv/sync/event_processing_lttv_null.c b/lttv/lttv/sync/event_processing_lttv_null.c
deleted file mode 100644 (file)
index 678e3c3..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "sync_chain.h"
-#include "event_processing_lttv_common.h"
-
-#include "event_processing_lttv_null.h"
-
-
-#ifndef g_info
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-
-// Functions common to all processing modules
-static void initProcessingLTTVNull(SyncState* const syncState,
-       LttvTracesetContext* const traceSetContext);
-static void destroyProcessingLTTVNull(SyncState* const syncState);
-
-static void finalizeProcessingLTTVNull(SyncState* const syncState);
-
-// Functions specific to this module
-static void registerProcessingLTTVNull() __attribute__((constructor (102)));
-static gboolean processEventLTTVNull(void* hookData, void* callData);
-
-
-static ProcessingModule processingModuleLTTVNull = {
-       .name= "LTTV-null",
-       .initProcessing= &initProcessingLTTVNull,
-       .destroyProcessing= &destroyProcessingLTTVNull,
-       .finalizeProcessing= &finalizeProcessingLTTVNull,
-       .printProcessingStats= NULL,
-       .writeProcessingGraphsPlots= NULL,
-       .writeProcessingGraphsOptions= NULL,
-};
-
-
-
-/*
- * Processing Module registering function
- */
-static void registerProcessingLTTVNull()
-{
-       g_queue_push_tail(&processingModules, &processingModuleLTTVNull);
-
-       createQuarks();
-}
-
-
-/*
- * Allocate and initialize data structures for synchronizing a traceset.
- * Register event hooks.
- *
- * Args:
- *   syncState:    container for synchronization data.
- *                 This function allocates these processingData members:
- *                 hookListList
- *   traceSetContext: set of LTTV traces
- */
-static void initProcessingLTTVNull(SyncState* const syncState,
-       LttvTracesetContext* const traceSetContext)
-{
-       ProcessingDataLTTVNull* processingData;
-
-       processingData= malloc(sizeof(ProcessingDataLTTVNull));
-       syncState->processingData= processingData;
-       processingData->traceSetContext= traceSetContext;
-
-       processingData->hookListList= g_array_sized_new(FALSE, FALSE,
-               sizeof(GArray*), syncState->traceNb);
-
-       registerHooks(processingData->hookListList, traceSetContext,
-               &processEventLTTVNull, syncState);
-}
-
-
-/*
- * Nothing to do
- *
- * Args:
- *   syncState     container for synchronization data.
- */
-static void finalizeProcessingLTTVNull(SyncState* const syncState)
-{
-       return;
-}
-
-
-/*
- * Unregister event hooks. Deallocate processingData.
- *
- * Args:
- *   syncState:    container for synchronization data.
- *                 This function deallocates these members:
- *                 hookListList
- */
-static void destroyProcessingLTTVNull(SyncState* const syncState)
-{
-       ProcessingDataLTTVNull* processingData;
-
-       processingData= (ProcessingDataLTTVNull*) syncState->processingData;
-
-       if (processingData == NULL)
-       {
-               return;
-       }
-
-       unregisterHooks(processingData->hookListList,
-               processingData->traceSetContext);
-
-       free(syncState->processingData);
-       syncState->processingData= NULL;
-}
-
-
-/*
- * Lttv hook function that will be called for network events
- *
- * Args:
- *   hookData:     LttvTraceHook* for the type of event that generated the call
- *   callData:     LttvTracefileContext* at the moment of the event
- *
- * Returns:
- *   FALSE         Always returns FALSE, meaning to keep processing hooks for
- *                 this event
- */
-static gboolean processEventLTTVNull(void* hookData, void* callData)
-{
-       return FALSE;
-}
diff --git a/lttv/lttv/sync/event_processing_lttv_null.h b/lttv/lttv/sync/event_processing_lttv_null.h
deleted file mode 100644 (file)
index 090b6b8..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef EVENT_PROCESSING_LTTV_NULL_H
-#define EVENT_PROCESSING_LTTV_NULL_H
-
-#include <glib.h>
-
-#include <lttv/tracecontext.h>
-
-
-typedef struct
-{
-       LttvTracesetContext* traceSetContext;
-
-       // hookListList conceptually is a two dimensionnal array of LttvTraceHook
-       // elements. It uses GArrays to interface with other lttv functions that
-       // do.
-       // LttvTraceHook hookListList[traceNum][hookNum]
-       GArray* hookListList;
-} ProcessingDataLTTVNull;
-
-#endif
diff --git a/lttv/lttv/sync/event_processing_lttv_standard.c b/lttv/lttv/sync/event_processing_lttv_standard.c
deleted file mode 100644 (file)
index b981d3a..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#define _ISOC99_SOURCE
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <linux/if_ether.h>
-#include <math.h>
-#include <netinet/in.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "sync_chain.h"
-#include "event_processing_lttv_common.h"
-
-#include "event_processing_lttv_standard.h"
-
-
-#ifndef g_info
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-
-// Functions common to all processing modules
-static void initProcessingLTTVStandard(SyncState* const syncState,
-       LttvTracesetContext* const traceSetContext);
-static void destroyProcessingLTTVStandard(SyncState* const syncState);
-
-static void finalizeProcessingLTTVStandard(SyncState* const syncState);
-static void printProcessingStatsLTTVStandard(SyncState* const syncState);
-static void writeProcessingGraphsPlotsLTTVStandard(FILE* stream, SyncState*
-       const syncState, const unsigned int i, const unsigned int j);
-static void writeProcessingGraphsOptionsLTTVStandard(FILE* stream, SyncState*
-       const syncState, const unsigned int i, const unsigned int j);
-
-// Functions specific to this module
-static void registerProcessingLTTVStandard() __attribute__((constructor (102)));
-static gboolean processEventLTTVStandard(void* hookData, void* callData);
-static void partialDestroyProcessingLTTVStandard(SyncState* const syncState);
-
-
-static ProcessingModule processingModuleLTTVStandard = {
-       .name= "LTTV-standard",
-       .initProcessing= &initProcessingLTTVStandard,
-       .destroyProcessing= &destroyProcessingLTTVStandard,
-       .finalizeProcessing= &finalizeProcessingLTTVStandard,
-       .printProcessingStats= &printProcessingStatsLTTVStandard,
-       .writeProcessingGraphsPlots= &writeProcessingGraphsPlotsLTTVStandard,
-       .writeProcessingGraphsOptions= &writeProcessingGraphsOptionsLTTVStandard,
-};
-
-
-
-/*
- * Processing Module registering function
- */
-static void registerProcessingLTTVStandard()
-{
-       g_queue_push_tail(&processingModules, &processingModuleLTTVStandard);
-
-       createQuarks();
-}
-
-
-/*
- * Allocate and initialize data structures for synchronizing a traceset.
- * Register event hooks.
- *
- * Args:
- *   syncState:    container for synchronization data.
- *                 This function allocates these processingData members:
- *                 traceNumTable
- *                 pendingRecv
- *                 hookListList
- *                 stats
- *   traceSetContext: set of LTTV traces
- */
-static void initProcessingLTTVStandard(SyncState* const syncState, LttvTracesetContext*
-       const traceSetContext)
-{
-       unsigned int i;
-       ProcessingDataLTTVStandard* processingData;
-
-       processingData= malloc(sizeof(ProcessingDataLTTVStandard));
-       syncState->processingData= processingData;
-       processingData->traceSetContext= traceSetContext;
-
-       if (syncState->stats)
-       {
-               processingData->stats= calloc(1, sizeof(ProcessingStatsLTTVStandard));
-       }
-       else
-       {
-               processingData->stats= NULL;
-       }
-
-       processingData->traceNumTable= g_hash_table_new(&g_direct_hash, NULL);
-       processingData->hookListList= g_array_sized_new(FALSE, FALSE,
-               sizeof(GArray*), syncState->traceNb);
-       processingData->pendingRecv= malloc(sizeof(GHashTable*) *
-               syncState->traceNb);
-
-       for(i= 0; i < syncState->traceNb; i++)
-       {
-               g_hash_table_insert(processingData->traceNumTable,
-                       processingData->traceSetContext->traces[i]->t, (gpointer) i);
-       }
-
-       for(i= 0; i < syncState->traceNb; i++)
-       {
-               processingData->pendingRecv[i]= g_hash_table_new_full(&g_direct_hash,
-                       NULL, NULL, &gdnDestroyNetEvent);
-       }
-
-       registerHooks(processingData->hookListList, traceSetContext,
-               &processEventLTTVStandard, syncState);
-}
-
-
-/*
- * Call the partial processing destroyer, obtain and adjust the factors from
- * downstream
- *
- * Args:
- *   syncState     container for synchronization data.
- */
-static void finalizeProcessingLTTVStandard(SyncState* const syncState)
-{
-       unsigned int i;
-       GArray* factors;
-       double minOffset, minDrift;
-       unsigned int refFreqTrace;
-       ProcessingDataLTTVStandard* processingData;
-
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-
-       partialDestroyProcessingLTTVStandard(syncState);
-
-       factors= syncState->matchingModule->finalizeMatching(syncState);
-
-       /* The offsets are adjusted so the lowest one is 0. This is done because
-        * of a Lttv specific limitation: events cannot have negative times. By
-        * having non-negative offsets, events cannot be moved backwards to
-        * negative times.
-        */
-       minOffset= 0;
-       for (i= 0; i < syncState->traceNb; i++)
-       {
-               minOffset= MIN(g_array_index(factors, Factors, i).offset, minOffset);
-       }
-
-       for (i= 0; i < syncState->traceNb; i++)
-       {
-               g_array_index(factors, Factors, i).offset-= minOffset;
-       }
-
-       /* Because the timestamps are corrected at the TSC level (not at the
-        * LttTime level) all trace frequencies must be made equal. We choose to
-        * use the frequency of the system with the lowest drift
-        */
-       minDrift= INFINITY;
-       refFreqTrace= 0;
-       for (i= 0; i < syncState->traceNb; i++)
-       {
-               if (g_array_index(factors, Factors, i).drift < minDrift)
-               {
-                       minDrift= g_array_index(factors, Factors, i).drift;
-                       refFreqTrace= i;
-               }
-       }
-       g_assert(syncState->traceNb == 0 || minDrift != INFINITY);
-
-       // Write the factors to the LttTrace structures
-       for (i= 0; i < syncState->traceNb; i++)
-       {
-               LttTrace* t;
-               Factors* traceFactors;
-
-               t= processingData->traceSetContext->traces[i]->t;
-               traceFactors= &g_array_index(factors, Factors, i);
-
-               t->drift= traceFactors->drift;
-               t->offset= traceFactors->offset;
-               t->start_freq=
-                       processingData->traceSetContext->traces[refFreqTrace]->t->start_freq;
-               t->freq_scale=
-                       processingData->traceSetContext->traces[refFreqTrace]->t->freq_scale;
-               t->start_time_from_tsc =
-                       ltt_time_from_uint64(tsc_to_uint64(t->freq_scale, t->start_freq,
-                                       t->drift * t->start_tsc + t->offset));
-       }
-
-       g_array_free(factors, TRUE);
-
-       lttv_traceset_context_compute_time_span(processingData->traceSetContext,
-               &processingData->traceSetContext->time_span);
-
-       g_debug("traceset start %ld.%09ld end %ld.%09ld\n",
-               processingData->traceSetContext->time_span.start_time.tv_sec,
-               processingData->traceSetContext->time_span.start_time.tv_nsec,
-               processingData->traceSetContext->time_span.end_time.tv_sec,
-               processingData->traceSetContext->time_span.end_time.tv_nsec);
-
-       return;
-}
-
-
-/*
- * Print statistics related to processing and downstream modules. Must be
- * called after finalizeProcessing.
- *
- * Args:
- *   syncState     container for synchronization data.
- */
-static void printProcessingStatsLTTVStandard(SyncState* const syncState)
-{
-       unsigned int i;
-       ProcessingDataLTTVStandard* processingData;
-
-       if (!syncState->stats)
-       {
-               return;
-       }
-
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-
-       printf("LTTV processing stats:\n");
-       printf("\treceived frames: %d\n", processingData->stats->totRecv);
-       printf("\treceived frames that are IP: %d\n",
-               processingData->stats->totRecvIp);
-       printf("\treceived and processed packets that are TCP: %d\n",
-               processingData->stats->totInE);
-       printf("\tsent packets that are TCP: %d\n",
-               processingData->stats->totOutE);
-
-       if (syncState->matchingModule->printMatchingStats != NULL)
-       {
-               syncState->matchingModule->printMatchingStats(syncState);
-       }
-
-       printf("Resulting synchronization factors:\n");
-       for (i= 0; i < syncState->traceNb; i++)
-       {
-               LttTrace* t;
-
-               t= processingData->traceSetContext->traces[i]->t;
-
-               printf("\ttrace %u drift= %g offset= %g (%f) start time= %ld.%09ld\n",
-                       i, t->drift, t->offset, (double) tsc_to_uint64(t->freq_scale,
-                               t->start_freq, t->offset) / NANOSECONDS_PER_SECOND,
-                       t->start_time_from_tsc.tv_sec, t->start_time_from_tsc.tv_nsec);
-       }
-}
-
-
-/*
- * Unregister event hooks. Deallocate processingData.
- *
- * Args:
- *   syncState:    container for synchronization data.
- *                 This function deallocates these processingData members:
- *                 stats
- */
-static void destroyProcessingLTTVStandard(SyncState* const syncState)
-{
-       ProcessingDataLTTVStandard* processingData;
-
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-
-       if (processingData == NULL)
-       {
-               return;
-       }
-
-       partialDestroyProcessingLTTVStandard(syncState);
-
-       if (syncState->stats)
-       {
-               free(processingData->stats);
-       }
-
-       free(syncState->processingData);
-       syncState->processingData= NULL;
-}
-
-
-/*
- * Unregister event hooks. Deallocate some of processingData.
- *
- * This function can be called right after the events have been processed to
- * free some data structures that are not needed for finalization.
- *
- * Args:
- *   syncState:    container for synchronization data.
- *                 This function deallocates these members:
- *                 traceNumTable
- *                 hookListList
- *                 pendingRecv
- */
-static void partialDestroyProcessingLTTVStandard(SyncState* const syncState)
-{
-       unsigned int i;
-       ProcessingDataLTTVStandard* processingData;
-
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-
-       if (processingData == NULL || processingData->traceNumTable == NULL)
-       {
-               return;
-       }
-
-       g_hash_table_destroy(processingData->traceNumTable);
-       processingData->traceNumTable= NULL;
-
-       for(i= 0; i < syncState->traceNb; i++)
-       {
-
-               g_debug("Cleaning up pendingRecv list\n");
-               g_hash_table_destroy(processingData->pendingRecv[i]);
-       }
-       free(processingData->pendingRecv);
-
-       unregisterHooks(processingData->hookListList,
-               processingData->traceSetContext);
-}
-
-
-/*
- * Lttv hook function that will be called for network events
- *
- * Args:
- *   hookData:     LttvTraceHook* for the type of event that generated the call
- *   callData:     LttvTracefileContext* at the moment of the event
- *
- * Returns:
- *   FALSE         Always returns FALSE, meaning to keep processing hooks for
- *                 this event
- */
-static gboolean processEventLTTVStandard(void* hookData, void* callData)
-{
-       LttvTraceHook* traceHook;
-       LttvTracefileContext* tfc;
-       LttEvent* event;
-       LttTime time;
-       LttCycleCount tsc;
-       LttTrace* trace;
-       unsigned long traceNum;
-       struct marker_info* info;
-       SyncState* syncState;
-       ProcessingDataLTTVStandard* processingData;
-
-       traceHook= (LttvTraceHook*) hookData;
-       tfc= (LttvTracefileContext*) callData;
-       syncState= (SyncState*) traceHook->hook_data;
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-       event= ltt_tracefile_get_event(tfc->tf);
-       time= ltt_event_time(event);
-       tsc= ltt_event_cycle_count(event);
-       trace= tfc->t_context->t;
-       info= marker_get_info_from_id(tfc->tf->mdata, event->event_id);
-
-       g_assert(g_hash_table_lookup_extended(processingData->traceNumTable,
-                       trace, NULL, (gpointer*) &traceNum));
-
-       g_debug("XXXX process event: time: %ld.%09ld trace: %ld (%p) name: %s ",
-               (long) time.tv_sec, time.tv_nsec, traceNum, trace,
-               g_quark_to_string(info->name));
-
-       if (info->name == LTT_EVENT_DEV_XMIT)
-       {
-               NetEvent* outE;
-
-               if (!ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 1)) == ETH_P_IP ||
-                       !ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 2)) == IPPROTO_TCP)
-               {
-                       return FALSE;
-               }
-
-               if (syncState->stats)
-               {
-                       processingData->stats->totOutE++;
-               }
-
-               outE= malloc(sizeof(NetEvent));
-               outE->packetKey= malloc(sizeof(PacketKey));
-
-               outE->traceNum= traceNum;
-               outE->tsc= tsc;
-               outE->skb= NULL;
-               outE->packetKey->connectionKey.saddr= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 3));
-               outE->packetKey->connectionKey.daddr= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 4));
-               outE->packetKey->tot_len= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 5));
-               outE->packetKey->ihl= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 6));
-               outE->packetKey->connectionKey.source= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 7));
-               outE->packetKey->connectionKey.dest= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 8));
-               outE->packetKey->seq= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 9));
-               outE->packetKey->ack_seq= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 10));
-               outE->packetKey->doff= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 11));
-               outE->packetKey->ack= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 12));
-               outE->packetKey->rst= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 13));
-               outE->packetKey->syn= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 14));
-               outE->packetKey->fin= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 15));
-
-               syncState->matchingModule->matchEvent(syncState, outE, OUT);
-
-               g_debug("Output event done\n");
-       }
-       else if (info->name == LTT_EVENT_DEV_RECEIVE)
-       {
-               guint32 protocol;
-
-               if (syncState->stats)
-               {
-                       processingData->stats->totRecv++;
-               }
-
-               protocol= ltt_event_get_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 1));
-
-               if (protocol == ETH_P_IP)
-               {
-                       NetEvent* inE;
-
-                       if (syncState->stats)
-                       {
-                               processingData->stats->totRecvIp++;
-                       }
-
-                       inE= malloc(sizeof(NetEvent));
-
-                       inE->traceNum= traceNum;
-                       inE->tsc= tsc;
-                       inE->skb= (void*) (long) ltt_event_get_long_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 0));
-                       inE->packetKey= NULL;
-
-                       g_hash_table_replace(processingData->pendingRecv[traceNum],
-                               inE->skb, inE);
-
-                       g_debug("Adding inE %p for skb %p to pendingRecv\n", inE, inE->skb);
-               }
-               else
-               {
-                       g_debug("\n");
-               }
-       }
-       else if (info->name == LTT_EVENT_TCPV4_RCV)
-       {
-               NetEvent* inE;
-               void* skb;
-
-               // Search pendingRecv for an event with the same skb
-               skb= (void*) (long) ltt_event_get_long_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 0));
-
-               inE= (NetEvent*)
-                       g_hash_table_lookup(processingData->pendingRecv[traceNum], skb);
-               if (inE == NULL)
-               {
-                       // This should only happen in case of lost events
-                       g_debug("No matching pending receive event found\n");
-               }
-               else
-               {
-                       if (syncState->stats)
-                       {
-                               processingData->stats->totInE++;
-                       }
-
-                       // If it's there, remove it and proceed with a receive event
-                       g_hash_table_steal(processingData->pendingRecv[traceNum], skb);
-
-                       inE->packetKey= malloc(sizeof(PacketKey));
-
-                       inE->packetKey->connectionKey.saddr= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 1));
-                       inE->packetKey->connectionKey.daddr= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 2));
-                       inE->packetKey->tot_len= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 3));
-                       inE->packetKey->ihl= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 4));
-                       inE->packetKey->connectionKey.source= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 5));
-                       inE->packetKey->connectionKey.dest= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 6));
-                       inE->packetKey->seq= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 7));
-                       inE->packetKey->ack_seq= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 8));
-                       inE->packetKey->doff= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 9));
-                       inE->packetKey->ack= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 10));
-                       inE->packetKey->rst= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 11));
-                       inE->packetKey->syn= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 12));
-                       inE->packetKey->fin= ltt_event_get_unsigned(event,
-                               lttv_trace_get_hook_field(traceHook, 13));
-
-                       syncState->matchingModule->matchEvent(syncState, inE, IN);
-
-                       g_debug("Input event %p for skb %p done\n", inE, skb);
-               }
-       }
-       else if (info->name == LTT_EVENT_NETWORK_IPV4_INTERFACE)
-       {
-               char* name;
-               guint64 address;
-               gint64 up;
-               char addressString[17];
-
-               address= ltt_event_get_long_unsigned(event,
-                       lttv_trace_get_hook_field(traceHook, 1));
-               up= ltt_event_get_long_int(event, lttv_trace_get_hook_field(traceHook,
-                               2));
-               /* name must be the last field to get or else copy the string, see the
-                * doc for ltt_event_get_string()
-                */
-               name= ltt_event_get_string(event, lttv_trace_get_hook_field(traceHook,
-                               0));
-
-               convertIP(addressString, address);
-
-               g_debug("name \"%s\" address %s up %lld\n", name, addressString, up);
-       }
-       else
-       {
-               g_assert_not_reached();
-       }
-
-       return FALSE;
-}
-
-
-/*
- * Write the processing-specific graph lines in the gnuplot script (none at
- * the moment). Call the downstream module's graph function.
- *
- * Args:
- *   stream:       stream where to write the data
- *   syncState:    container for synchronization data
- *   i:            first trace number
- *   j:            second trace number, garanteed to be larger than i
- */
-static void writeProcessingGraphsPlotsLTTVStandard(FILE* stream, SyncState*
-       const syncState, const unsigned int i, const unsigned int j)
-{
-       if (syncState->matchingModule->writeMatchingGraphsPlots != NULL)
-       {
-               syncState->matchingModule->writeMatchingGraphsPlots(stream, syncState,
-                       i, j);
-       }
-}
-
-
-/*
- * Write the processing-specific options in the gnuplot script. Call the
- * downstream module's options function.
- *
- * Args:
- *   stream:       stream where to write the data
- *   syncState:    container for synchronization data
- *   i:            first trace number
- *   j:            second trace number, garanteed to be larger than i
- */
-static void writeProcessingGraphsOptionsLTTVStandard(FILE* stream, SyncState*
-       const syncState, const unsigned int i, const unsigned int j)
-{
-       ProcessingDataLTTVStandard* processingData;
-       LttTrace* traceI, * traceJ;
-
-       processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
-
-       traceI= processingData->traceSetContext->traces[i]->t;
-       traceJ= processingData->traceSetContext->traces[j]->t;
-
-       fprintf(stream,
-               "set x2label \"Clock %1$d (s)\"\n"
-               "set x2range [GPVAL_X_MIN / %2$.1f : GPVAL_X_MAX / %2$.1f]\n"
-               "set x2tics\n"
-               "set y2label \"Clock %3$d (s)\"\n"
-               "set y2range [GPVAL_Y_MIN / %4$.1f : GPVAL_Y_MAX / %4$.1f]\n"
-               "set y2tics\n", i, (double) traceI->start_freq / traceI->freq_scale,
-               j, (double) traceJ->start_freq / traceJ->freq_scale);
-
-       if (syncState->matchingModule->writeMatchingGraphsOptions != NULL)
-       {
-               syncState->matchingModule->writeMatchingGraphsOptions(stream,
-                       syncState, i, j);
-       }
-}
diff --git a/lttv/lttv/sync/event_processing_lttv_standard.h b/lttv/lttv/sync/event_processing_lttv_standard.h
deleted file mode 100644 (file)
index 15139ec..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef EVENT_PROCESSING_LTTV_STANDARD_H
-#define EVENT_PROCESSING_LTTV_STANDARD_H
-
-#include <glib.h>
-
-#include <lttv/tracecontext.h>
-
-#include "event_processing.h"
-
-typedef struct
-{
-       int totRecv,
-               totRecvIp,
-               totInE,
-               totOutE;
-} ProcessingStatsLTTVStandard;
-
-typedef struct
-{
-       LttvTracesetContext* traceSetContext;
-
-       // unsigned int traceNumTable[trace*]
-       GHashTable* traceNumTable;
-
-       // hookListList conceptually is a two dimensionnal array of LttvTraceHook
-       // elements. It uses GArrays to interface with other lttv functions that
-       // do.
-       // LttvTraceHook hookListList[traceNum][hookNum]
-       GArray* hookListList;
-
-       // inE* pendingRecv[traceNb]
-       GHashTable** pendingRecv;
-
-       ProcessingStatsLTTVStandard* stats;
-} ProcessingDataLTTVStandard;
-
-#endif
diff --git a/lttv/lttv/sync/sync_chain.c b/lttv/lttv/sync/sync_chain.c
deleted file mode 100644 (file)
index 52e0bb9..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <lttv/module.h>
-#include <lttv/option.h>
-
-#include "sync_chain.h"
-
-
-#ifndef g_info
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-
-static void init();
-static void destroy();
-
-static void timeDiff(struct timeval* const end, const struct timeval* const start);
-
-static gint gcfCompareAnalysis(gconstpointer a, gconstpointer b);
-static gint gcfCompareProcessing(gconstpointer a, gconstpointer b);
-static void gfAppendAnalysisName(gpointer data, gpointer user_data);
-
-static gboolean optionSync;
-static gboolean optionSyncStats;
-static gboolean optionSyncNull;
-static char* optionSyncAnalysis;
-static gboolean optionSyncGraphs;
-static char* optionSyncGraphsDir;
-static char graphsDir[20];
-
-GQueue processingModules= G_QUEUE_INIT;
-GQueue matchingModules= G_QUEUE_INIT;
-GQueue analysisModules= G_QUEUE_INIT;
-
-
-/*
- * Module init function
- *
- * This function is declared to be the module initialization function. Event
- * modules are registered with a "constructor (102)" attribute except one in
- * each class (processing, matching, analysis) which is chosen to be the
- * default and which is registered with a "constructor (101)" attribute.
- * Constructors with no priority are called after constructors with
- * priorities. The result is that the list of event modules is known when this
- * function is executed.
- */
-static void init()
-{
-       GString* analysisModulesNames;
-       int retval;
-
-       g_debug("\t\t\tXXXX sync init\n");
-
-       optionSync= FALSE;
-       lttv_option_add("sync", '\0', "synchronize the time between the traces" ,
-               "none", LTTV_OPT_NONE, &optionSync, NULL, NULL);
-
-       optionSyncStats= FALSE;
-       lttv_option_add("sync-stats", '\0', "print statistics about the time "
-               "synchronization", "none", LTTV_OPT_NONE, &optionSyncStats, NULL,
-               NULL);
-
-       optionSyncNull= FALSE;
-       lttv_option_add("sync-null", '\0', "read the events but do not perform "
-               "any processing", "none", LTTV_OPT_NONE, &optionSyncNull, NULL, NULL);
-
-       g_assert(g_queue_get_length(&analysisModules) > 0);
-       optionSyncAnalysis= ((AnalysisModule*)
-               g_queue_peek_head(&analysisModules))->name;
-       analysisModulesNames= g_string_new("");
-       g_queue_foreach(&analysisModules, &gfAppendAnalysisName,
-               analysisModulesNames);
-       // remove the last ", "
-       g_string_truncate(analysisModulesNames, analysisModulesNames->len - 2);
-       lttv_option_add("sync-analysis", '\0', "specify the algorithm to use for "
-               "event analysis" , analysisModulesNames->str, LTTV_OPT_STRING,
-               &optionSyncAnalysis, NULL, NULL);
-       g_string_free(analysisModulesNames, TRUE);
-
-       optionSyncGraphs= FALSE;
-       lttv_option_add("sync-graphs", '\0', "output gnuplot graph showing "
-               "synchronization points", "none", LTTV_OPT_NONE, &optionSyncGraphs,
-               NULL, NULL);
-
-       retval= snprintf(graphsDir, sizeof(graphsDir), "graphs-%d", getpid());
-       if (retval > sizeof(graphsDir) - 1)
-       {
-               graphsDir[sizeof(graphsDir) - 1]= '\0';
-       }
-       optionSyncGraphsDir= graphsDir;
-       lttv_option_add("sync-graphs-dir", '\0', "specify the directory where to"
-               " store the graphs", graphsDir, LTTV_OPT_STRING, &optionSyncGraphsDir,
-               NULL, NULL);
-}
-
-
-/*
- * Module unload function
- */
-static void destroy()
-{
-       g_debug("\t\t\tXXXX sync destroy\n");
-
-       lttv_option_remove("sync");
-       lttv_option_remove("sync-stats");
-       lttv_option_remove("sync-null");
-       lttv_option_remove("sync-analysis");
-       lttv_option_remove("sync-graphs");
-       lttv_option_remove("sync-graphs-dir");
-}
-
-
-/*
- * Calculate a traceset's drift and offset values based on network events
- *
- * The individual correction factors are written out to each trace.
- *
- * Args:
- *   traceSetContext: traceset
- */
-void syncTraceset(LttvTracesetContext* const traceSetContext)
-{
-       SyncState* syncState;
-       struct timeval startTime, endTime;
-       struct rusage startUsage, endUsage;
-       GList* result;
-       char* cwd;
-       FILE* graphsStream;
-       int graphsFp;
-       int retval;
-
-       if (optionSync == FALSE)
-       {
-               g_debug("Not synchronizing traceset because option is disabled");
-               return;
-       }
-
-       if (optionSyncStats)
-       {
-               gettimeofday(&startTime, 0);
-               getrusage(RUSAGE_SELF, &startUsage);
-       }
-
-       // Initialize data structures
-       syncState= malloc(sizeof(SyncState));
-       syncState->traceNb= lttv_traceset_number(traceSetContext->ts);
-
-       if (optionSyncStats)
-       {
-               syncState->stats= true;
-       }
-       else
-       {
-               syncState->stats= false;
-       }
-
-       if (optionSyncGraphs)
-       {
-               syncState->graphs= optionSyncGraphsDir;
-       }
-       else
-       {
-               syncState->graphs= NULL;
-       }
-
-       // Identify and initialize processing module
-       syncState->processingData= NULL;
-       if (optionSyncNull)
-       {
-               result= g_queue_find_custom(&processingModules, "LTTV-null",
-                       &gcfCompareProcessing);
-       }
-       else
-       {
-               result= g_queue_find_custom(&processingModules, "LTTV-standard",
-                       &gcfCompareProcessing);
-       }
-       g_assert(result != NULL);
-       syncState->processingModule= (ProcessingModule*) result->data;
-
-       graphsStream= NULL;
-       if (syncState->graphs)
-       {
-               // Create the graph directory right away in case the module initialization
-               // functions have something to write in it.
-               cwd= changeToGraphDir(syncState->graphs);
-
-               if (syncState->processingModule->writeProcessingGraphsPlots != NULL)
-               {
-                       if ((graphsFp= open("graphs.gnu", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
-                                       S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
-                                       | S_IWOTH | S_IXOTH)) == -1)
-                       {
-                               g_error(strerror(errno));
-                       }
-                       if ((graphsStream= fdopen(graphsFp, "w")) == NULL)
-                       {
-                               g_error(strerror(errno));
-                       }
-               }
-
-               retval= chdir(cwd);
-               if (retval == -1)
-               {
-                       g_error(strerror(errno));
-               }
-               free(cwd);
-       }
-
-       syncState->processingModule->initProcessing(syncState, traceSetContext);
-
-       // Identify and initialize matching and analysis modules
-       syncState->matchingData= NULL;
-       syncState->analysisData= NULL;
-       if (optionSyncNull)
-       {
-               syncState->matchingModule= NULL;
-               syncState->analysisModule= NULL;
-       }
-       else
-       {
-               g_assert(g_queue_get_length(&matchingModules) == 1);
-               syncState->matchingModule= (MatchingModule*)
-                       g_queue_peek_head(&matchingModules);
-               syncState->matchingModule->initMatching(syncState);
-
-               result= g_queue_find_custom(&analysisModules, optionSyncAnalysis,
-                       &gcfCompareAnalysis);
-               if (result != NULL)
-               {
-                       syncState->analysisModule= (AnalysisModule*) result->data;
-                       syncState->analysisModule->initAnalysis(syncState);
-               }
-               else
-               {
-                       g_error("Analysis module '%s' not found", optionSyncAnalysis);
-               }
-       }
-
-       // Process traceset
-       lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero);
-       lttv_process_traceset_middle(traceSetContext, ltt_time_infinite,
-               G_MAXULONG, NULL);
-       lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero);
-
-       syncState->processingModule->finalizeProcessing(syncState);
-
-       // Write graphs file
-       if (graphsStream != NULL)
-       {
-               unsigned int i, j;
-
-               fprintf(graphsStream,
-                       "#!/usr/bin/gnuplot\n\n"
-                       "set terminal postscript eps color size 8in,6in\n");
-
-               // Cover the upper triangular matrix, i is the reference node.
-               for (i= 0; i < syncState->traceNb; i++)
-               {
-                       for (j= i + 1; j < syncState->traceNb; j++)
-                       {
-                               long pos;
-
-                               fprintf(graphsStream,
-                                       "\nset output \"%03d-%03d.eps\"\n"
-                                       "plot \\\n", i, j);
-
-                               syncState->processingModule->writeProcessingGraphsPlots(graphsStream,
-                                       syncState, i, j);
-
-                               // Remove the ", \\\n" from the last graph plot line
-                               fflush(graphsStream);
-                               pos= ftell(graphsStream);
-                               if (ftruncate(fileno(graphsStream), pos - 4) == -1)
-                               {
-                                       g_error(strerror(errno));
-                               }
-                               if (fseek(graphsStream, 0, SEEK_END) == -1)
-                               {
-                                       g_error(strerror(errno));
-                               }
-
-                               fprintf(graphsStream,
-                                       "\nset output \"%1$03d-%2$03d.eps\"\n"
-                                       "set key inside right bottom\n"
-                                       "set title \"\"\n"
-                                       "set xlabel \"Clock %1$u\"\n"
-                                       "set xtics nomirror\n"
-                                       "set ylabel \"Clock %2$u\"\n"
-                                       "set ytics nomirror\n", i, j);
-
-                               syncState->processingModule->writeProcessingGraphsOptions(graphsStream,
-                                       syncState, i, j);
-
-                               fprintf(graphsStream,
-                                       "replot\n");
-                       }
-               }
-
-               if (fclose(graphsStream) != 0)
-               {
-                       g_error(strerror(errno));
-               }
-       }
-
-       if (syncState->processingModule->printProcessingStats != NULL)
-       {
-               syncState->processingModule->printProcessingStats(syncState);
-       }
-
-       syncState->processingModule->destroyProcessing(syncState);
-       if (syncState->matchingModule != NULL)
-       {
-               syncState->matchingModule->destroyMatching(syncState);
-       }
-       if (syncState->analysisModule != NULL)
-       {
-               syncState->analysisModule->destroyAnalysis(syncState);
-       }
-
-       free(syncState);
-
-       if (optionSyncStats)
-       {
-               gettimeofday(&endTime, 0);
-               retval= getrusage(RUSAGE_SELF, &endUsage);
-
-               timeDiff(&endTime, &startTime);
-               timeDiff(&endUsage.ru_utime, &startUsage.ru_utime);
-               timeDiff(&endUsage.ru_stime, &startUsage.ru_stime);
-
-               printf("Synchronization time:\n");
-               printf("\treal time: %ld.%06ld\n", endTime.tv_sec, endTime.tv_usec);
-               printf("\tuser time: %ld.%06ld\n", endUsage.ru_utime.tv_sec,
-                       endUsage.ru_utime.tv_usec);
-               printf("\tsystem time: %ld.%06ld\n", endUsage.ru_stime.tv_sec,
-                       endUsage.ru_stime.tv_usec);
-       }
-}
-
-
-/*
- * Calculate the elapsed time between two timeval values
- *
- * Args:
- *   end:          end time, result is also stored in this structure
- *   start:        start time
- */
-static void timeDiff(struct timeval* const end, const struct timeval* const start)
-{
-               if (end->tv_usec >= start->tv_usec)
-               {
-                       end->tv_sec-= start->tv_sec;
-                       end->tv_usec-= start->tv_usec;
-               }
-               else
-               {
-                       end->tv_sec= end->tv_sec - start->tv_sec - 1;
-                       end->tv_usec= end->tv_usec - start->tv_usec + 1e6;
-               }
-}
-
-
-/*
- * A GCompareFunc for g_slist_find_custom()
- *
- * Args:
- *   a:            AnalysisModule*, element's data
- *   b:            char*, user data to compare against
- *
- * Returns:
- *   0 if the analysis module a's name is b
- */
-static gint gcfCompareAnalysis(gconstpointer a, gconstpointer b)
-{
-       const AnalysisModule* analysisModule;
-       const char* name;
-
-       analysisModule= (const AnalysisModule*)a;
-       name= (const char*)b;
-
-       return strncmp(analysisModule->name, name, strlen(analysisModule->name) +
-               1);
-}
-
-
-/*
- * A GCompareFunc for g_slist_find_custom()
- *
- * Args:
- *   a:            ProcessingModule*, element's data
- *   b:            char*, user data to compare against
- *
- * Returns:
- *   0 if the analysis module a's name is b
- */
-static gint gcfCompareProcessing(gconstpointer a, gconstpointer b)
-{
-       const ProcessingModule* processingModule;
-       const char* name;
-
-       processingModule= (const ProcessingModule*)a;
-       name= (const char*)b;
-
-       return strncmp(processingModule->name, name,
-               strlen(processingModule->name) + 1);
-}
-
-
-/*
- * A GFunc for g_queue_foreach()
- *
- * Concatenate analysis module names.
- *
- * Args:
- *   data:         AnalysisModule*
- *   user_data:    GString*, concatenated names
- */
-static void gfAppendAnalysisName(gpointer data, gpointer user_data)
-{
-       g_string_append((GString*) user_data, ((AnalysisModule*) data)->name);
-       g_string_append((GString*) user_data, ", ");
-}
-
-
-/*
- * Change to the directory used to hold graphs. Create it if necessary.
- *
- * Args:
- *   graph:        name of directory
- *
- * Returns:
- *   The current working directory before the execution of the function. The
- *   string must be free'd by the caller.
- */
-char* changeToGraphDir(char* const graphs)
-{
-       int retval;
-       char* cwd;
-
-       cwd= getcwd(NULL, 0);
-       if (cwd == NULL)
-       {
-               g_error(strerror(errno));
-       }
-       while ((retval= chdir(graphs)) != 0)
-       {
-               if (errno == ENOENT)
-               {
-                       retval= mkdir(graphs, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
-                               S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
-                       if (retval != 0)
-                       {
-                               g_error(strerror(errno));
-                       }
-               }
-               else
-               {
-                       g_error(strerror(errno));
-               }
-       }
-
-       return cwd;
-}
-
-
-LTTV_MODULE("sync", "Synchronize traces", \
-       "Synchronizes a traceset based on the correspondance of network events", \
-       init, destroy, "option")
diff --git a/lttv/lttv/sync/sync_chain.h b/lttv/lttv/sync/sync_chain.h
deleted file mode 100644 (file)
index 152d132..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifndef SYNC_CHAIN_H
-#define SYNC_CHAIN_H
-
-#include <glib.h>
-
-#include "event_processing.h"
-#include "event_matching.h"
-#include "event_analysis.h"
-
-typedef struct _SyncState
-{
-       unsigned int traceNb;
-       bool stats;
-       char* graphs;
-
-       const ProcessingModule* processingModule;
-       void* processingData;
-       const MatchingModule* matchingModule;
-       void* matchingData;
-       const AnalysisModule* analysisModule;
-       void* analysisData;
-} SyncState;
-
-extern GQueue processingModules;
-extern GQueue matchingModules;
-extern GQueue analysisModules;
-
-
-void syncTraceset(LttvTracesetContext* const traceSetContext);
-
-char* changeToGraphDir(char* const graphs);
-
-#endif
diff --git a/lttv/lttv/sync/sync_chain_lttv.c b/lttv/lttv/sync/sync_chain_lttv.c
new file mode 100644 (file)
index 0000000..16190c4
--- /dev/null
@@ -0,0 +1,500 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <lttv/module.h>
+#include <lttv/option.h>
+
+#include "sync_chain_lttv.h"
+
+
+#ifndef g_info
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#endif
+
+
+static void init();
+static void destroy();
+
+static void timeDiff(struct timeval* const end, const struct timeval* const start);
+
+static gint gcfCompareAnalysis(gconstpointer a, gconstpointer b);
+static gint gcfCompareProcessing(gconstpointer a, gconstpointer b);
+static void gfAppendAnalysisName(gpointer data, gpointer user_data);
+
+static gboolean optionSync;
+static gboolean optionSyncStats;
+static gboolean optionSyncNull;
+static char* optionSyncAnalysis;
+static gboolean optionSyncGraphs;
+static char* optionSyncGraphsDir;
+static char graphsDir[20];
+
+GQueue processingModules= G_QUEUE_INIT;
+GQueue matchingModules= G_QUEUE_INIT;
+GQueue analysisModules= G_QUEUE_INIT;
+
+
+/*
+ * Module init function
+ *
+ * This function is declared to be the module initialization function. Event
+ * modules are registered with a "constructor (102)" attribute except one in
+ * each class (processing, matching, analysis) which is chosen to be the
+ * default and which is registered with a "constructor (101)" attribute.
+ * Constructors with no priority are called after constructors with
+ * priorities. The result is that the list of event modules is known when this
+ * function is executed.
+ */
+static void init()
+{
+       GString* analysisModulesNames;
+       int retval;
+
+       g_debug("\t\t\tXXXX sync init\n");
+
+       optionSync= FALSE;
+       lttv_option_add("sync", '\0', "synchronize the time between the traces" ,
+               "none", LTTV_OPT_NONE, &optionSync, NULL, NULL);
+
+       optionSyncStats= FALSE;
+       lttv_option_add("sync-stats", '\0', "print statistics about the time "
+               "synchronization", "none", LTTV_OPT_NONE, &optionSyncStats, NULL,
+               NULL);
+
+       optionSyncNull= FALSE;
+       lttv_option_add("sync-null", '\0', "read the events but do not perform "
+               "any processing", "none", LTTV_OPT_NONE, &optionSyncNull, NULL, NULL);
+
+       g_assert(g_queue_get_length(&analysisModules) > 0);
+       optionSyncAnalysis= ((AnalysisModule*)
+               g_queue_peek_head(&analysisModules))->name;
+       analysisModulesNames= g_string_new("");
+       g_queue_foreach(&analysisModules, &gfAppendAnalysisName,
+               analysisModulesNames);
+       // remove the last ", "
+       g_string_truncate(analysisModulesNames, analysisModulesNames->len - 2);
+       lttv_option_add("sync-analysis", '\0', "specify the algorithm to use for "
+               "event analysis" , analysisModulesNames->str, LTTV_OPT_STRING,
+               &optionSyncAnalysis, NULL, NULL);
+       g_string_free(analysisModulesNames, TRUE);
+
+       optionSyncGraphs= FALSE;
+       lttv_option_add("sync-graphs", '\0', "output gnuplot graph showing "
+               "synchronization points", "none", LTTV_OPT_NONE, &optionSyncGraphs,
+               NULL, NULL);
+
+       retval= snprintf(graphsDir, sizeof(graphsDir), "graphs-%d", getpid());
+       if (retval > sizeof(graphsDir) - 1)
+       {
+               graphsDir[sizeof(graphsDir) - 1]= '\0';
+       }
+       optionSyncGraphsDir= graphsDir;
+       lttv_option_add("sync-graphs-dir", '\0', "specify the directory where to"
+               " store the graphs", graphsDir, LTTV_OPT_STRING, &optionSyncGraphsDir,
+               NULL, NULL);
+}
+
+
+/*
+ * Module unload function
+ */
+static void destroy()
+{
+       g_debug("\t\t\tXXXX sync destroy\n");
+
+       lttv_option_remove("sync");
+       lttv_option_remove("sync-stats");
+       lttv_option_remove("sync-null");
+       lttv_option_remove("sync-analysis");
+       lttv_option_remove("sync-graphs");
+       lttv_option_remove("sync-graphs-dir");
+}
+
+
+/*
+ * Calculate a traceset's drift and offset values based on network events
+ *
+ * The individual correction factors are written out to each trace.
+ *
+ * Args:
+ *   traceSetContext: traceset
+ */
+void syncTraceset(LttvTracesetContext* const traceSetContext)
+{
+       SyncState* syncState;
+       struct timeval startTime, endTime;
+       struct rusage startUsage, endUsage;
+       GList* result;
+       char* cwd;
+       FILE* graphsStream;
+       int graphsFp;
+       int retval;
+
+       if (optionSync == FALSE)
+       {
+               g_debug("Not synchronizing traceset because option is disabled");
+               return;
+       }
+
+       if (optionSyncStats)
+       {
+               gettimeofday(&startTime, 0);
+               getrusage(RUSAGE_SELF, &startUsage);
+       }
+
+       // Initialize data structures
+       syncState= malloc(sizeof(SyncState));
+       syncState->traceNb= lttv_traceset_number(traceSetContext->ts);
+
+       if (optionSyncStats)
+       {
+               syncState->stats= true;
+       }
+       else
+       {
+               syncState->stats= false;
+       }
+
+       if (optionSyncGraphs)
+       {
+               syncState->graphs= optionSyncGraphsDir;
+       }
+       else
+       {
+               syncState->graphs= NULL;
+       }
+
+       // Identify and initialize processing module
+       syncState->processingData= NULL;
+       if (optionSyncNull)
+       {
+               result= g_queue_find_custom(&processingModules, "LTTV-null",
+                       &gcfCompareProcessing);
+       }
+       else
+       {
+               result= g_queue_find_custom(&processingModules, "LTTV-standard",
+                       &gcfCompareProcessing);
+       }
+       g_assert(result != NULL);
+       syncState->processingModule= (ProcessingModule*) result->data;
+
+       graphsStream= NULL;
+       if (syncState->graphs)
+       {
+               // Create the graph directory right away in case the module initialization
+               // functions have something to write in it.
+               cwd= changeToGraphDir(syncState->graphs);
+
+               if (syncState->processingModule->writeProcessingGraphsPlots != NULL)
+               {
+                       if ((graphsFp= open("graphs.gnu", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
+                                       S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
+                                       | S_IWOTH | S_IXOTH)) == -1)
+                       {
+                               g_error(strerror(errno));
+                       }
+                       if ((graphsStream= fdopen(graphsFp, "w")) == NULL)
+                       {
+                               g_error(strerror(errno));
+                       }
+               }
+
+               retval= chdir(cwd);
+               if (retval == -1)
+               {
+                       g_error(strerror(errno));
+               }
+               free(cwd);
+       }
+
+       syncState->processingModule->initProcessing(syncState, traceSetContext);
+
+       // Identify and initialize matching and analysis modules
+       syncState->matchingData= NULL;
+       syncState->analysisData= NULL;
+       if (optionSyncNull)
+       {
+               syncState->matchingModule= NULL;
+               syncState->analysisModule= NULL;
+       }
+       else
+       {
+               g_assert(g_queue_get_length(&matchingModules) == 1);
+               syncState->matchingModule= (MatchingModule*)
+                       g_queue_peek_head(&matchingModules);
+               syncState->matchingModule->initMatching(syncState);
+
+               result= g_queue_find_custom(&analysisModules, optionSyncAnalysis,
+                       &gcfCompareAnalysis);
+               if (result != NULL)
+               {
+                       syncState->analysisModule= (AnalysisModule*) result->data;
+                       syncState->analysisModule->initAnalysis(syncState);
+               }
+               else
+               {
+                       g_error("Analysis module '%s' not found", optionSyncAnalysis);
+               }
+       }
+
+       // Process traceset
+       lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero);
+       lttv_process_traceset_middle(traceSetContext, ltt_time_infinite,
+               G_MAXULONG, NULL);
+       lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero);
+
+       syncState->processingModule->finalizeProcessing(syncState);
+
+       // Write graphs file
+       if (graphsStream != NULL)
+       {
+               unsigned int i, j;
+
+               fprintf(graphsStream,
+                       "#!/usr/bin/gnuplot\n\n"
+                       "set terminal postscript eps color size 8in,6in\n");
+
+               // Cover the upper triangular matrix, i is the reference node.
+               for (i= 0; i < syncState->traceNb; i++)
+               {
+                       for (j= i + 1; j < syncState->traceNb; j++)
+                       {
+                               long pos;
+
+                               fprintf(graphsStream,
+                                       "\nset output \"%03d-%03d.eps\"\n"
+                                       "plot \\\n", i, j);
+
+                               syncState->processingModule->writeProcessingGraphsPlots(graphsStream,
+                                       syncState, i, j);
+
+                               // Remove the ", \\\n" from the last graph plot line
+                               fflush(graphsStream);
+                               pos= ftell(graphsStream);
+                               if (ftruncate(fileno(graphsStream), pos - 4) == -1)
+                               {
+                                       g_error(strerror(errno));
+                               }
+                               if (fseek(graphsStream, 0, SEEK_END) == -1)
+                               {
+                                       g_error(strerror(errno));
+                               }
+
+                               fprintf(graphsStream,
+                                       "\nset output \"%1$03d-%2$03d.eps\"\n"
+                                       "set key inside right bottom\n"
+                                       "set title \"\"\n"
+                                       "set xlabel \"Clock %1$u\"\n"
+                                       "set xtics nomirror\n"
+                                       "set ylabel \"Clock %2$u\"\n"
+                                       "set ytics nomirror\n", i, j);
+
+                               syncState->processingModule->writeProcessingGraphsOptions(graphsStream,
+                                       syncState, i, j);
+
+                               fprintf(graphsStream,
+                                       "replot\n");
+                       }
+               }
+
+               if (fclose(graphsStream) != 0)
+               {
+                       g_error(strerror(errno));
+               }
+       }
+
+       if (syncState->processingModule->printProcessingStats != NULL)
+       {
+               syncState->processingModule->printProcessingStats(syncState);
+       }
+
+       syncState->processingModule->destroyProcessing(syncState);
+       if (syncState->matchingModule != NULL)
+       {
+               syncState->matchingModule->destroyMatching(syncState);
+       }
+       if (syncState->analysisModule != NULL)
+       {
+               syncState->analysisModule->destroyAnalysis(syncState);
+       }
+
+       free(syncState);
+
+       if (optionSyncStats)
+       {
+               gettimeofday(&endTime, 0);
+               retval= getrusage(RUSAGE_SELF, &endUsage);
+
+               timeDiff(&endTime, &startTime);
+               timeDiff(&endUsage.ru_utime, &startUsage.ru_utime);
+               timeDiff(&endUsage.ru_stime, &startUsage.ru_stime);
+
+               printf("Synchronization time:\n");
+               printf("\treal time: %ld.%06ld\n", endTime.tv_sec, endTime.tv_usec);
+               printf("\tuser time: %ld.%06ld\n", endUsage.ru_utime.tv_sec,
+                       endUsage.ru_utime.tv_usec);
+               printf("\tsystem time: %ld.%06ld\n", endUsage.ru_stime.tv_sec,
+                       endUsage.ru_stime.tv_usec);
+       }
+}
+
+
+/*
+ * Calculate the elapsed time between two timeval values
+ *
+ * Args:
+ *   end:          end time, result is also stored in this structure
+ *   start:        start time
+ */
+static void timeDiff(struct timeval* const end, const struct timeval* const start)
+{
+               if (end->tv_usec >= start->tv_usec)
+               {
+                       end->tv_sec-= start->tv_sec;
+                       end->tv_usec-= start->tv_usec;
+               }
+               else
+               {
+                       end->tv_sec= end->tv_sec - start->tv_sec - 1;
+                       end->tv_usec= end->tv_usec - start->tv_usec + 1e6;
+               }
+}
+
+
+/*
+ * A GCompareFunc for g_slist_find_custom()
+ *
+ * Args:
+ *   a:            AnalysisModule*, element's data
+ *   b:            char*, user data to compare against
+ *
+ * Returns:
+ *   0 if the analysis module a's name is b
+ */
+static gint gcfCompareAnalysis(gconstpointer a, gconstpointer b)
+{
+       const AnalysisModule* analysisModule;
+       const char* name;
+
+       analysisModule= (const AnalysisModule*)a;
+       name= (const char*)b;
+
+       return strncmp(analysisModule->name, name, strlen(analysisModule->name) +
+               1);
+}
+
+
+/*
+ * A GCompareFunc for g_slist_find_custom()
+ *
+ * Args:
+ *   a:            ProcessingModule*, element's data
+ *   b:            char*, user data to compare against
+ *
+ * Returns:
+ *   0 if the analysis module a's name is b
+ */
+static gint gcfCompareProcessing(gconstpointer a, gconstpointer b)
+{
+       const ProcessingModule* processingModule;
+       const char* name;
+
+       processingModule= (const ProcessingModule*)a;
+       name= (const char*)b;
+
+       return strncmp(processingModule->name, name,
+               strlen(processingModule->name) + 1);
+}
+
+
+/*
+ * A GFunc for g_queue_foreach()
+ *
+ * Concatenate analysis module names.
+ *
+ * Args:
+ *   data:         AnalysisModule*
+ *   user_data:    GString*, concatenated names
+ */
+static void gfAppendAnalysisName(gpointer data, gpointer user_data)
+{
+       g_string_append((GString*) user_data, ((AnalysisModule*) data)->name);
+       g_string_append((GString*) user_data, ", ");
+}
+
+
+/*
+ * Change to the directory used to hold graphs. Create it if necessary.
+ *
+ * Args:
+ *   graph:        name of directory
+ *
+ * Returns:
+ *   The current working directory before the execution of the function. The
+ *   string must be free'd by the caller.
+ */
+char* changeToGraphDir(char* const graphs)
+{
+       int retval;
+       char* cwd;
+
+       cwd= getcwd(NULL, 0);
+       if (cwd == NULL)
+       {
+               g_error(strerror(errno));
+       }
+       while ((retval= chdir(graphs)) != 0)
+       {
+               if (errno == ENOENT)
+               {
+                       retval= mkdir(graphs, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
+                               S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
+                       if (retval != 0)
+                       {
+                               g_error(strerror(errno));
+                       }
+               }
+               else
+               {
+                       g_error(strerror(errno));
+               }
+       }
+
+       return cwd;
+}
+
+
+LTTV_MODULE("sync", "Synchronize traces", \
+       "Synchronizes a traceset based on the correspondance of network events", \
+       init, destroy, "option")
diff --git a/lttv/lttv/sync/sync_chain_lttv.h b/lttv/lttv/sync/sync_chain_lttv.h
new file mode 100644 (file)
index 0000000..a6a460b
--- /dev/null
@@ -0,0 +1,51 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef SYNC_CHAIN_LTTV_H
+#define SYNC_CHAIN_LTTV_H
+
+#include <glib.h>
+
+#include "event_processing.h"
+#include "event_matching.h"
+#include "event_analysis.h"
+
+typedef struct _SyncState
+{
+       unsigned int traceNb;
+       bool stats;
+       char* graphs;
+
+       const ProcessingModule* processingModule;
+       void* processingData;
+       const MatchingModule* matchingModule;
+       void* matchingData;
+       const AnalysisModule* analysisModule;
+       void* analysisData;
+} SyncState;
+
+extern GQueue processingModules;
+extern GQueue matchingModules;
+extern GQueue analysisModules;
+
+
+void syncTraceset(LttvTracesetContext* const traceSetContext);
+
+char* changeToGraphDir(char* const graphs);
+
+#endif
index 4ca2b932a2c303ed14186df0919bf3d9076c752f..a452d08db7e76e771949286b9db86fdb1d555f28 100644 (file)
@@ -34,7 +34,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
 
 
 #ifndef g_info
@@ -616,7 +616,7 @@ static void processEvents(SyncState* const syncState, FILE* testCase)
                unsigned int sender, receiver;
                double sendTime, recvTime;
                char tmp;
-               NetEvent* event;
+               Event* event;
 
                if (retval == -1 && !feof(testCase))
                {
@@ -650,48 +650,54 @@ static void processEvents(SyncState* const syncState, FILE* testCase)
                }
 
                // Output event
-               event= malloc(sizeof(NetEvent));
+               event= malloc(sizeof(Event));
                event->traceNum= sender;
-               event->tsc= round(sendTime * freq);
-               event->skb= NULL;
-               event->packetKey= malloc(sizeof(PacketKey));
-               event->packetKey->ihl= 5;
-               event->packetKey->tot_len= 40;
-               event->packetKey->connectionKey.saddr= sender + addressOffset;
-               event->packetKey->connectionKey.daddr= receiver + addressOffset;
-               event->packetKey->connectionKey.source= 57645;
-               event->packetKey->connectionKey.dest= 80;
-               event->packetKey->seq= seq[sender];
-               event->packetKey->ack_seq= 0;
-               event->packetKey->doff= 5;
-               event->packetKey->ack= 0;
-               event->packetKey->rst= 0;
-               event->packetKey->syn= 1;
-               event->packetKey->fin= 0;
-
-               syncState->matchingModule->matchEvent(syncState, event, OUT);
+               event->time= round(sendTime * freq);
+               event->type= TCP;
+               event->destroy= &destroyTCPEvent;
+               event->event.tcpEvent= malloc(sizeof(TCPEvent));
+               event->event.tcpEvent->direction= OUT;
+               event->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
+               event->event.tcpEvent->segmentKey->ihl= 5;
+               event->event.tcpEvent->segmentKey->tot_len= 40;
+               event->event.tcpEvent->segmentKey->connectionKey.saddr= sender + addressOffset;
+               event->event.tcpEvent->segmentKey->connectionKey.daddr= receiver + addressOffset;
+               event->event.tcpEvent->segmentKey->connectionKey.source= 57645;
+               event->event.tcpEvent->segmentKey->connectionKey.dest= 80;
+               event->event.tcpEvent->segmentKey->seq= seq[sender];
+               event->event.tcpEvent->segmentKey->ack_seq= 0;
+               event->event.tcpEvent->segmentKey->doff= 5;
+               event->event.tcpEvent->segmentKey->ack= 0;
+               event->event.tcpEvent->segmentKey->rst= 0;
+               event->event.tcpEvent->segmentKey->syn= 1;
+               event->event.tcpEvent->segmentKey->fin= 0;
+
+               syncState->matchingModule->matchEvent(syncState, event);
 
                // Input event
-               event= malloc(sizeof(NetEvent));
+               event= malloc(sizeof(Event));
                event->traceNum= receiver;
-               event->tsc= round(recvTime * freq);
-               event->skb= NULL;
-               event->packetKey= malloc(sizeof(PacketKey));
-               event->packetKey->ihl= 5;
-               event->packetKey->tot_len= 40;
-               event->packetKey->connectionKey.saddr= sender + addressOffset;
-               event->packetKey->connectionKey.daddr= receiver + addressOffset;
-               event->packetKey->connectionKey.source= 57645;
-               event->packetKey->connectionKey.dest= 80;
-               event->packetKey->seq= seq[sender];
-               event->packetKey->ack_seq= 0;
-               event->packetKey->doff= 5;
-               event->packetKey->ack= 0;
-               event->packetKey->rst= 0;
-               event->packetKey->syn= 1;
-               event->packetKey->fin= 0;
-
-               syncState->matchingModule->matchEvent(syncState, event, IN);
+               event->time= round(recvTime * freq);
+               event->type= TCP;
+               event->destroy= &destroyTCPEvent;
+               event->event.tcpEvent= malloc(sizeof(TCPEvent));
+               event->event.tcpEvent->direction= IN;
+               event->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
+               event->event.tcpEvent->segmentKey->ihl= 5;
+               event->event.tcpEvent->segmentKey->tot_len= 40;
+               event->event.tcpEvent->segmentKey->connectionKey.saddr= sender + addressOffset;
+               event->event.tcpEvent->segmentKey->connectionKey.daddr= receiver + addressOffset;
+               event->event.tcpEvent->segmentKey->connectionKey.source= 57645;
+               event->event.tcpEvent->segmentKey->connectionKey.dest= 80;
+               event->event.tcpEvent->segmentKey->seq= seq[sender];
+               event->event.tcpEvent->segmentKey->ack_seq= 0;
+               event->event.tcpEvent->segmentKey->doff= 5;
+               event->event.tcpEvent->segmentKey->ack= 0;
+               event->event.tcpEvent->segmentKey->rst= 0;
+               event->event.tcpEvent->segmentKey->syn= 1;
+               event->event.tcpEvent->segmentKey->fin= 0;
+
+               syncState->matchingModule->matchEvent(syncState, event);
 
                seq[sender]++;
 
index 53681f48bb4dbb775b1509bd8307a15c982c2632..6514ef0a5ccd9e9203840e509f815da870f3f391 100644 (file)
@@ -39,7 +39,7 @@
 #include <lttv/iattribute.h>
 #include <lttv/stats.h>
 #include <lttv/filter.h>
-#include <lttv/sync/sync_chain.h>
+#include <lttv/sync/sync_chain_lttv.h>
 #include <lttvwindow/mainwindow.h>
 #include <lttvwindow/mainwindow-private.h>
 #include <lttvwindow/menu.h>
index 3ee4d021fc6539c4f804b086fd2bac7596a8f99e..4b02f33250f886c17082ed4e18537355e7627b5f 100644 (file)
@@ -34,7 +34,7 @@
 #include <lttv/stats.h>
 #include <lttv/filter.h>
 #include <ltt/trace.h>
-#include <lttv/sync/sync_chain.h>
+#include <lttv/sync/sync_chain_lttv.h>
 
 static LttvTraceset *traceset;
 
This page took 0.08288 seconds and 4 git commands to generate.