update various refcount patches
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 26 Dec 2009 19:03:36 +0100
changeset 3 82c980107fc4
parent 2 6f00a498cce2
child 4 1ef8640dee4a
update various refcount patches
add-ts-primitives
use-ts-primitives
--- a/add-ts-primitives	Fri Dec 25 18:05:18 2009 +0100
+++ b/add-ts-primitives	Sat Dec 26 19:03:36 2009 +0100
@@ -1,6 +1,6 @@
-diff -r 0f612e981787 src/core/Makefile
+diff -r c7a0ec2bdae4 src/core/Makefile
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/Makefile	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/Makefile	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,8 @@
 +CXXFLAGS+=-O0 -Wall -g3
 +all: tst
@@ -11,9 +11,9 @@
 +clean: 
 +	rm -f tst *.o *~
 \ No newline at end of file
-diff -r 0f612e981787 src/core/atomic-ref-count.h
+diff -r c7a0ec2bdae4 src/core/atomic-ref-count.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/atomic-ref-count.h	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/atomic-ref-count.h	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,72 @@
 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 +/*
@@ -87,9 +87,9 @@
 +} // namespace ns3
 +
 +#endif /* ATOMIC_REF_COUNT_H */
-diff -r 0f612e981787 src/core/buffer-ref-count.h
+diff -r c7a0ec2bdae4 src/core/buffer-ref-count.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/buffer-ref-count.h	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/buffer-ref-count.h	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,305 @@
 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 +/*
@@ -396,10 +396,10 @@
 +} // namespace ns3
 +
 +#endif /* BUFFER_REF_COUNT_H */
-diff -r 0f612e981787 src/core/hash-ref-count.h
+diff -r c7a0ec2bdae4 src/core/hash-ref-count.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/hash-ref-count.h	Fri Dec 25 18:04:44 2009 +0100
-@@ -0,0 +1,171 @@
++++ b/src/core/hash-ref-count.h	Sat Dec 26 19:02:15 2009 +0100
+@@ -0,0 +1,172 @@
 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 +/*
 + * Copyright (c) 2009 Mathieu Lacage
@@ -478,6 +478,7 @@
 +          }
 +      }
 +    delete [] entries;
++    tls->hashRefCount = 0;
 +  }
 +
 +  int GetReferenceCount (void) const 
@@ -571,10 +572,10 @@
 +} // namespace ns3
 +
 +#endif /* HASH_REF_COUNT_H */
-diff -r 0f612e981787 src/core/no-ref-count.h
+diff -r c7a0ec2bdae4 src/core/no-ref-count.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/no-ref-count.h	Fri Dec 25 18:04:44 2009 +0100
-@@ -0,0 +1,89 @@
++++ b/src/core/no-ref-count.h	Sat Dec 26 19:02:15 2009 +0100
+@@ -0,0 +1,124 @@
 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 +/*
 + * Copyright (c) 2009 Mathieu Lacage
@@ -600,10 +601,11 @@
 +#include "empty.h"
 +#include "default-deleter.h"
 +#include "atomic.h"
-+#include "tls-data.h"
++#include "spin-lock.h"
 +
 +namespace ns3 {
 +
++
 +/**
 + * XXX
 + */
