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
unittest_SOURCES = \
unittest.c\
- data_structures_tcp.c\
+ data_structures.c\
event_matching_tcp.c\
event_analysis_linreg.c\
event_analysis_chull.c
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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
#include <glib.h>
#include <stdio.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
struct _SyncState;
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
#include <stdio.h>
#include <unistd.h>
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
#include "event_analysis_chull.h"
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
.name= "chull",
.initAnalysis= &initAnalysisCHull,
.destroyAnalysis= &destroyAnalysisCHull,
- .analyzePacket= &analyzePacketCHull,
+ .analyzeMessage= &analyzeMessageCHull,
.analyzeExchange= NULL,
+ .analyzeBroadcast= NULL,
.finalizeAnalysis= &finalizeAnalysisCHull,
.printAnalysisStats= &printAnalysisStatsCHull,
.writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsCHull,
*
* 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;
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)
#include <glib.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
typedef struct
#include <stdio.h>
#include <stdlib.h>
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
#include "event_analysis_linreg.h"
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
.name= "linreg",
.initAnalysis= &initAnalysisLinReg,
.destroyAnalysis= &destroyAnalysisLinReg,
- .analyzePacket= NULL,
+ .analyzeMessage= NULL,
.analyzeExchange= &analyzeExchangeLinReg,
+ .analyzeBroadcast= NULL,
.finalizeAnalysis= &finalizeAnalysisLinReg,
.printAnalysisStats= &printAnalysisStatsLinReg,
.writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsLinReg,
/*
* 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++;
#include <glib.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
typedef struct
#include <glib.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
struct _SyncState;
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
#include <unistd.h>
#include "event_analysis.h"
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
#include "event_matching_tcp.h"
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
// 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 = {
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)
{
* 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));
}
}
* 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)
{
// Discard loopback traffic
if (packet->inE->traceNum == packet->outE->traceNum)
{
- destroyPacket(packet);
+ destroyTCPSegment(packet);
return;
}
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;
}
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)
{
// 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)
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");
}
}
syncState->analysisModule->analyzeExchange(syncState,
- packet);
+ exchange);
}
+
+ exchange->message= NULL;
+ destroyTCPExchange(exchange);
}
}
}
// 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());
}
else
{
- destroyPacket(packet);
+ destroyTCPSegment(packet);
}
}
else
// 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);
}
}
/*
* 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;
}
* 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;
}
* 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);
#include <glib.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
typedef struct
#include <lttv/tracecontext.h>
-#include "data_structures_tcp.h"
+#include "data_structures.h"
struct _SyncState;
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+/* 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
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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);
- }
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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")
+++ /dev/null
-/* 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
--- /dev/null
+/* 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")
--- /dev/null
+/* 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
#include <sys/stat.h>
#include <unistd.h>
-#include "sync_chain.h"
+#include "sync_chain_lttv.h"
#ifndef g_info
unsigned int sender, receiver;
double sendTime, recvTime;
char tmp;
- NetEvent* event;
+ Event* event;
if (retval == -1 && !feof(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]++;
#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>
#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;