[Doxygen] OS functions: filesystem, threading, wall clock.

This commit is contained in:
Peter D. Barnes, Jr.
2014-12-09 13:17:49 -08:00
parent 846fd6a6d9
commit 345c8a94ac
13 changed files with 274 additions and 73 deletions

View File

@@ -158,7 +158,7 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
/**
* \ingroup attributehelper
*
* Declare the attribute value class \p <name>Value
* Declare the attribute value class \p \<name>Value
* for underlying class \p type.
*
* \param type The underlying type name
@@ -198,7 +198,7 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
/**
* \ingroup attributehelper
*
* Declare the attribute value class \p <Name>Value
* Declare the attribute value class \p \<Name>Value
* for the class \p Name
*
* \param Name the name of the class.
@@ -230,15 +230,15 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
/**
* \ingroup attributehelper
*
* Declare the AttributeChecker class \p <type>Checker
* Declare the AttributeChecker class \p \<type>Checker
* and the \c MakeTypeChecker function for class \p type.
*
* \param type the name of the class
*
* This macro declares the \p <type>Checker class and the associated
* This macro declares the \p \<type>Checker class and the associated
* \c MakeTypeChecker function.
*
* (Note that the \p <type>Checker class needs no implementation
* (Note that the \p \<type>Checker class needs no implementation
* since it just inherits all its implementation from AttributeChecker.)
*
* Typically invoked in the class header file.
@@ -252,15 +252,15 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
* \ingroup attributehelper
*
* Define the class methods belonging to
* the attribute value class \p <name>Value
* the attribute value class \p \<name>Value
* of the underlying class \p type.
*
* \param type The underlying type name
* \param name The token to use in defining the accessor name.
*
* This macro implements the \p <type>Value class methods
* (including the \p <type>Value::SerializeToString
* and \p <type>Value::DeserializeFromString methods).
* This macro implements the \p \<type>Value class methods
* (including the \p \<type>Value::SerializeToString
* and \p \<type>Value::DeserializeFromString methods).
*
* Typically invoked in the source file.
*/
@@ -297,13 +297,13 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
* \ingroup attributehelper
*
* Define the class methods belonging to
* attribute value class \p <type>Value for class \p type.
* attribute value class \p \<type>Value for class \p type.
*
* \param type the name of the class.
*
* This macro implements the \p <type>Value class methods
* (including the \p <type>Value::SerializeToString
* and \p <type>Value::DeserializeFromString methods).
* This macro implements the \p \<type>Value class methods
* (including the \p \<type>Value::SerializeToString
* and \p \<type>Value::DeserializeFromString methods).
*
* Typically invoked in the source file.
*/
@@ -356,11 +356,11 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
*
* This macro declares:
*
* - The attribute value class \p <type>Value,
* - The attribute value class \p \<type>Value,
*
* - The attribute accessor functions \c MakeTypeAccessor,
*
* - The AttributeChecker class \p <type>Checker
* - The AttributeChecker class \p \<type>Checker
* and the \c MakeTypeChecker function,
*
* for class \p type.
@@ -382,7 +382,7 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
*
* This macro implements
*
* - The \p <type>Value class methods,
* - The \p \<type>Value class methods,
*
* - The \c MakeTypeChecker function,
*

View File

@@ -21,11 +21,25 @@
#include "ptr.h"
namespace ns3 {
/**
* @file
* @ingroup thread
* System-independent thread conditional wait.
*/
namespace ns3 {
/**
* @ingroup system
* @defgroup thread Threading and Signaling.
*
* System-independent interfaces to threads, signal conditions, and mutex.
*/
class SystemConditionPrivate;
/**
* @ingroup thread
* @brief A class which provides a relatively platform-independent
* conditional-wait thread synchronization primitive.
*
@@ -61,7 +75,7 @@ public:
/**
* Set the value of the underlying condition.
* \param condition value
* @param condition value
*/
void SetCondition (bool condition);
@@ -92,12 +106,14 @@ public:
/**
* Wait a maximum of ns nanoseconds for the condition to be true. If the
* wait times out, return true else return false.
* \param ns maximum of nanoseconds to wait
* @param ns maximum of nanoseconds to wait
* @returns true if the timer expired, otherwise return false.
*/
bool TimedWait (uint64_t ns);
private:
/** The (system-dependent) implementation. */
SystemConditionPrivate * m_priv;
};

View File

@@ -23,11 +23,19 @@
#include "ptr.h"
/**
* @file
* @ingroup thread
* System-independent mutex primitive, ns3::SystemMutex,
* and ns3::CriticalSection.
*/
namespace ns3 {
class SystemMutexPrivate;
/**
* @ingroup thread
* @brief A class which provides a relatively platform-independent Mutual
* Exclusion thread synchronization primitive.
*
@@ -64,6 +72,7 @@ public:
void Unlock ();
private:
/** The (system-dependent) implementation. */
SystemMutexPrivate * m_priv;
};
@@ -73,32 +82,32 @@ private:
* When more than one SystemThread needs to access a shared resource, we
* control 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.
* operations on the shared SystemMutex 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);
* ...
* }
*
* @code
* Class::Method ()
* {
* CriticalSection cs (mutex);
* ...
* }
* @endcode
* 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 ()
* {
* ...
* @code
* Class::Method ()
* {
* CriticalSection cs (mutex);
* ...
* {
* CriticalSection cs (mutex);
* }
* ...
* }
* ...
* }
*
* @endcode
* 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
@@ -109,10 +118,16 @@ private:
class CriticalSection
{
public:
/**
* Construct with the required SystemMutex.
*
* @param [in] mutex The mutex.
*/
CriticalSection (SystemMutex &mutex);
/** Destructor */
~CriticalSection ();
private:
SystemMutex &m_mutex;
SystemMutex &m_mutex; /**< The mutex. */
};
} // namespace ns3