@@ -611,25 +613,30 @@
 +class NoRefCount : public PARENT
 +{
 +private:
-+  NoRefCount *m_next;
-+  static inline NoRefCount *Head (void) __attribute__((const))
++  mutable NoRefCount *m_next;
++  mutable NoRefCount *m_prev;
++  static NoRefCount *g_head;
++  static RecursiveSpinLock g_lock;
++  inline void Construct (void)
 +  {
-+    return (NoRefCount *) TlsDataGet ()->noRefCountListHead;
++    g_lock.Lock ();
++    m_prev = 0;
++    m_next = g_head;
++    if (m_next != 0)
++      {
++        m_next->m_prev = this;
++      }
++    g_head = this;
++    g_lock.Unlock ();
 +  }
-+  static inline void Insert (NoRefCount *self)
-+  {
-+    TlsDataGet ()->noRefCountListHead = self;
-+  } 
 +public:
 +  inline NoRefCount ()
 +  {
-+    m_next = Head ();
-+    Insert (this);
++    Construct ();
 +  }
 +  inline NoRefCount (const NoRefCount &o)
 +  {
-+    m_next = Head ();
-+    Insert (this);
++    Construct ();
 +  }
 +  NoRefCount & operator = (const NoRefCount &o)
 +  {
@@ -637,18 +644,21 @@
 +  }
 +  ~NoRefCount () 
 +  {
-+    m_next = 0;
++    Remove ();
 +  }
 +  static void Cleanup (void)
 +  {
-+    NoRefCount *current = Head ();
-+    while (current != 0)
-+      {
-+	NoRefCount *next = current->m_next;
-+	DELETER::Delete (static_cast<T*> (current));
-+	current = next;
-+      }
-+    Insert (0);
++    g_lock.Lock ();
++    // a pointer to volatile pointer to NoRefCount
++    // volatile introduced to force the while loop
++    // below to read the memory location at each
++    // iteration.
++    //NoRefCount *volatile *phead = &g_head;
++    //while (*phead != 0)
++    //{
++	//DELETER::Delete (static_cast<T*> (*phead));
++    //}
++    g_lock.Unlock ();
 +  }
 +  inline void Ref (void) const
 +  {}
@@ -658,15 +668,41 @@
 +  {
 +    return 0;
 +  }
++  void Remove (void) const
++  {
++    g_lock.Lock ();
++    if (g_head == this)
++      {
++        // head of list
++        g_head = m_next;
++      }
++    if (m_prev != 0)
++      {
++        m_prev->m_next = m_next;
++      }
++    if (m_next != 0)
++      {
++        m_next->m_prev = m_prev;
++      }
++    m_prev = 0;
++    m_next = 0;    
++    g_lock.Unlock ();
++  }
 +};
 +
++template <typename T, typename PARENT, typename DELETER>
++NoRefCount<T,PARENT,DELETER> *NoRefCount<T,PARENT,DELETER>::g_head;
++template <typename T, typename PARENT, typename DELETER>
++RecursiveSpinLock NoRefCount<T,PARENT,DELETER>::g_lock;
++
++
 +} // namespace ns3
 +
 +#endif /* NO_REF_COUNT_H */
 +
-diff -r 0f612e981787 src/core/reference-list.h
+diff -r c7a0ec2bdae4 src/core/reference-list.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/reference-list.h	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/reference-list.h	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,118 @@
 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 +/*
@@ -786,13 +822,16 @@
 +};
 +
 +#endif /* REFERENCE_LIST_H */
-diff -r 0f612e981787 src/core/spin-lock.h
+diff -r c7a0ec2bdae4 src/core/spin-lock.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/spin-lock.h	Fri Dec 25 18:04:44 2009 +0100
-@@ -0,0 +1,40 @@
++++ b/src/core/spin-lock.h	Sat Dec 26 19:02:15 2009 +0100
+@@ -0,0 +1,92 @@
 +#ifndef SPIN_LOCK_H
 +#define SPIN_LOCK_H
 +
++#include "assert.h"
++#include "tls-data.h"
++
 +namespace ns3 {
 +
 +class SpinLock
@@ -801,18 +840,31 @@
 +  inline SpinLock ();
 +  inline void Lock (void);
 +  inline void Unlock (void);
++  inline bool IsLocked (void) const;
 +private:
 +  int m_lock;
 +};
 +
++class RecursiveSpinLock
++{
++public:
++  inline RecursiveSpinLock ();
++  inline void Lock (void);
++  inline void Unlock (void);
++private:
++  void *m_lockHolder;
++  int m_lockCounter;
++  SpinLock m_lock;
++};
++
 +} // namespace ns3
 +
 +namespace ns3 {
 +
-+inline SpinLock::SpinLock ()
++SpinLock::SpinLock ()
 +  : m_lock (0)
 +{}
-+inline void 
++void 
 +SpinLock::Lock (void)
 +{
 +  int old = AtomicCompareAndExchange (&m_lock, 0, 1);
@@ -821,18 +873,54 @@
 +      old = AtomicCompareAndExchange (&m_lock, 0, 1);
 +    }
 +}
