merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Wed, 16 Jul 2008 10:46:51 +0100
changeset 3428 75f74d6b6219
parent 3427 3401e899479c (current diff)
parent 3426 108fd72e3291 (diff)
child 3429 2658cf81a5cd
child 3459 a67df503c7bc
merge
--- a/RELEASE_NOTES	Wed Jul 16 10:45:13 2008 +0100
+++ b/RELEASE_NOTES	Wed Jul 16 10:46:51 2008 +0100
@@ -3,6 +3,15 @@
 
 This file contains ns-3 release notes (most recent releases first).
 
+Next Release (in ns-3-dev)
+==========================
+- Kernel thread support (class SystemThread) added;
+- Kernel mutual exclusion support (class SystemMutex) added;
+- Kernel critical section RAII support (class CriticalSection) added;
+- Kernel system condition support (class SystemCondition) added;
+- Move required methods in helper classes to constructors;
+- Change obsolete references to Parameter to Attribute in helpers;
+
 Release 3.1 (2008/06/30)
 ========================
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/system-condition.h	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * 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 SYSTEM_CONDITION_H
+#define SYSTEM_CONDITION_H
+
+#include "ptr.h"
+
+namespace ns3 { 
+	
+class SystemConditionPrivate;
+
+/**
+ * @brief A class which provides a relatively platform-independent 
+ * conditional-wait thread synchronization primitive.
+ *
+ * It is often desirable to have a mechanism by which a thread can suspend its
+ * execution and relinquish the process until some condition to becomes true.
+ * We provide platform-independent access to this OS-dependent capability with
+ * the SystemCondition class.
+ *
+ * There are two ways to tell the underlying primitive that the condition has
+ * become true:  Signal and Broadcast.  Signal will only wake up one thread
+ * waiting on the condition (according to the OS scheduling policy); 
+ * Broadcast will wake up all of the threads waiting on the condition 
+ * (cf. "The Thundering Herd").
+ * 
+ * In order to wait for the underlying condition, you also have two
+ * alternatives:  Wait and TimedWait.  The Wait call will wait forever for the
+ * condition to become true; but the TimedWait has a timeout.
+ *
+ * The condition underlying this class is a simple boolean variable.  It is
+ * set to false in each call to Wait and TimedWait.  It is set to true in each
+ * call to Signal and Broadcast.  This is a fairly simple-minded condition
+ * designed for 
+ *
+ * A typical use case will be to call Wait() or TimedWait() in one thread
+ * context and put the processor to sleep until an event happens somewhere 
+ * else that 
+ */
+class SystemCondition
+{
+public:
+  SystemCondition ();
+  ~SystemCondition ();
+
+  /**
+   * Set the value of the underlying condition.
+   */
+  void SetCondition (bool condition);
+
+  /**
+   * Get the value of the underlying condition.
+   */
+  bool GetCondition (void);
+
+  /**
+   * Release one thread if waiting for the condition to be true.  If you want 
+   * a waiting thread to return, you should have done a SetCondition (true)
+   * prior to calling.
+   */
+  void Signal (void);
+
+  /**
+   * Release all threads waiting for the condition to be true.  If you want 
+   * all waiting threads to return, you should have done a SetCondition (true)
+   * prior to calling.
+   */
+  void Broadcast (void);
+
+  /**
+   * Wait, possibly forever, for the condition to be true.  
+   */
+  void Wait (void);
+	
+  /**
+   * Wait a maximum of ns nanoseconds for the condition to be true.  If the
+   * wait times out, return true else return false.
+   */
+  bool TimedWait (uint64_t ns);
+	
+
+private:
+  SystemConditionPrivate * m_priv;    
+};
+
+} //namespace ns3
+
+#endif /* SYSTEM_CONDITION_H */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/system-mutex.h	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage.inria.fr>
+ */
+
+#ifndef SYSTEM_MUTEX_H
+#define SYSTEM_MUTEX_H
+
+#include "ptr.h"
+
+namespace ns3 { 
+	
+class SystemMutexPrivate;
+
+/**
+ * @brief A class which provides a relatively platform-independent Mutual
+ * Exclusion thread synchronization primitive.
+ *
+ * When more than one thread needs to access a shared resource (data structure
+ * or device), the system needs to provide a way to serialize access to the
+ * resource.  An operating system will typically provide a Mutual Exclusion
+ * primitive to provide that capability.  We provide plattorm-independent
+ * access to the OS-dependent capability with the SystemMutex class.
+ *
+ * There are two operations:  Lock and Unlock.  Lock allows an executing 
+ * SystemThread to attempt to acquire ownership of the Mutual Exclusion 
+ * object.  If the SystemMutex object is not owned by another thread, then
+ * ownership is granted to the calling SystemThread and Lock returns 
+ * immediately,  However, if the SystemMutex is already owned by another
+ * SystemThread, the calling SystemThread is blocked until the current owner
+ * releases the SystemMutex by calling Unlock.
+ *
+ * @see CriticalSection
+ */
+class SystemMutex 
+{
+public:
+  SystemMutex ();
+  ~SystemMutex ();
+
+  /**
+   * Acquire ownership of the Mutual Exclusion object.
+   */
+  void Lock ();
+
+  /**
+   * Release ownership of the Mutual Exclusion object.
+   */
+  void Unlock ();
+	
+private:
+  SystemMutexPrivate * m_priv;    
+};
+
+/**
+ * @brief A class which provides a simple way to implement a Critical Section.
+ *
+ * When more than one SystemThread needs to access a shared resource, we
+ * conrol access by acquiring a SystemMutex.  The CriticalSection class uses
+ * the C++ scoping rules to automatically perform the required Lock and Unlock
+ * operations to implement a Critical Section.
+ *
+ * If one wants to treat an entire method call as a critical section, one would
+ * do something like,
+ *
+ * Class::Method ()
+ * {
+ *   CriticalSection cs (mutex);
+ *   ...
+ * }
+ *
+ * In this case, the critical section is entered when the CriticalSection 
+ * object is created, and the critical section is exited when the 
+ * CriticalSection object goes out of scope at the end of the method.
+ *
+ * Finer granularity is achieved by using local scope blocks.
+ *
+ * Class::Method ()
+ * {
+ *   ...
+ *   {
+ *     CriticalSection cs (mutex);
+ *   }
+ *   ...
+ * }
+ *
+ * Here, the critical section is entered partway through the method when the
+ * CriticalSection object is created in the local scope block (the braces).
+ * The critical section is exited when the CriticalSection object goes out of
+ * scope at the end of block.
+ *
+ * @see SystemMutex
+ */
+class CriticalSection
+{
+public:
+  CriticalSection (SystemMutex &mutex);
+  ~CriticalSection ();
+private:
+  SystemMutex &m_mutex;
+};
+
+} //namespace ns3
+
+#endif /* SYSTEM_MUTEX_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/system-thread.h	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage.inria.fr>
+ */
+
+#ifndef SYSTEM_THREAD_H
+#define SYSTEM_THREAD_H
+
+#include "callback.h"
+
+namespace ns3 { 
+
+class SystemThreadImpl;
+
+/**
+ * @brief A class which provides a relatively platform-independent thread
+ * primitive.
+ *
+ * This class allows for creation of multiple threads of execution in a
+ * process.  The exact implementation of the thread functionality is 
+ * operating system dependent, but typically in ns-3 one is using an 
+ * environment in which Posix Threads are supported (either navively or
+ * in the case of Windows via Cygwin's implementation of pthreads on the 
+ * Win32 API.  In either case we expect that these will be kernel-level
+ * threads and therefore a system with multiple CPUs will see truly concurrent 
+ * execution.
+ *
+ * Synchronization between threads is provided via the SystemMutex class.
+ */
+class SystemThread 
+{
+public:
+  /**
+   * @brief Create a SystemThread object.
+   *
+   * A system thread object is not created running.  A thread of execution
+   * must be explicitly started by calling the Start method.  When the 
+   * Start method is called, it will spawn a thread of execution and cause
+   * that thread to call out into the callback function provided here as
+   * a parameter.
+   *
+   * Like all ns-3 callbacks, the provided callback may refer to a function
+   * or a method of an object depending on how the MakeCallback function is
+   * used.
+   *
+   * The most common use is expected to be creating a thread of execution in
+   * a method.  In this case you would use code similar to,
+   *
+   *   MyClass myObject;
+   *   Ptr<SystemThread> st = Create<SystemThread> (
+   *     MakeCallback (&MyClass::MyMethod, &myObject));
+   *   st->Start ();
+   *
+   * The SystemThread is passed a callback that calls out to the function
+   * MyClass::MyMethod.  When this function is called, it is called as an
+   * object method on the myObject object.  Essentially what you are doing
+   * is asking the SystemThread to call object->MyMethod () in a new thread
+   * of execution.
+   *
+   * Remember that if you are invoking a callback on an object that is
+   * managed by a smart pointer, you need to call PeekPointer.
+   *
+   *   Ptr<MyClass> myPtr = Create<MyClass> ();
+   *   Ptr<SystemThread> st = Create<SystemThread> (
+   *     MakeCallback (&MyClass::MyMethod, PeekPointer (myPtr)));
+   *   st->Start ();
+   *
+   * Just like any thread, you can synchronize with its termination.  The 
+   * method provided to do this is Join (). If you call Join() you will block
+   * until the SystemThread run method returns.
+   *
+   * @warning I've made the system thread class look like a normal ns3 object
+   * with smart pointers, and living in the heap.  This makes it very easy to
+   * manage threads from a single master thread context.  You should be very
+   * aware though that I have not made Ptr multithread safe!  This means that
+   * if you pass Ptr<SystemThread> around in a multithreaded environment, it is
+   * possible that the reference count will get messed up since it is not an
+   * atomic operation.  CREATE AND MANAGE YOUR THREADS IN ONE PLACE -- LEAVE
+   * THE PTR THERE.
+   */
+  SystemThread(Callback<void> callback);
+
+  /**
+   * @brief Destroy a SystemThread object.
+   *
+   */
+  ~SystemThread();
+
+  /**
+   * Increment the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
+   */
+  inline void Ref (void) const;
+
+  /**
+   * Decrement the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
+   */
+  inline void Unref (void) const;
+
+  /**
+   * @brief Start a thread of execution, running the provided callback.
+   */
+  void Start (void);
+
+  /**
+   * @brief Suspend the caller until the thread of execution, running the 
+   * provided callback, finishes.
+   */
+  void Join (void);
+
+private:
+  SystemThreadImpl * m_impl;
+  mutable uint32_t m_count;
+};
+
+ void
+SystemThread::Ref (void) const
+{
+  m_count++;
+}
+
+ void
+SystemThread::Unref (void) const
+{
+  m_count--;
+  if (m_count == 0)
+    {
+      delete this;
+    }
+}
+
+} //namespace ns3
+
+#endif /* SYSTEM_THREAD_H */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/unix-system-condition.cc	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,212 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * 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
+ */
+
+#include <pthread.h>
+#include <errno.h>
+#include <sys/time.h>
+#include "fatal-error.h"
+#include "system-condition.h"
+#include "log.h"
+
+NS_LOG_COMPONENT_DEFINE ("SystemCondition");
+
+namespace ns3 {
+
+class SystemConditionPrivate {    
+public: 
+  static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
+
+  SystemConditionPrivate ();
+  ~SystemConditionPrivate ();
+	
+  void SetCondition (bool condition);
+  bool GetCondition (void);
+  void Signal (void);
+  void Broadcast (void);
+  void Wait (void);
+  bool TimedWait (uint64_t ns);
+
+private:
+  pthread_mutex_t m_mutex;
+  pthread_cond_t  m_cond;
+  bool m_condition;
+};
+
+SystemConditionPrivate::SystemConditionPrivate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_condition = false;
+
+  pthread_mutexattr_t mAttr;
+  pthread_mutexattr_init (&mAttr);
+  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
+  pthread_mutex_init (&m_mutex, &mAttr);
+
+  pthread_condattr_t cAttr;
+  pthread_condattr_init (&cAttr);
+  pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE);
+  pthread_cond_init (&m_cond, &cAttr);
+}
+    
+SystemConditionPrivate::~SystemConditionPrivate() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  pthread_mutex_destroy (&m_mutex);
+  pthread_cond_destroy (&m_cond);
+}
+	
+  void 
+SystemConditionPrivate::SetCondition (bool condition)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_condition = condition;
+}
+	
+  bool
+SystemConditionPrivate::GetCondition (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_condition;
+}
+	
+  void 
+SystemConditionPrivate::Signal (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  pthread_mutex_lock (&m_mutex);
+  pthread_cond_signal (&m_cond);
+  pthread_mutex_unlock (&m_mutex);
+}
+	
+  void 
+SystemConditionPrivate::Broadcast (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  pthread_mutex_lock (&m_mutex);
+  pthread_cond_broadcast (&m_cond);
+  pthread_mutex_unlock (&m_mutex);
+}
+
+  void 
+SystemConditionPrivate::Wait (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  pthread_mutex_lock (&m_mutex);
+  m_condition = false;
+  while (m_condition == false)
+    {
+      pthread_cond_wait (&m_cond, &m_mutex);
+    }
+  pthread_mutex_unlock (&m_mutex);
+}
+
+  bool
+SystemConditionPrivate::TimedWait (uint64_t ns)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  struct timespec ts;
+  ts.tv_sec = ns / NS_PER_SEC;
+  ts.tv_nsec = ns % NS_PER_SEC;
+
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+
+  ts.tv_sec += tv.tv_sec;
+  ts.tv_nsec += tv.tv_usec * 1000;
+  if (ts.tv_nsec > (int64_t)NS_PER_SEC)
+    {
+      ++ts.tv_sec;
+      ts.tv_nsec %= NS_PER_SEC;
+    }
+
+  int rc;
+
+  pthread_mutex_lock (&m_mutex);
+  while (m_condition == false)
+    {
+      rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts);
+      if (rc == ETIMEDOUT)
+        {
+          pthread_mutex_unlock (&m_mutex); 
+         return true;
+        }
+    }
+  pthread_mutex_unlock (&m_mutex);
+  return false;
+}
+	
+SystemCondition::SystemCondition() 
+  : m_priv (new SystemConditionPrivate ())
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+SystemCondition::~SystemCondition () 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  delete m_priv;
+}
+
+  void 
+SystemCondition::SetCondition (bool condition) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->SetCondition (condition);
+}
+
+  bool
+SystemCondition::GetCondition (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_priv->GetCondition ();
+}
+
+  void 
+SystemCondition::Signal (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->Signal ();
+}
+
+  void 
+SystemCondition::Broadcast (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->Broadcast ();
+}  
+
+  void 
+SystemCondition::Wait (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->Wait ();
+}  
+
+  bool
+SystemCondition::TimedWait (uint64_t ns) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_priv->TimedWait (ns);
+}  
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/unix-system-mutex.cc	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,131 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage.inria.fr>
+ */
+
+#include <pthread.h>
+#include <errno.h>
+#include "fatal-error.h"
+#include "system-mutex.h"
+#include "log.h"
+
+NS_LOG_COMPONENT_DEFINE ("SystemMutex");
+
+namespace ns3 {
+
+class SystemMutexPrivate {    
+public: 
+  SystemMutexPrivate ();
+  ~SystemMutexPrivate ();
+	
+  void Lock (void);
+  void Unlock (void);
+private:
+  pthread_mutex_t m_mutex;
+};
+
+SystemMutexPrivate::SystemMutexPrivate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  pthread_mutexattr_t attr;
+  pthread_mutexattr_init (&attr);
+//
+// Make this an error checking mutex.  This will check to see if the current
+// thread already owns the mutex before trying to lock it.  Instead of 
+// deadlocking it returns an error.  It will also check to make sure a thread
+// has previously called pthread_mutex_lock when it calls pthread_mutex_unlock.
+//
+  pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+  pthread_mutex_init (&m_mutex, &attr);
+}
+    
+SystemMutexPrivate::~SystemMutexPrivate() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  pthread_mutex_destroy (&m_mutex);
+}
+	
+  void 
+SystemMutexPrivate::Lock (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  int rc = pthread_mutex_lock (&m_mutex);
+  if (rc != 0) 
+    {
+      NS_FATAL_ERROR ("SystemMutexPrivate::Lock()"
+        "pthread_mutex_lock failed: " << rc << " = \"" << 
+        strerror(rc) << "\"");
+    }
+}
+	
+  void
+SystemMutexPrivate::Unlock (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  int rc = pthread_mutex_unlock (&m_mutex);
+  if (rc != 0)
+    {
+      NS_FATAL_ERROR ("SystemMutexPrivate::Unlock()"
+        "pthread_mutex_unlock failed: " << rc << " = \"" << 
+        strerror(rc) << "\"");
+    }
+}
+
+SystemMutex::SystemMutex() 
+  : m_priv (new SystemMutexPrivate ())
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+SystemMutex::~SystemMutex() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  delete m_priv;
+}
+
+  void 
+SystemMutex::Lock() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->Lock ();
+}
+
+  void 
+SystemMutex::Unlock() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_priv->Unlock ();
+}  
+
+CriticalSection::CriticalSection (SystemMutex &mutex)
+  : m_mutex(mutex)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_mutex.Lock ();
+}
+
+CriticalSection::~CriticalSection ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_mutex.Unlock ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/unix-system-thread.cc	Wed Jul 16 10:46:51 2008 +0100
@@ -0,0 +1,138 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage.inria.fr>
+ */
+
+#include <pthread.h>
+#include "fatal-error.h"
+#include "system-thread.h"
+#include "log.h"
+
+NS_LOG_COMPONENT_DEFINE ("SystemThread");
+
+namespace ns3 {
+
+//
+// Private implementation class for the SystemThread class.  The deal is
+// that we export the SystemThread class to the user.  The header just 
+// declares a class and its members.  There is a forward declaration for
+// a private implementation class there and a member declaration.  Thus
+// there is no knowledge of the implementation in the exported header.
+//
+// We provide an implementation class for each operating system.  This is
+// the Unix implementation of the SystemThread.
+//
+// In order to use the SystemThread, you will include "system-thread.h" and
+// get the implementation by linking unix-system-thread.cc (if you are running
+// a Posix system).
+//
+class SystemThreadImpl
+{
+public:
+  SystemThreadImpl (Callback<void> callback);
+
+  void Start (void);
+  void Join (void);
+
+private:
+  static void *DoRun (void *arg);
+  Callback<void> m_callback;
+  pthread_t m_thread;
+  void *    m_ret;
+};
+
+SystemThreadImpl::SystemThreadImpl (Callback<void> callback)
+  : m_callback (callback)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+  void
+SystemThreadImpl::Start (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  int rc = pthread_create (&m_thread, NULL, &SystemThreadImpl::DoRun,
+    (void *)this);
+
+  if (rc) 
+    {
+      NS_FATAL_ERROR ("pthread_create failed: " << rc << "=\"" << 
+        strerror(rc) << "\".");
+    }
+}
+
+  void 
+SystemThreadImpl::Join (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  void *thread_return;
+  int rc = pthread_join (m_thread, &thread_return);
+  if (rc) 
+    {
+      NS_FATAL_ERROR ("pthread_join failed: " << rc << "=\"" << 
+        strerror(rc) << "\".");
+    }
+}
+
+  void *
+SystemThreadImpl::DoRun (void *arg)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  SystemThreadImpl *self = static_cast<SystemThreadImpl *> (arg);
+  self->m_callback ();
+
+  return 0;
+}
+
+//
+// Remember that we just export the delcaration of the SystemThread class to
+// the user.  There is no code to implement the SystemThread methods.  We
+// have to do that here.  We just vector the calls to our implementation 
+// class above.
+//
+SystemThread::SystemThread (Callback<void> callback) 
+  : m_impl (new SystemThreadImpl (callback)),
+    m_count (1)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+  
+SystemThread::~SystemThread() 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  delete m_impl;
+}
+  
+  void 
+SystemThread::Start (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_impl->Start ();
+}
+  
+  void 
+SystemThread::Join (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_impl->Join ();
+}  
+
+} // namespace ns3
--- a/src/core/wscript	Wed Jul 16 10:45:13 2008 +0100
+++ b/src/core/wscript	Wed Jul 16 10:46:51 2008 +0100
@@ -21,9 +21,14 @@
     e.define = 'HAVE_SIGNAL_H'
     e.run()
 
-    conf.write_config_header('ns3/core-config.h')
+    e = conf.create_library_configurator()
+    e.mandatory = False
+    e.name = 'rt'
+    e.define = 'HAVE_RT'
+    e.uselib = 'RT'
+    e.run()
 
-
+    conf.write_config_header('ns3/core-config.h')
 
 def build(bld):
     core = bld.create_ns3_module('core')
@@ -60,6 +65,7 @@
         'trace-source-accessor.cc',
         'config.cc',
         ]
+    core.uselib = 'RT'
 
     if sys.platform == 'win32':
         core.source.extend([
@@ -67,12 +73,18 @@
             ])
     else:
         core.source.extend([
+            'unix-system-thread.cc',
+            'unix-system-mutex.cc',
+            'unix-system-condition.cc',
             'unix-system-wall-clock-ms.cc',
             ])
     
     headers = bld.create_obj('ns3header')
     headers.module = 'core'
     headers.source = [
+        'system-mutex.h',
+        'system-thread.h',
+        'system-condition.h',
         'system-wall-clock-ms.h',
         'empty.h',
         'callback.h',