Perform factor reduction as a modular step
[lttv.git] / lttv / lttv / sync / data_structures.c
index 70eb22c74a84f6d56f957f2d81da5f4d4422072e..79b8963d61427d83b48a2feebb2051c471a2322b 100644 (file)
@@ -1,19 +1,18 @@
 /* This file is part of the Linux Trace Toolkit viewer
- * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
+ * Copyright (C) 2009, 2010 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 free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or (at
+ * your option) any later version.
  *
- * 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.
+ * 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 Lesser 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_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_GT(a,b)     ((int32_t)((a)-(b)) > 0)
 #define SEQ_GEQ(a,b)    ((int32_t)((a)-(b)) >= 0)
 
+const char* const approxNames[]= {
+       [EXACT]= "Exact",
+       [ACCURATE]= "Accurate",
+       [APPROXIMATE]= "Approximate",
+       [INCOMPLETE]= "Incomplete",
+       [ABSENT]= "Absent",
+       [SCREWED]= "Screwed",
+};
+
 
 /*
  * Compare two ConnectionKey structures
@@ -99,15 +103,12 @@ bool isAcking(const Message* const ackSegment, const Message* const
  * Convert an IP address from 32 bit form to dotted quad
  *
  * Args:
- *   str:          A preallocated string of length >= 17
+ *   str:          A preallocated string of length >= 16
  *   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));
+       strcpy(str, inet_ntoa((struct in_addr) {.s_addr= addr}));
 }
 
 
@@ -116,7 +117,7 @@ void convertIP(char* const str, const uint32_t addr)
  */
 void printTCPSegment(const Message* const segment)
 {
-       char saddr[17], daddr[17];
+       char saddr[16], daddr[16];
        SegmentKey* segmentKey;
 
        g_assert(segment->inE->type == TCP);
@@ -241,8 +242,6 @@ void gdnTCPSegmentListDestroy(gpointer data)
 
        list= (GQueue*) data;
 
-       g_debug("XXXX gdnTCPSegmentListDestroy\n");
-
        g_queue_foreach(list, &gfTCPSegmentDestroy, NULL);
        g_queue_free(list);
 }
@@ -257,7 +256,6 @@ void gdnTCPSegmentListDestroy(gpointer data)
  */
 void gfTCPSegmentDestroy(gpointer data, gpointer user_data)
 {
-       g_debug("XXXX gfTCPSegmentDestroy\n");
        destroyTCPSegment((Message*) data);
 }
 
@@ -273,7 +271,6 @@ void destroyTCPSegment(Message* const segment)
 {
        TCPEvent* inE, *outE;
 
-       g_debug("XXXX destroyTCPSegment");
        segment->print(segment);
 
        g_assert(segment->inE != NULL && segment->outE != NULL);
@@ -329,6 +326,7 @@ void destroyTCPEvent(Event* const event)
        destroyEvent(event);
 }
 
+
 /*
  * Free the memory used by a base Event
  */
@@ -464,9 +462,14 @@ void gdnConnectionKeyDestroy(gpointer data)
 guint ghfDatagramKeyHash(gconstpointer key)
 {
        DatagramKey* datagramKey;
+       union {
+               uint8_t byteKey[8];
+               uint32_t hashableKey[2];
+       } dataKey;
        uint32_t a, b, c;
 
        datagramKey= (DatagramKey*) key;
+       memcpy(dataKey.byteKey, datagramKey->dataKey, sizeof(dataKey.byteKey));
 
        a= datagramKey->saddr;
        b= datagramKey->daddr;
@@ -474,8 +477,8 @@ guint ghfDatagramKeyHash(gconstpointer key)
        mix(a, b, c);
 
        a+= datagramKey->ulen; // 16 bits left here
-       b+= *((uint32_t*) datagramKey->dataKey);
-       c+= *((uint32_t*) ((void*) datagramKey->dataKey + 4));
+       b+= dataKey.hashableKey[0];
+       c+= dataKey.hashableKey[1];
        final(a, b, c);
 
        return c;
@@ -545,7 +548,7 @@ void gdnDestroyBroadcast(gpointer data)
 void destroyBroadcast(Broadcast* const broadcast)
 {
        g_queue_foreach(broadcast->events, &gfDestroyEvent, NULL);
-       g_queue_clear(broadcast->events);
+       g_queue_free(broadcast->events);
        free(broadcast);
 }
 
@@ -563,3 +566,190 @@ void gfDestroyEvent(gpointer data, gpointer user_data)
 
        event->destroy(event);
 }