-+inline void 
++void 
 +SpinLock::Unlock (void)
 +{
 +  AtomicExchangeAndAdd (&m_lock, -1);
 +}
 +
++bool 
++SpinLock::IsLocked (void) const
++{
++  return AtomicGet ((volatile int *)&m_lock) == 1;
++}
++
++
++RecursiveSpinLock::RecursiveSpinLock ()
++  : m_lockHolder (0),
++    m_lockCounter (0),
++    m_lock ()
++{}
++void 
++RecursiveSpinLock::Lock (void)
++{
++  if (TlsDataGet () == m_lockHolder)
++    {
++      m_lockCounter++;
++      return;
++    }
++  m_lock.Lock ();
++  m_lockCounter++;
++  m_lockHolder = TlsDataGet ();
++}
++void 
++RecursiveSpinLock::Unlock (void)
++{
++  NS_ASSERT (TlsDataGet () == m_lockHolder);
++  m_lockCounter--;
++  if (m_lockCounter == 0)
++    {
++      m_lockHolder = 0;
++      m_lock.Unlock ();
++    }
++}
++
 +} // namespace ns3
 +
 +#endif /* SPIN_LOCK_H */
-diff -r 0f612e981787 src/core/spin-rwlock.cc
+diff -r c7a0ec2bdae4 src/core/spin-rwlock.cc
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/spin-rwlock.cc	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/spin-rwlock.cc	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,48 @@
 +#include "spin-rwlock.h"
 +#include "atomic.h"
@@ -882,9 +970,9 @@
 +}
 +
 +} // namespace ns3
-diff -r 0f612e981787 src/core/spin-rwlock.h
+diff -r c7a0ec2bdae4 src/core/spin-rwlock.h
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/spin-rwlock.h	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/spin-rwlock.h	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,20 @@
 +#ifndef SPIN_RWLOCK_H
 +#define SPIN_RWLOCK_H
@@ -906,9 +994,9 @@
 +} // namespace ns3
 +
 +#endif /* SPIN_RWLOCK_H */
-diff -r 0f612e981787 src/core/tls-data.h
---- a/src/core/tls-data.h	Wed Dec 23 09:37:03 2009 +0100
-+++ b/src/core/tls-data.h	Fri Dec 25 18:04:44 2009 +0100
+diff -r c7a0ec2bdae4 src/core/tls-data.h
+--- a/src/core/tls-data.h	Fri Dec 25 18:17:40 2009 +0100
++++ b/src/core/tls-data.h	Sat Dec 26 19:02:15 2009 +0100
 @@ -32,6 +32,9 @@
    uint16_t packetMetadataMaxSize;
    uint32_t bufferMaxSize;
@@ -937,9 +1025,9 @@
  inline struct TlsData *
  TlsDataGet (void)
  {
-diff -r 0f612e981787 src/core/tst.cc
+diff -r c7a0ec2bdae4 src/core/tst.cc
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/src/core/tst.cc	Fri Dec 25 18:04:44 2009 +0100
++++ b/src/core/tst.cc	Sat Dec 26 19:02:15 2009 +0100
 @@ -0,0 +1,168 @@
 +#include "simple-ref-count.h"
 +#include "atomic-ref-count.h"
@@ -1109,9 +1197,9 @@
 +  
 +  return 0;
 +}
-diff -r 0f612e981787 src/core/wscript
---- a/src/core/wscript	Wed Dec 23 09:37:03 2009 +0100
-+++ b/src/core/wscript	Fri Dec 25 18:04:44 2009 +0100
+diff -r c7a0ec2bdae4 src/core/wscript
+--- a/src/core/wscript	Fri Dec 25 18:17:40 2009 +0100
++++ b/src/core/wscript	Sat Dec 26 19:02:15 2009 +0100
 @@ -81,6 +81,7 @@
          'traced-callback-test-suite.cc',
          'ptr-test-suite.cc',
