1.1 --- a/src/contrib/net-anim/animation-interface.cc Thu Nov 05 19:14:37 2009 -0800
1.2 +++ b/src/contrib/net-anim/animation-interface.cc Thu Nov 05 19:15:28 2009 -0800
1.3 @@ -21,9 +21,15 @@
1.4 #include <stdio.h>
1.5 #include <sstream>
1.6
1.7 +#include "ns3/net-anim-config.h"
1.8 +
1.9 // Socket related includes
1.10 -#include <sys/socket.h>
1.11 -#include <netinet/in.h>
1.12 +#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
1.13 +# include <sys/socket.h>
1.14 +# include <netinet/in.h>
1.15 +#else
1.16 +#include <fcntl.h>
1.17 +#endif
1.18
1.19 // ns3 includes
1.20 #include "ns3/animation-interface.h"
1.21 @@ -58,6 +64,7 @@
1.22
1.23 bool AnimationInterface::SetServerPort (uint16_t port)
1.24 {
1.25 +#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
1.26 int s = socket (AF_INET, SOCK_STREAM, 0);
1.27 struct sockaddr_in addr;
1.28 addr.sin_family = AF_INET;
1.29 @@ -77,6 +84,8 @@
1.30 int t = 1;
1.31 setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
1.32 return true;
1.33 +#endif
1.34 + return false;//never reached unless the above is disabled
1.35 }
1.36
1.37 bool AnimationInterface::SetInternalAnimation ()
2.1 --- a/src/contrib/net-anim/point-to-point-dumbbell-helper.cc Thu Nov 05 19:14:37 2009 -0800
2.2 +++ b/src/contrib/net-anim/point-to-point-dumbbell-helper.cc Thu Nov 05 19:15:28 2009 -0800
2.3 @@ -21,10 +21,6 @@
2.4 #include <iostream>
2.5 #include <sstream>
2.6
2.7 -// Socket related includes
2.8 -#include <sys/socket.h>
2.9 -#include <netinet/in.h>
2.10 -
2.11 // ns3 includes
2.12 #include "ns3/animation-interface.h"
2.13 #include "ns3/point-to-point-dumbbell-helper.h"
3.1 --- a/src/contrib/net-anim/wscript Thu Nov 05 19:14:37 2009 -0800
3.2 +++ b/src/contrib/net-anim/wscript Thu Nov 05 19:15:28 2009 -0800
3.3 @@ -1,5 +1,11 @@
3.4 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
3.5
3.6 +def configure(conf):
3.7 + conf.check(header_name='sys/socket.h', define_name='HAVE_SYS_SOCKET_H')
3.8 + conf.check(header_name='netinet/in.h', define_name='HAVE_NETINET_IN_H')
3.9 + conf.write_config_header('ns3/net-anim-config.h', top=True)
3.10 +
3.11 +
3.12 def build(bld):
3.13 obj = bld.create_ns3_module('net-anim')
3.14 obj.source = [
4.1 --- a/src/contrib/wscript Thu Nov 05 19:14:37 2009 -0800
4.2 +++ b/src/contrib/wscript Thu Nov 05 19:15:28 2009 -0800
4.3 @@ -14,9 +14,11 @@
4.4 conf.report_optional_feature("XmlIo", "XmlIo",
4.5 conf.env['ENABLE_LIBXML2'],
4.6 "library 'libxml-2.0 >= 2.7' not found")
4.7 + conf.write_config_header('ns3/contrib-config.h', top=True)
4.8 +
4.9 conf.sub_config('stats')
4.10 + conf.sub_config('net-anim')
4.11
4.12 - conf.write_config_header('ns3/contrib-config.h', top=True)
4.13
4.14 def build(bld):
4.15 module = bld.create_ns3_module('contrib', ['simulator', 'common'])
5.1 --- a/src/core/object.cc Thu Nov 05 19:14:37 2009 -0800
5.2 +++ b/src/core/object.cc Thu Nov 05 19:15:28 2009 -0800
5.3 @@ -28,6 +28,8 @@
5.4 #include "string.h"
5.5 #include <vector>
5.6 #include <sstream>
5.7 +#include <stdlib.h>
5.8 +#include <string.h>
5.9
5.10 NS_LOG_COMPONENT_DEFINE ("Object");
5.11
5.12 @@ -40,28 +42,23 @@
5.13 NS_OBJECT_ENSURE_REGISTERED (Object);
5.14
5.15 Object::AggregateIterator::AggregateIterator ()
5.16 - : m_first (0),
5.17 + : m_object (0),
5.18 m_current (0)
5.19 {}
5.20
5.21 bool
5.22 Object::AggregateIterator::HasNext (void) const
5.23 {
5.24 - if (m_current != 0 && m_current->m_next != PeekPointer (m_first))
5.25 - {
5.26 - return true;
5.27 - }
5.28 - return false;
5.29 + return m_current < m_object->m_aggregates->n;
5.30 }
5.31 Ptr<const Object>
5.32 Object::AggregateIterator::Next (void)
5.33 {
5.34 - m_current = m_current->m_next;
5.35 - return m_current;
5.36 + return m_object->m_aggregates->buffer[m_current];
5.37 }
5.38 -Object::AggregateIterator::AggregateIterator (Ptr<const Object> first)
5.39 - : m_first (first),
5.40 - m_current (first)
5.41 +Object::AggregateIterator::AggregateIterator (Ptr<const Object> object)
5.42 + : m_object (object),
5.43 + m_current (0)
5.44 {}
5.45
5.46
5.47 @@ -85,18 +82,45 @@
5.48 : m_count (1),
5.49 m_tid (Object::GetTypeId ()),
5.50 m_disposed (false),
5.51 - m_next (this)
5.52 -{}
5.53 + m_aggregates ((struct Aggregates *)malloc (sizeof (struct Aggregates))),
5.54 + m_getObjectCount (0)
5.55 +{
5.56 + m_aggregates->n = 1;
5.57 + m_aggregates->buffer[0] = this;
5.58 +}
5.59 Object::~Object ()
5.60 {
5.61 - m_next = 0;
5.62 + // remove this object from the aggregate list
5.63 + uint32_t n = m_aggregates->n;
5.64 + for (uint32_t i = 0; i < n; i++)
5.65 + {
5.66 + Object *current = m_aggregates->buffer[i];
5.67 + if (current == this)
5.68 + {
5.69 + memmove (&m_aggregates->buffer[i],
5.70 + &m_aggregates->buffer[i+1],
5.71 + sizeof (Object *)*(m_aggregates->n - (i+1)));
5.72 + m_aggregates->n--;
5.73 + }
5.74 + }
5.75 + // finally, if all objects have been removed from the list,
5.76 + // delete the aggregate list
5.77 + if (m_aggregates->n == 0)
5.78 + {
5.79 + free (m_aggregates);
5.80 + }
5.81 + m_aggregates = 0;
5.82 }
5.83 Object::Object (const Object &o)
5.84 : m_count (1),
5.85 m_tid (o.m_tid),
5.86 m_disposed (false),
5.87 - m_next (this)
5.88 -{}
5.89 + m_aggregates ((struct Aggregates *)malloc (sizeof (struct Aggregates))),
5.90 + m_getObjectCount (0)
5.91 +{
5.92 + m_aggregates->n = 1;
5.93 + m_aggregates->buffer[0] = this;
5.94 +}
5.95 uint32_t
5.96 Object::GetReferenceCount (void) const
5.97 {
5.98 @@ -112,48 +136,58 @@
5.99 Object::DoGetObject (TypeId tid) const
5.100 {
5.101 NS_ASSERT (CheckLoose ());
5.102 - const Object *currentObject = this;
5.103 - const Object *prevObject = 0;
5.104 +
5.105 + uint32_t n = m_aggregates->n;
5.106 TypeId objectTid = Object::GetTypeId ();
5.107 - do {
5.108 - NS_ASSERT (currentObject != 0);
5.109 - TypeId cur = currentObject->GetInstanceTypeId ();
5.110 - while (cur != tid && cur != objectTid)
5.111 - {
5.112 - cur = cur.GetParent ();
5.113 - }
5.114 - if (cur == tid)
5.115 - {
5.116 - if (prevObject != 0)
5.117 - {
5.118 - // This is an attempt to 'cache' the result of this lookup.
5.119 - // the idea is that if we perform a lookup for a TypdId on this object,
5.120 - // we are likely to perform the same lookup later so, we re-order
5.121 - // the circular linked-list of objects here by putting the object we
5.122 - // just found at the head of the list. This optimization is
5.123 - // _extremely_ effective in general.
5.124 - const_cast<Object*>(prevObject)->m_next = currentObject->m_next;
5.125 - const_cast<Object*>(currentObject)->m_next = m_next;
5.126 - const_cast<Object*>(this)->m_next = (Object*)currentObject;
5.127 - }
5.128 - return const_cast<Object *> (currentObject);
5.129 - }
5.130 - prevObject = currentObject;
5.131 - currentObject = currentObject->m_next;
5.132 - } while (currentObject != this);
5.133 + for (uint32_t i = 0; i < n; i++)
5.134 + {
5.135 + Object *current = m_aggregates->buffer[i];
5.136 + TypeId cur = current->GetInstanceTypeId ();
5.137 + while (cur != tid && cur != objectTid)
5.138 + {
5.139 + cur = cur.GetParent ();
5.140 + }
5.141 + if (cur == tid)
5.142 + {
5.143 + // This is an attempt to 'cache' the result of this lookup.
5.144 + // the idea is that if we perform a lookup for a TypeId on this object,
5.145 + // we are likely to perform the same lookup later so, we make sure
5.146 + // that the aggregate array is sorted by the number of accesses
5.147 + // to each object.
5.148 +
5.149 + // first, increment the access count
5.150 + current->m_getObjectCount++;
5.151 + // then, update the sort
5.152 + UpdateSortedArray (m_aggregates, i);
5.153 + // finally, return the match
5.154 + return const_cast<Object *> (current);
5.155 + }
5.156 + }
5.157 return 0;
5.158 }
5.159 void
5.160 Object::Dispose (void)
5.161 {
5.162 - Object *current = this;
5.163 - do {
5.164 - NS_ASSERT (current != 0);
5.165 - NS_ASSERT (!current->m_disposed);
5.166 - current->DoDispose ();
5.167 - current->m_disposed = true;
5.168 - current = current->m_next;
5.169 - } while (current != this);
5.170 + uint32_t n = m_aggregates->n;
5.171 + for (uint32_t i = 0; i < n; i++)
5.172 + {
5.173 + Object *current = m_aggregates->buffer[i];
5.174 + NS_ASSERT (!current->m_disposed);
5.175 + current->DoDispose ();
5.176 + current->m_disposed = true;
5.177 + }
5.178 +}
5.179 +void
5.180 +Object::UpdateSortedArray (struct Aggregates *aggregates, uint32_t j) const
5.181 +{
5.182 + while (j > 0 &&
5.183 + aggregates->buffer[j]->m_getObjectCount > aggregates->buffer[j-1]->m_getObjectCount)
5.184 + {
5.185 + Object *tmp = aggregates->buffer[j-1];
5.186 + aggregates->buffer[j-1] = aggregates->buffer[j];
5.187 + aggregates->buffer[j] = tmp;
5.188 + j--;
5.189 + }
5.190 }
5.191 void
5.192 Object::AggregateObject (Ptr<Object> o)
5.193 @@ -171,20 +205,38 @@
5.194 }
5.195
5.196 Object *other = PeekPointer (o);
5.197 - Object *next = m_next;
5.198 - m_next = other->m_next;
5.199 - other->m_next = next;
5.200 - NS_ASSERT (CheckLoose ());
5.201 - NS_ASSERT (o->CheckLoose ());
5.202 - // call NotifyNewAggregate in the listed chain
5.203 - Object *currentObject = this;
5.204 - do
5.205 + // first create the new aggregate buffer.
5.206 + uint32_t total = m_aggregates->n + other->m_aggregates->n;
5.207 + struct Aggregates *aggregates =
5.208 + (struct Aggregates *)malloc (sizeof(struct Aggregates)+(total-1)*sizeof(Object*));
5.209 + aggregates->n = total;
5.210 + memcpy (&aggregates->buffer[0],
5.211 + &m_aggregates->buffer[0],
5.212 + m_aggregates->n*sizeof(Object*));
5.213 + // append the other aggregates in the new buffer
5.214 + for (uint32_t i = 0; i < other->m_aggregates->n; i++)
5.215 {
5.216 - // the NotifyNewAggregate of the current object implementation
5.217 - // should be called on the next object in the linked chain
5.218 - currentObject->NotifyNewAggregate ();
5.219 - currentObject = currentObject->m_next;
5.220 - } while (currentObject != this);
5.221 + aggregates->buffer[m_aggregates->n+i] = other->m_aggregates->buffer[i];
5.222 + UpdateSortedArray (aggregates, m_aggregates->n + i);
5.223 + }
5.224 +
5.225 + // free both aggregate buffers
5.226 + free (m_aggregates);
5.227 + free (other->m_aggregates);
5.228 +
5.229 + // Then, assign that buffer to every object
5.230 + uint32_t n = aggregates->n;
5.231 + for (uint32_t i = 0; i < n; i++)
5.232 + {
5.233 + Object *current = aggregates->buffer[i];
5.234 + current->m_aggregates = aggregates;
5.235 + }
5.236 + // Finally, call NotifyNewAggregate in the listed chain
5.237 + for (uint32_t i = 0; i < n; i++)
5.238 + {
5.239 + Object *current = m_aggregates->buffer[i];
5.240 + current->NotifyNewAggregate ();
5.241 + }
5.242 }
5.243 /**
5.244 * This function must be implemented in the stack that needs to notify
5.245 @@ -233,14 +285,12 @@
5.246 Object::CheckLoose (void) const
5.247 {
5.248 uint32_t refcount = 0;
5.249 - const Object *current = this;
5.250 - do
5.251 + uint32_t n = m_aggregates->n;
5.252 + for (uint32_t i = 0; i < n; i++)
5.253 {
5.254 + Object *current = m_aggregates->buffer[i];
5.255 refcount += current->m_count;
5.256 - current = current->m_next;
5.257 }
5.258 - while (current != this);
5.259 -
5.260 return (refcount > 0);
5.261 }
5.262
5.263 @@ -249,38 +299,38 @@
5.264 {
5.265 // First, check if any of the attached
5.266 // Object has a non-zero count.
5.267 - const Object *current = this;
5.268 - do {
5.269 - NS_ASSERT (current != 0);
5.270 - if (current->m_count != 0)
5.271 - {
5.272 - return;
5.273 - }
5.274 - current = current->m_next;
5.275 - } while (current != this);
5.276 + uint32_t n = m_aggregates->n;
5.277 + for (uint32_t i = 0; i < n; i++)
5.278 + {
5.279 + Object *current = m_aggregates->buffer[i];
5.280 + if (current->m_count != 0)
5.281 + {
5.282 + return;
5.283 + }
5.284 + }
5.285
5.286 // Ensure we are disposed.
5.287 - Object *tmp = const_cast<Object *> (this);
5.288 - const Object *end = this;
5.289 - do {
5.290 - NS_ASSERT (current != 0);
5.291 - Object *next = tmp->m_next;
5.292 - if (!tmp->m_disposed)
5.293 - {
5.294 - tmp->DoDispose ();
5.295 - }
5.296 - tmp = next;
5.297 - } while (tmp != end);
5.298 + for (uint32_t i = 0; i < n; i++)
5.299 + {
5.300 + Object *current = m_aggregates->buffer[i];
5.301 + if (!current->m_disposed)
5.302 + {
5.303 + current->DoDispose ();
5.304 + }
5.305 + }
5.306
5.307 // all attached objects have a zero count so,
5.308 - // we can delete all attached objects.
5.309 - current = this;
5.310 - do {
5.311 - NS_ASSERT (current != 0);
5.312 - Object *next = current->m_next;
5.313 - delete current;
5.314 - current = next;
5.315 - } while (current != end);
5.316 + // we can delete them all.
5.317 + struct Aggregates *aggregates = m_aggregates;
5.318 + for (uint32_t i = 0; i < n; i++)
5.319 + {
5.320 + // There is a trick here: each time we call delete below,
5.321 + // the deleted object is removed from the aggregate buffer
5.322 + // in the destructor so, the index of the next element to
5.323 + // lookup is always zero
5.324 + Object *current = aggregates->buffer[0];
5.325 + delete current;
5.326 + }
5.327 }
5.328 } // namespace ns3
5.329
6.1 --- a/src/core/object.h Thu Nov 05 19:14:37 2009 -0800
6.2 +++ b/src/core/object.h Thu Nov 05 19:15:28 2009 -0800
6.3 @@ -85,9 +85,9 @@
6.4 Ptr<const Object> Next (void);
6.5 private:
6.6 friend class Object;
6.7 - AggregateIterator (Ptr<const Object> first);
6.8 - Ptr<const Object> m_first;
6.9 - Ptr<const Object> m_current;
6.10 + AggregateIterator (Ptr<const Object> object);
6.11 + Ptr<const Object> m_object;
6.12 + uint32_t m_current;
6.13 };
6.14
6.15 Object ();
6.16 @@ -215,6 +215,21 @@
6.17 friend class ObjectFactory;
6.18 friend class AggregateIterator;
6.19
6.20 + /**
6.21 + * This data structure uses a classic C-style trick to
6.22 + * hold an array of variable size without performing
6.23 + * two memory allocations: the declaration of the structure
6.24 + * declares a one-element array but when we allocate
6.25 + * memory for this struct, we effectively allocate a larger
6.26 + * chunk of memory than the struct to allow space for a larger
6.27 + * variable sized buffer whose size is indicated by the element
6.28 + * 'n'
6.29 + */
6.30 + struct Aggregates {
6.31 + uint32_t n;
6.32 + Object *buffer[1];
6.33 + };
6.34 +
6.35 Ptr<Object> DoGetObject (TypeId tid) const;
6.36 bool Check (void) const;
6.37 bool CheckLoose (void) const;
6.38 @@ -243,6 +258,8 @@
6.39 */
6.40 void Construct (const AttributeList &attributes);
6.41
6.42 + void UpdateSortedArray (struct Aggregates *aggregates, uint32_t i) const;
6.43 +
6.44 /**
6.45 * The reference count for this object. Each aggregate
6.46 * has an individual reference count. When the global
6.47 @@ -261,13 +278,19 @@
6.48 */
6.49 bool m_disposed;
6.50 /**
6.51 - * A pointer to the next aggregate object. This is a circular
6.52 - * linked list of aggregated objects: the last one points
6.53 - * back to the first one. If an object is not aggregated to
6.54 - * any other object, the value of this field is equal to the
6.55 - * value of the 'this' pointer.
6.56 + * a pointer to an array of 'aggregates'. i.e., a pointer to
6.57 + * each object aggregated to this object is stored in this
6.58 + * array. The array is shared by all aggregated objects
6.59 + * so the size of the array is indirectly a reference count.
6.60 */
6.61 - Object *m_next;
6.62 + struct Aggregates * m_aggregates;
6.63 + /**
6.64 + * Indicates the number of times the object was accessed with a
6.65 + * call to GetObject. This integer is used to implement a
6.66 + * heuristic to sort the array of aggregates to put at the start
6.67 + * of the array the most-frequently accessed elements.
6.68 + */
6.69 + uint32_t m_getObjectCount;
6.70 };
6.71
6.72 /**
7.1 --- a/src/devices/mesh/dot11s/hwmp-protocol.cc Thu Nov 05 19:14:37 2009 -0800
7.2 +++ b/src/devices/mesh/dot11s/hwmp-protocol.cc Thu Nov 05 19:15:28 2009 -0800
7.3 @@ -401,6 +401,7 @@
7.4 //acceptance cretirea:
7.5 std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
7.6 preq.GetOriginatorAddress ());
7.7 + bool freshInfo (true);
7.8 if (i != m_hwmpSeqnoMetricDatabase.end ())
7.9 {
7.10 if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
7.11 @@ -409,6 +410,7 @@
7.12 }
7.13 if (i->second.first == preq.GetOriginatorSeqNumber ())
7.14 {
7.15 + freshInfo = false;
7.16 if (i->second.second <= preq.GetMetric ())
7.17 {
7.18 return;
7.19 @@ -421,7 +423,7 @@
7.20 std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
7.21 //Add reactive path to originator:
7.22 if (
7.23 - ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) < 0) ||
7.24 + (freshInfo) ||
7.25 (
7.26 (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
7.27 (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
7.28 @@ -562,9 +564,17 @@
7.29 //acceptance cretirea:
7.30 std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
7.31 prep.GetOriginatorAddress ());
7.32 - if ((i != m_hwmpSeqnoMetricDatabase.end ()) && ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0))
7.33 + bool freshInfo (true);
7.34 + if (i != m_hwmpSeqnoMetricDatabase.end ())
7.35 {
7.36 - return;
7.37 + if ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0)
7.38 + {
7.39 + return;
7.40 + }
7.41 + if (i->second.first == prep.GetOriginatorSeqNumber ())
7.42 + {
7.43 + freshInfo = false;
7.44 + }
7.45 }
7.46 m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (prep.GetOriginatorSeqNumber (), prep.GetMetric ());
7.47 //update routing info
7.48 @@ -574,7 +584,7 @@
7.49 //Add a reactive path only if seqno is fresher or it improves the
7.50 //metric
7.51 if (
7.52 - (((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) < 0)) ||
7.53 + (freshInfo) ||
7.54 (
7.55 ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
7.56 ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())