View File

@@ -25,12 +25,16 @@
#include <cstdlib>
#include <cerrno>
#include <cstring>
#if defined (HAVE_DIRENT_H) and defined (HAVE_SYS_TYPES_H)
/** Do we have an \c opendir function? */
#define HAVE_OPENDIR
#include <sys/types.h>
#include <dirent.h>
#endif
#if defined (HAVE_SYS_STAT_H) and defined (HAVE_SYS_TYPES_H)
/** Do we have a \c makedir function? */
#define HAVE_MKDIR_H
#include <sys/types.h>
#include <sys/stat.h>
@@ -49,12 +53,22 @@
#include <unistd.h>
#endif
/**
* \def SYSTEM_PATH_SEP
* System-specific path separator used between directory names.
*/
#if defined (__win32__)
#define SYSTEM_PATH_SEP "\\"
#else
#define SYSTEM_PATH_SEP "/"
#endif
/**
* \file
* \ingroup systempath
* System-independent file and directory function definitions.
*/
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("SystemPath");
@@ -313,6 +327,8 @@ void
MakeDirectories (std::string path)
{
NS_LOG_FUNCTION (path);
// Make sure all directories on the path exist
std::list<std::string> elements = Split (path);
for (std::list<std::string>::const_iterator i = elements.begin (); i != elements.end (); ++i)
{
@@ -324,11 +340,13 @@ MakeDirectories (std::string path)
}
#endif
}
// Make the final directory. Is this redundant with last iteration above?
#if defined(HAVE_MKDIR_H)
if (mkdir (path.c_str (), S_IRWXU))
{
NS_LOG_ERROR ("failed creating directory " << path);
}
if (mkdir (path.c_str (), S_IRWXU))
{
NS_LOG_ERROR ("failed creating directory " << path);
}
#endif
}

View File