+
+
+/* Subtract two WallTime structs
+ *
+ * Args:
+ *   tA, tB:       WallTime
+ *
+ * Returns:
+ *   The result of tA - tB, as a double. This may incur a loss of
+ *   precision.
+ */
+double wallTimeSub(const WallTime const* tA, const WallTime const* tB)
+{
+       return (double) tA->seconds - tB->seconds + ((double) tA->nanosec - tB->nanosec) / 1e9;
+}
+
+
+/*
+ * Allocate and copy a base event
+ *
+ * Args:
+ *   newEvent:     new event, pointer will be updated
+ *   event:        event to copy
+ */
+void copyEvent(const Event* const event, Event** const newEvent)
+{
+       g_assert(event->event.tcpEvent == NULL);
+
+       *newEvent= malloc(sizeof(Event));
+       memcpy(*newEvent, event, sizeof(Event));
+}
+
+
+/*
+ * Allocate and copy a TCP event
+ *
+ * Args:
+ *   newEvent:     new event, pointer will be updated
+ *   event:        event to copy
+ */
+void copyTCPEvent(const Event* const event, Event** const newEvent)
+{
+       g_assert(event->type == TCP);
+
+       *newEvent= malloc(sizeof(Event));
+       memcpy(*newEvent, event, sizeof(Event));
+
+       (*newEvent)->event.tcpEvent= malloc(sizeof(TCPEvent));
+       memcpy((*newEvent)->event.tcpEvent, event->event.tcpEvent,
+               sizeof(TCPEvent));
+
+       (*newEvent)->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
+       memcpy((*newEvent)->event.tcpEvent->segmentKey,
+               event->event.tcpEvent->segmentKey, sizeof(SegmentKey));
+}
+
+
+/*
+ * Allocate and copy a UDP event
+ *
+ * Args:
+ *   newEvent:     new event, pointer will be updated
+ *   event:        event to copy
+ */
+void copyUDPEvent(const Event* const event, Event** const newEvent)
+{
+       g_assert(event->type == UDP);
+
+       *newEvent= malloc(sizeof(Event));
+       memcpy(*newEvent, event, sizeof(Event));
+
+       (*newEvent)->event.udpEvent= malloc(sizeof(UDPEvent));
+       memcpy((*newEvent)->event.udpEvent, event->event.udpEvent,
+               sizeof(UDPEvent));
+
+       (*newEvent)->event.udpEvent->datagramKey= malloc(sizeof(DatagramKey));
+       memcpy((*newEvent)->event.udpEvent->datagramKey,
+               event->event.udpEvent->datagramKey, sizeof(DatagramKey));
+}
+
+
+/*
+ * A GFunc for g_queue_foreach()
+ *
+ * Args:
+ *   data          Event*, event to add
+ *   user_data     GArray*, array to add to
+ */
+void gfAddEventToArray(gpointer data, gpointer user_data)
+{
+       g_array_append_val((GArray*) user_data, data);
+}
+
+
+/*
+ * Free a PairFactors
+ *
+ * Args:
+ *   factorsCHull: container of Factors
+ */
+void destroyPairFactors(PairFactors* pairFactors)
+{
+       if (pairFactors->min != NULL)
+       {
+               free(pairFactors->min);
+       }
+       if (pairFactors->max != NULL)
+       {
+               free(pairFactors->max);
+       }
+       if (pairFactors->approx != NULL)
+       {
+               free(pairFactors->approx);
+       }
+}
+
+
+/*
+ * Create and initialize a container of PairFactors
+ *
+ * Args:
+ *   traceNb:      number of traces
+ *
+ * Returns:
+ *   A new array, which can be freed with freeAllFactors()
+ */
+AllFactors* createAllFactors(const unsigned int traceNb)
+{
+       AllFactors* allFactors;
+       PairFactors** factorsArray;
+       unsigned int i, j;
+
+       allFactors= malloc(sizeof(AllFactors));
+       allFactors->refCount= 1;
+       allFactors->pairFactors= malloc(traceNb * sizeof(PairFactors*));
+       factorsArray=allFactors->pairFactors;
+       for (i= 0; i < traceNb; i++)
+       {
+               factorsArray[i]= calloc(traceNb, sizeof(PairFactors));
+
+               for (j= 0; j < traceNb; j++)
+               {
+                       if (i == j)
+                       {
+                               factorsArray[i][i].type= EXACT;
+                               factorsArray[i][i].approx= malloc(sizeof(Factors));
+                               factorsArray[i][i].approx->drift= 1.;
+                               factorsArray[i][i].approx->offset= 0.;
+                       }
+                       else
+                       {
+                               factorsArray[i][j].type= ABSENT;
+                       }
+               }
+       }
+
+       return allFactors;
+}
+
+
+/*
+ * Free a container of PairFactors
+ *
+ * Args:
+ *   allFactors:   container of PairFactors
+ *   traceNb:      number of traces
+ */
+void freeAllFactors(AllFactors* const allFactors, const unsigned int traceNb)
+{
+       unsigned int i, j;
+
+       allFactors->refCount--;
+
+       if (allFactors->refCount == 0)
+       {
+               for (i= 0; i < traceNb; i++)
+               {
+                       for (j= 0; j < traceNb; j++)
+                       {
+                               destroyPairFactors(&allFactors->pairFactors[i][j]);
+                       }
+                       free(allFactors->pairFactors[i]);
+               }
+               free(allFactors->pairFactors);
+               free(allFactors);
+       }
+}
This page took 0.025636 seconds and 4 git commands to generate.