--- a/use-ts-primitives	Fri Dec 25 18:05:18 2009 +0100
+++ b/use-ts-primitives	Sat Dec 26 19:03:36 2009 +0100
@@ -1,6 +1,6 @@
-diff -r 8c334a2fb970 src/common/ascii-writer.h
---- a/src/common/ascii-writer.h	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/common/ascii-writer.h	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/common/ascii-writer.h
+--- a/src/common/ascii-writer.h	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/common/ascii-writer.h	Sat Dec 26 19:02:29 2009 +0100
 @@ -23,7 +23,7 @@
  
  #include <stdint.h>
@@ -19,9 +19,9 @@
  {
  public:
    static Ptr<AsciiWriter> Get (std::ostream &os);
-diff -r 8c334a2fb970 src/core/attribute.h
---- a/src/core/attribute.h	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/core/attribute.h	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/core/attribute.h
+--- a/src/core/attribute.h	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/core/attribute.h	Sat Dec 26 19:02:29 2009 +0100
 @@ -23,7 +23,7 @@
  #include <string>
  #include <stdint.h>
@@ -58,9 +58,9 @@
  {
  public:
    AttributeChecker ();
-diff -r 8c334a2fb970 src/core/callback.h
---- a/src/core/callback.h	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/core/callback.h	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/core/callback.h
+--- a/src/core/callback.h	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/core/callback.h	Sat Dec 26 19:02:29 2009 +0100
 @@ -27,7 +27,7 @@
  #include "type-traits.h"
  #include "attribute.h"
@@ -79,9 +79,9 @@
  {
  public:
    virtual ~CallbackImplBase () {}
-diff -r 8c334a2fb970 src/core/object.cc
---- a/src/core/object.cc	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/core/object.cc	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/core/object.cc
+--- a/src/core/object.cc	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/core/object.cc	Sat Dec 26 19:02:29 2009 +0100
 @@ -85,6 +85,7 @@
      m_aggregates ((struct Aggregates *)malloc (sizeof (struct Aggregates))),
      m_getObjectCount (0)
@@ -98,15 +98,15 @@
    m_aggregates->n = 1;
    m_aggregates->buffer[0] = this;
  }
-@@ -128,15 +130,16 @@
+@@ -128,15 +130,14 @@
  }
  
  Ptr<Object>
 -Object::DoGetObject (TypeId tid) const
 +Object::DoGetObject (struct Aggregates *aggregates, TypeId tid) const
  {
-   NS_ASSERT (CheckLoose ());
- 
+-  NS_ASSERT (CheckLoose ());
+-
 -  uint32_t n = m_aggregates->n;
 +  aggregates->lock.RLock ();
 +  uint32_t n = aggregates->n;
@@ -118,7 +118,7 @@
        TypeId cur = current->GetInstanceTypeId ();
        while (cur != tid && cur != objectTid)
          {
-@@ -152,12 +155,14 @@
+@@ -152,12 +153,14 @@
  
            // first, increment the access count
            current->m_getObjectCount++;
@@ -134,7 +134,7 @@
    return 0;
  }
  void
-@@ -211,6 +216,7 @@
+@@ -211,6 +214,7 @@
  void
  Object::UpdateSortedArray (struct Aggregates *aggregates, uint32_t j) const
  {
@@ -142,7 +142,7 @@
    while (j > 0 && 
           aggregates->buffer[j]->m_getObjectCount > aggregates->buffer[j-1]->m_getObjectCount)
      {
-@@ -219,6 +225,7 @@
+@@ -219,27 +223,30 @@
        aggregates->buffer[j] = tmp;
        j--;
      }
@@ -150,9 +150,11 @@
  }
  void 
  Object::AggregateObject (Ptr<Object> o)
-@@ -228,18 +235,22 @@
-   NS_ASSERT (CheckLoose ());
-   NS_ASSERT (o->CheckLoose ());
+ {
+   NS_ASSERT (!m_disposed);
+   NS_ASSERT (!o->m_disposed);
+-  NS_ASSERT (CheckLoose ());
+-  NS_ASSERT (o->CheckLoose ());
  
 -  if (DoGetObject (o->GetInstanceTypeId ()))
 +  if (DoGetObject (m_aggregates, o->GetInstanceTypeId ()))
@@ -174,7 +176,7 @@
    aggregates->n = total;
  
    // copy our buffer to the new buffer
-@@ -283,6 +294,9 @@
+@@ -283,6 +290,9 @@
        current->NotifyNewAggregate ();
      }
  
@@ -184,21 +186,43 @@
    // Now that we are done with them, we can free our old aggregate buffers
    free (a);
    free (b);
-@@ -338,6 +352,7 @@
- bool 
- Object::CheckLoose (void) const
+@@ -306,7 +316,6 @@
+ void 
+ Object::SetTypeId (TypeId tid)
  {
-+  m_aggregates->lock.RLock ();
-   uint32_t refcount = 0;
-   uint32_t n = m_aggregates->n;
-   for (uint32_t i = 0; i < n; i++)
-@@ -345,20 +360,24 @@
-       Object *current = m_aggregates->buffer[i];
-       refcount += current->GetReferenceCount ();
-     }
-+  m_aggregates->lock.RUnlock ();
-   return (refcount > 0);
+-  NS_ASSERT (Check ());
+   m_tid = tid;
+ }
+ 
+@@ -322,43 +331,21 @@
+   NS_ASSERT (!m_started);
  }