@@ -23,10 +23,16 @@
#include <string>
#include <list>
/**
* \file
* \ingroup systempath
* System-independent file and directory function declarations.
*/
namespace ns3 {
/**
* \ingroup testing
* \ingroup system
* \defgroup systempath Host Filesystem
* \brief Encapsulate OS-specific functions to manipulate file
* and directory paths.
@@ -35,11 +41,6 @@ namespace ns3 {
* the ns-3 test framework.
*/
/**
* \addtogroup core
* \see systempath
*/
/**
* \ingroup systempath
* \brief Namespace for various file and directory path functions.
@@ -48,12 +49,16 @@ namespace SystemPath {
/**
* \ingroup systempath
* Get the file system path to the current executable.
*
* \return the directory in which the currently-executing binary is located
*/
std::string FindSelfDirectory (void);
/**
* \ingroup systempath
* Join two file system path elements.
*
* \param left a path element
* \param right a path element
* \return a concatenation of the two input paths
@@ -62,6 +67,11 @@ namespace SystemPath {
/**
* \ingroup systempath
* Split a file system path into directories according to
* the local path separator.
*
* This is the inverse of Join.
*
* \param path a path
* \return a list of path elements that can be joined together again with
* the Join function.
@@ -70,6 +80,11 @@ namespace SystemPath {
std::list<std::string> Split (std::string path);
/**
* Join a list of file system path directories into a single
* file system path.
*
* This is the inverse of Split.
*
* \ingroup systempath
* \param begin iterator to first element to join
* \param end iterator to last element to join
@@ -80,6 +95,8 @@ namespace SystemPath {
/**
* \ingroup systempath
* Get the list of files located in a file system directory.
*
* \param path a path which identifies a directory
* \return a list of the filenames which are located in the input directory
*/
@@ -87,19 +104,21 @@ namespace SystemPath {
/**
* \ingroup systempath
* \return a path which identifies a temporary directory.
* Get the name of a temporary directory.
*
* The returned path identifies a directory which does not exist yet
* The returned path identifies a directory which does not exist yet.
* Call ns3::SystemPath::MakeDirectories to create it. Yes, there is a
* well-known security race in this API but we don't care in ns-3.
*
* \return a path which identifies a temporary directory.
*/
std::string MakeTemporaryDirectoryName (void);
/**
* \ingroup systempath
* \param path a path to a directory
*
* Create all the directories leading to path.
*
* \param path a path to a directory
*/
void MakeDirectories (std::string path);

View File

@@ -23,6 +23,12 @@
#include "log.h"
#include <cstring>
/**
* @file
* @ingroup thread
* System-independent thread class ns3::SystemThread definitions.
*/
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("SystemThread");

View File

@@ -27,9 +27,16 @@
#include <pthread.h>
#endif /* HAVE_PTHREAD_H */
/**
* @file
* @ingroup thread
* System-independent thread class ns3::SystemThread declaration.
*/
namespace ns3 {
/**
* @ingroup thread
* @brief A class which provides a relatively platform-independent thread
* primitive.
*
@@ -43,12 +50,15 @@ namespace ns3 {
* execution.
*
* Synchronization between threads is provided via the SystemMutex class.
*
* See @ref main-test-sync.cc for example usage.
*/
class SystemThread : public SimpleRefCount<SystemThread>
{
public:
#ifdef HAVE_PTHREAD_H
/** Type alias for the system-dependent thread object. */
typedef pthread_t ThreadId;
#endif
@@ -67,36 +77,39 @@ public:
*
* 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,
*
* @code
* MyClass myObject;
* Ptr<SystemThread> st = Create<SystemThread> (
* MakeCallback (&MyClass::MyMethod, &myObject));
* st->Start ();
* @endcode
*
* 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
* @c MyClass::MyMethod. When this function is called, it is called as an
* object method on the @c myObject object. Essentially what you are doing
* is asking the SystemThread to call @c object->MyMethod() in a new thread
* of execution.
*
* If starting a thread in your currently executing object, you can use the
* "this" pointer:
*
* @code
* Ptr<SystemThread> st = Create<SystemThread> (
* MakeCallback (&MyClass::MyMethod, this));
* st->Start ();
* @endcode
*
* Object lifetime is always an issue with threads, so it is common to use
* smart pointers. If you are spinning up a thread in an object that is
* managed by a smart pointer, you can use that pointer directly:
*
* @code
* Ptr<MyClass> myPtr = Create<MyClass> ();
* Ptr<SystemThread> st = Create<SystemThread> (
* MakeCallback (&MyClass::MyMethod, myPtr));
* st->Start ();
* @endcode
*
* 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
* method provided to do this is Join(). If you call Join() you will block
* until the SystemThread run method returns.
*
* @param callback entry point of the thread
@@ -136,18 +149,25 @@ public:
static ThreadId Self(void);
/**
* @brief Compares an TharedId with the current ThreadId .
* @brief Compares an ThreadId with the current ThreadId .
*
* @returns true if Id matches the current ThreadId.
* @param [in] id The ThreadId to compare to.
* @returns true if @c id matches the current ThreadId.
*/
static bool Equals(ThreadId id);
private:
#ifdef HAVE_PTHREAD_H
/**
* Invoke the callback in the new thread.
*
* @param [in] arg This SystemThread instance to communicate to the newly
* launched thread.
*/
static void *DoRun (void *arg);
Callback<void> m_callback;
pthread_t m_thread;
Callback<void> m_callback; /**< The main function for this thread when launched. */
pthread_t m_thread; /**< The thread id of the child thread. */
#endif
};

View File

@@ -23,14 +23,31 @@
#include <stdint.h>
/**
* \file
* \ingroup system
* System-independent wall clock class ns3::SystemWallClockMs declaration.
*/
namespace ns3 {
/**
* \addtogroup core
* \see SystemWallClockMs
* @ingroup core
* @defgroup system System Services
*
* System-independent interfaces to operating system services:
* files system, threading, wall clock time.
*
* Services provided:
*
* - File and directory paths.
* - Thread primitives: threads, conditional waits, mutex, critical sections.
* - Asynchronous input from a file descriptor.
* - Wall clock time.
*/
/**
* \ingroup testing
* \ingroup system
* \brief Measure elapsed wall clock time in milliseconds.
*/
class SystemWallClockMs {

View File

@@ -27,9 +27,16 @@
#include "system-thread.h"
#include "event-id.h"
/**
* \ingroup system
* \file
* Asynchronous reads from a file descriptor, which trigger a Callback.
*/
namespace ns3 {
/**
* \ingroup system
* \brief A class that asynchronously reads from a file descriptor.
*
* This class can be used to start a system thread that reads from a
@@ -40,7 +47,9 @@ namespace ns3 {
class FdReader : public SimpleRefCount<FdReader>
{
public:
/** Constructor. */
FdReader();
/** Destructor. */
virtual ~FdReader();
/**
@@ -66,9 +75,18 @@ protected:
*/
struct Data
{
/** Default constructor, with null buffer and zero length. */
Data () : m_buf (0), m_len (0) {}
/**
* Construct from a buffer of a given length.
*
* \param buf The buffer.
* \param len The size of the buffer, in bytes.
*/
Data (uint8_t *buf, ssize_t len) : m_buf (buf), m_len (len) {}
/** The read data buffer. */
uint8_t *m_buf;
/** The size of the read data buffer, in bytes. */
ssize_t m_len;
};
@@ -94,13 +112,26 @@ protected:
private:
/** The asynchronous function which performs the read. */
void Run (void);
/** Event handler scheduled for destroy time to halt the thread. */
void DestroyEvent (void);
/** The main thread callback function to invoke when we have data. */
Callback<void, uint8_t *, ssize_t> m_readCallback;
/** The thread doing the read, created and launched by Start(). */
Ptr<SystemThread> m_readThread;
int m_evpipe[2]; // pipe used to signal events between threads
bool m_stop; // true means the read thread should stop
/** Pipe used to signal events between threads. */
int m_evpipe[2];
/** Signal the read thread to stop. */
bool m_stop;
/**
* The event scheduled for destroy time which will invoke DestroyEvent
* and halt the thread.
*/
EventId m_destroyEvent;
};

View File

@@ -25,28 +25,66 @@
#include "log.h"
/**
* \file
* \ingroup thread
* Thread conditional wait implementation for Unix-like systems.
*/
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("SystemCondition");
/**
* \ingroup thread
* Implementation of SystemCondition for Unix-like systems.
*/
class SystemConditionPrivate {
public:
/// Conversion from ns to s.
static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
/** Constructor. */
SystemConditionPrivate ();
/** Destructor. */
~SystemConditionPrivate ();
/**
* Set the condition.
*
* \param condition The new condition value.
*/
void SetCondition (bool condition);
/**
* Get the condition value.
*
* \returns The condition value.
*/
bool GetCondition (void);
/** Signal the condition. */
void Signal (void);
/** Broadcast the condition. */
void Broadcast (void);
/**
* Unset the condition, then wait for another thread
* to set it with SetCondition. */
void Wait (void);
/**
* Unset the condition, then wait for a limited amount of wall-clock
* time for another thread to set it with SetCondition.
*
* \param ns Maximum time to wait, in ns.
* \returns \c true if the condition timed out; \c false if the other
* thread set it.
*/
bool TimedWait (uint64_t ns);
private:
/** Mutex controlling access to the condition. */
pthread_mutex_t m_mutex;
/** The pthread condition variable. */
pthread_cond_t m_cond;
/** The condition state. */
bool m_condition;
};

View File

@@ -27,19 +27,26 @@
#include "log.h"
/**
* @file
* @ingroup thread
* Mutex critical section primitive definitions for Unix-like systems.
*/
namespace ns3 {
NS_LOG_COMPONENT_DEFINE_MASK ("SystemMutex", ns3::LOG_PREFIX_TIME);
/** System-dependent implementation of SystemMutex. */
class SystemMutexPrivate {
public:
SystemMutexPrivate ();
SystemMutexPrivate ();
~SystemMutexPrivate ();
void Lock (void);
void Unlock (void);
void Lock (void); /**< Acquire ownership of the mutex. */
void Unlock (void); /**< Release ownership of the mutex. */
private:
pthread_mutex_t m_mutex;
pthread_mutex_t m_mutex; /**< The mutex. */
};
SystemMutexPrivate::SystemMutexPrivate ()

View File

@@ -24,12 +24,19 @@
#include <sys/times.h>
#include <unistd.h>
/**
* \file
* \ingroup system
* Wall clock class ns3::SystemWallClockMs implementation
* for Unix-like systems.
*/
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("SystemWallClockMsPrivate");
/**
* \ingroup testingimpl
* \ingroup system
* \brief System-dependent implementation for SystemWallClockMs
*/
class SystemWallClockMsPrivate {

View File

@@ -22,10 +22,17 @@
#include <ctime>
/**
* \file
* \ingroup system
* Wall clock class ns3::SystemWallClockMs implementation
* for Windows-32 systems.
*/
namespace ns3 {
/**
* \ingroup testingimpl
* \ingroup system
* \brief System-dependent implementation for SystemWallClockMs
*/
class SystemWallClockMsPrivate {