+ 
+-bool 
+-Object::Check (void) const
+-{
+-  return (GetReferenceCount () > 0);
+-}
+-
+-/* In some cases, when an event is scheduled against a subclass of
+- * Object, and if no one owns a reference directly to this object, the
+- * object is alive, has a refcount of zero and the method ran when the
+- * event expires runs against the raw pointer which means that we are
+- * manipulating an object with a refcount of zero.  So, instead we
+- * check the aggregate reference count.
+- */
+-bool 
+-Object::CheckLoose (void) const
+-{
+-  uint32_t refcount = 0;
+-  uint32_t n = m_aggregates->n;
+-  for (uint32_t i = 0; i < n; i++)
+-    {
+-      Object *current = m_aggregates->buffer[i];
+-      refcount += current->GetReferenceCount ();
+-    }
+-  return (refcount > 0);
+-}
  void
  Object::DoDelete (void)
  {
@@ -217,29 +241,49 @@
  
    // Now, we know that we are alone to use this aggregate so, 
    // we can dispose and delete everything safely.
-diff -r 8c334a2fb970 src/core/object.h
---- a/src/core/object.h	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/core/object.h	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/core/object.h
+--- a/src/core/object.h	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/core/object.h	Sat Dec 26 19:02:29 2009 +0100
 @@ -28,7 +28,8 @@
  #include "attribute.h"
  #include "object-base.h"
  #include "attribute-list.h"
 -#include "simple-ref-count.h"
-+#include "hash-ref-count.h"
++#include "no-ref-count.h"
 +#include "spin-rwlock.h"
  
  
  namespace ns3 {
-@@ -61,7 +62,7 @@
+@@ -44,6 +45,19 @@
+   inline static void Delete (Object *object);
+ };
+ 
++// Note: this deleter is declared as a template to avoid 
++// instanciating the associated code when this NoRefCount
++// template base class is not used. i.e., the code of this
++// deleter class calls Object::Remove which is defined
++// in NoRefCount: if this was not a template, the deleter would
++// attempt to call Object::Remove which would not exist
++// when Object derives from another object.
++template <typename T>
++struct NoRefCountObjectDeleter
++{
++  inline static void Delete (Object *object);
++};
++
+ /**
+  * \ingroup core
+  * \defgroup object Object
+@@ -61,7 +75,7 @@
   * invoked from the Object::Unref method before destroying the object, even if the user 
   * did not call Object::Dispose directly.
   */
 -class Object : public SimpleRefCount<Object,ObjectBase,ObjectDeleter>
-+class Object : public HashRefCount<Object,ObjectBase,ObjectDeleter>
++class Object : public NoRefCount<Object,ObjectBase,NoRefCountObjectDeleter<Object> >
  {
  public:
    static TypeId GetTypeId (void);
-@@ -242,11 +243,12 @@
+@@ -242,13 +256,12 @@
     * 'n'
     */
    struct Aggregates {
@@ -249,11 +293,35 @@
    };
  
 -  Ptr<Object> DoGetObject (TypeId tid) const;
+-  bool Check (void) const;
+-  bool CheckLoose (void) const;
 +  Ptr<Object> DoGetObject (struct Aggregates *aggregates, TypeId tid) const;
-   bool Check (void) const;
-   bool CheckLoose (void) const;
    /**
-@@ -386,12 +388,13 @@
+    * \param tid an TypeId
+    *
+@@ -377,6 +390,21 @@
+ {
+   object->DoDelete ();
+ }
++template <typename T>
++void 
++NoRefCountObjectDeleter<T>::Delete (Object *object)
++{
++  // first, make sure that all aggregates are removed from
++  // the list of managed objects
++  Object::AggregateIterator i = object->GetAggregateIterator ();
++  while (i.HasNext ())
++    {
++      Ptr<const Object> current = i.Next ();
++      current->Remove ();
++    }
++  // finally, actually delete the object.
++  ObjectDeleter::Delete (object);
++}
+ 
+ /*************************************************************************
+  *   The Object implementation which depends on templates
+@@ -386,12 +414,13 @@
  Ptr<T> 
  Object::GetObject () const
  {
@@ -269,7 +337,7 @@
    if (found != 0)
      {
        return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
-@@ -403,7 +406,7 @@
+@@ -403,7 +432,7 @@
  Ptr<T> 
  Object::GetObject (TypeId tid) const
  {
@@ -278,9 +346,9 @@
    if (found != 0)
      {
        return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
-diff -r 8c334a2fb970 src/core/system-thread.h
---- a/src/core/system-thread.h	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/core/system-thread.h	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/core/system-thread.h
+--- a/src/core/system-thread.h	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/core/system-thread.h	Sat Dec 26 19:02:29 2009 +0100
 @@ -22,6 +22,7 @@
  #define SYSTEM_THREAD_H
  
@@ -314,9 +382,9 @@
     */
    SystemThread(Callback<void> callback);
  
-diff -r 8c334a2fb970 src/simulator/default-simulator-impl.cc
---- a/src/simulator/default-simulator-impl.cc	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/simulator/default-simulator-impl.cc	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/simulator/default-simulator-impl.cc
+--- a/src/simulator/default-simulator-impl.cc	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/simulator/default-simulator-impl.cc	Sat Dec 26 19:02:29 2009 +0100
 @@ -85,6 +85,7 @@
            ev->Invoke ();
          }
@@ -325,9 +393,9 @@
  }
  
  void
-diff -r 8c334a2fb970 src/simulator/realtime-simulator-impl.cc
---- a/src/simulator/realtime-simulator-impl.cc	Fri Dec 04 13:05:45 2009 +0100
-+++ b/src/simulator/realtime-simulator-impl.cc	Fri Dec 04 13:21:49 2009 +0100
+diff -r f8869d04c920 src/simulator/realtime-simulator-impl.cc
+--- a/src/simulator/realtime-simulator-impl.cc	Sat Dec 26 19:02:16 2009 +0100
++++ b/src/simulator/realtime-simulator-impl.cc	Sat Dec 26 19:02:29 2009 +0100
 @@ -121,6 +121,7 @@
            ev->Invoke ();
          }