core: Replace SystemMutex and CriticalSection classes with STL

This commit is contained in:
Eduardo Almeida
2021-12-14 17:15:59 +00:00
parent a387d0cd1e
commit b32c80ecb0
12 changed files with 37 additions and 338 deletions

View File

@@ -166,7 +166,7 @@ DefaultSimulatorImpl::ProcessEventsWithContext (void)
// swap queues
EventsWithContext eventsWithContext;
{
CriticalSection cs (m_eventsWithContextMutex);
std::unique_lock lock {m_eventsWithContextMutex};
m_eventsWithContext.swap (eventsWithContext);
m_eventsWithContextEmpty = true;
}
@@ -266,7 +266,7 @@ DefaultSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &delay,
ev.timestamp = delay.GetTimeStep ();
ev.event = event;
{
CriticalSection cs (m_eventsWithContextMutex);
std::unique_lock lock {m_eventsWithContextMutex};
m_eventsWithContext.push_back (ev);
m_eventsWithContextEmpty = false;
}

View File

@@ -23,9 +23,9 @@
#include "simulator-impl.h"
#include "system-thread.h"
#include "system-mutex.h"
#include <list>
#include <mutex>
/**
* \file
@@ -106,7 +106,7 @@ private:
*/
bool m_eventsWithContextEmpty;
/** Mutex to control access to the list of events with context. */
SystemMutex m_eventsWithContextMutex;
std::mutex m_eventsWithContextMutex;
/** Container type for the events to run at Simulator::Destroy() */
typedef std::list<EventId> DestroyEvents;

View File

@@ -131,7 +131,7 @@ DesMetrics::TraceWithContext (uint32_t context, const Time & now, const Time & d
<< (now + delay).GetTimeStep () << "\"]";
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
m_os << ss.str ();
}

View File

@@ -29,10 +29,10 @@
#include "nstime.h"
#include "singleton.h"
#include "system-mutex.h"
#include <stdint.h> // uint32_t
#include <fstream>
#include <mutex>
#include <string>
#include <vector>
@@ -160,7 +160,7 @@ private:
char m_separator; //!< The separator between event records.
/** Mutex to control access to the output file. */
SystemMutex m_mutex;
std::mutex m_mutex;
}; // class DesMetrics

View File

@@ -28,13 +28,12 @@
#include "assert.h"
#include "fatal-error.h"
#include "log.h"
#include "system-mutex.h"
#include "boolean.h"
#include "enum.h"
#include <cmath>
#include <mutex>
/**
* \file
@@ -146,7 +145,7 @@ RealtimeSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
if (m_events != 0)
{
@@ -203,7 +202,7 @@ RealtimeSimulatorImpl::ProcessOneEvent (void)
uint64_t tsNow;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
//
// Since we are in realtime mode, the time to delay has got to be the
// difference between the current realtime and the timestamp of the next
@@ -314,7 +313,7 @@ RealtimeSimulatorImpl::ProcessOneEvent (void)
Scheduler::Event next;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
//
// We do know we're waiting for an event, so there had better be an event on the
@@ -399,7 +398,7 @@ RealtimeSimulatorImpl::IsFinished (void) const
{
bool rc;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
rc = m_events->IsEmpty () || m_stop;
}
@@ -441,7 +440,7 @@ RealtimeSimulatorImpl::Run (void)
{
bool process = false;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
if (!m_events->IsEmpty ())
{
@@ -471,7 +470,7 @@ RealtimeSimulatorImpl::Run (void)
// consistency test to check that we didn't lose any events along the way.
//
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
NS_ASSERT_MSG (m_events->IsEmpty () == false || m_unscheduledEvents == 0,
"RealtimeSimulatorImpl::Run(): Empty queue and unprocessed events");
@@ -516,7 +515,7 @@ RealtimeSimulatorImpl::Schedule (Time const &delay, EventImpl *impl)
Scheduler::Event ev;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
//
// This is the reason we had to bring the absolute time calculation in from the
// simulator.h into the implementation. Since the implementations may be
@@ -544,7 +543,7 @@ RealtimeSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &delay,
NS_LOG_FUNCTION (this << context << delay << impl);
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
uint64_t ts;
if (SystemThread::Equals (m_main))
@@ -596,7 +595,7 @@ RealtimeSimulatorImpl::ScheduleRealtimeWithContext (uint32_t context, Time const
NS_LOG_FUNCTION (this << context << time << impl);
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
uint64_t ts = m_synchronizer->GetCurrentRealtime () + time.GetTimeStep ();
NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtime(): schedule for time < m_currentTs");
@@ -623,7 +622,7 @@ RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext (uint32_t context, EventIm
{
NS_LOG_FUNCTION (this << context << impl);
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
//
// If the simulator is running, we're pacing and have a meaningful
@@ -664,7 +663,7 @@ RealtimeSimulatorImpl::ScheduleDestroy (EventImpl *impl)
EventId id;
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
//
// Time doesn't really matter here (especially in realtime mode). It is
@@ -719,7 +718,7 @@ RealtimeSimulatorImpl::Remove (const EventId &id)
}
{
CriticalSection cs (m_mutex);
std::unique_lock lock {m_mutex};
Scheduler::Event event;
event.impl = id.PeekEventImpl ();

View File

@@ -29,9 +29,9 @@
#include "ptr.h"
#include "assert.h"
#include "log.h"
#include "system-mutex.h"
#include <list>
#include <mutex>
/**
* \file
@@ -218,7 +218,7 @@ private:
/**@}*/
/** Mutex to control access to key state. */
mutable SystemMutex m_mutex;
mutable std::mutex m_mutex;
/** The synchronizer in use to track real time. */
Ptr<Synchronizer> m_synchronizer;

View File

@@ -1,136 +0,0 @@
/* -*- 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"
/**
* @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.
*
* 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 platform-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:
/** The (system-dependent) implementation. */
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
* control access by acquiring a SystemMutex. The CriticalSection class uses
* the C++ scoping rules to automatically perform the required Lock and Unlock
* 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,
* @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.
* @code
* Class::Method ()
* {
* ...
* {
* 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
* scope at the end of block.
*
* @see SystemMutex
*/
class CriticalSection
{
public:
/**
* Construct with the required SystemMutex.
*
* @param [in] mutex The mutex.
*/
CriticalSection (SystemMutex &mutex);
/** Destructor */
~CriticalSection ();
private:
SystemMutex &m_mutex; /**< The mutex. */
};
} // namespace ns3
#endif /* SYSTEM_MUTEX_H */

View File

@@ -21,10 +21,10 @@
*/
#include "nstime.h"
#include "abort.h"
#include "system-mutex.h"
#include "log.h"
#include <cmath> // pow
#include <iomanip> // showpos
#include <mutex>
#include <sstream>
/**
@@ -88,21 +88,8 @@ namespace {
// static
Time::MarkedTimes * Time::g_markingTimes = 0;
/**
* \internal
* Get mutex for critical sections around modification of Time::g_markingTimes
*
* \returns The static mutex to control access to Time::g_markingTimes.
*
* \relates Time
*/
SystemMutex &
GetMarkingMutex ()
{
static SystemMutex g_markingMutex;
return g_markingMutex;
}
/// The static mutex for critical sections around modification of Time::g_markingTimes.
static std::mutex g_markingMutex;
// Function called to force static initialization
// static
@@ -110,7 +97,7 @@ bool Time::StaticInit ()
{
static bool firstTime = true;
CriticalSection critical (GetMarkingMutex ());
std::unique_lock lock {g_markingMutex};
if (firstTime)
{
@@ -307,14 +294,13 @@ Time::ClearMarkedTimes ()
*
* It would seem natural to use this function at the end of
* ConvertTimes, but that function already has the mutex.
* Our SystemMutex throws a fatal error if we try to lock it more than
* once in the same thread (at least in the unix implementation),
* The mutex can not be locked more than once in the same thread,
* so calling this function from ConvertTimes is a bad idea.
*
* Instead, we copy this body into ConvertTimes.
*/
CriticalSection critical (GetMarkingMutex ());
std::unique_lock lock {g_markingMutex};
NS_LOG_FUNCTION_NOARGS ();
if (g_markingTimes)
@@ -330,7 +316,7 @@ Time::ClearMarkedTimes ()
void
Time::Mark (Time * const time)
{
CriticalSection critical (GetMarkingMutex ());
std::unique_lock lock {g_markingMutex};
NS_LOG_FUNCTION (time);
NS_ASSERT (time != 0);
@@ -356,7 +342,7 @@ Time::Mark (Time * const time)
void
Time::Clear (Time * const time)
{
CriticalSection critical (GetMarkingMutex ());
std::unique_lock lock {g_markingMutex};
NS_LOG_FUNCTION (time);
NS_ASSERT (time != 0);
@@ -386,7 +372,7 @@ Time::Clear (Time * const time)
void
Time::ConvertTimes (const enum Unit unit)
{
CriticalSection critical (GetMarkingMutex ());
std::unique_lock lock {g_markingMutex};
NS_LOG_FUNCTION_NOARGS ();

View File

@@ -1,150 +0,0 @@
/* -*- 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 <cstring>
#include <cerrno> // for strerror
#include "fatal-error.h"
#include "system-mutex.h"
#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 ();
void Lock (void); /**< Acquire ownership of the mutex. */
void Unlock (void); /**< Release ownership of the mutex. */
private:
pthread_mutex_t m_mutex; /**< The mutex. */
};
SystemMutexPrivate::SystemMutexPrivate ()
{
NS_LOG_FUNCTION (this);
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.
//
// Linux and OS X (at least) have, of course chosen different names for the
// error checking flags just to make life difficult.
//
#if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
#else
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
pthread_mutex_init (&m_mutex, &attr);
}
SystemMutexPrivate::~SystemMutexPrivate ()
{
NS_LOG_FUNCTION (this);
pthread_mutex_destroy (&m_mutex);
}
void
SystemMutexPrivate::Lock (void)
{
NS_LOG_FUNCTION (this);
int rc = pthread_mutex_lock (&m_mutex);
if (rc != 0)
{
NS_FATAL_ERROR ("SystemMutexPrivate::Lock()"
"pthread_mutex_lock failed: " << rc << " = \"" <<
std::strerror (rc) << "\"");
}
}
void
SystemMutexPrivate::Unlock (void)
{
NS_LOG_FUNCTION (this);
int rc = pthread_mutex_unlock (&m_mutex);
if (rc != 0)
{
NS_FATAL_ERROR ("SystemMutexPrivate::Unlock()"
"pthread_mutex_unlock failed: " << rc << " = \"" <<
std::strerror (rc) << "\"");
}
}
SystemMutex::SystemMutex ()
: m_priv (new SystemMutexPrivate ())
{
NS_LOG_FUNCTION (this);
}
SystemMutex::~SystemMutex ()
{
NS_LOG_FUNCTION (this);
delete m_priv;
}
void
SystemMutex::Lock ()
{
NS_LOG_FUNCTION (this);
m_priv->Lock ();
}
void
SystemMutex::Unlock ()
{
NS_LOG_FUNCTION (this);
m_priv->Unlock ();
}
CriticalSection::CriticalSection (SystemMutex &mutex)
: m_mutex (mutex)
{
NS_LOG_FUNCTION (this << &mutex);
m_mutex.Lock ();
}
CriticalSection::~CriticalSection ()
{
NS_LOG_FUNCTION (this);
m_mutex.Unlock ();
}
} // namespace ns3

View File

@@ -25,7 +25,6 @@
#include "ns3/log.h"
#include "ns3/net-device-queue-interface.h"
#include "ns3/simulator.h"
#include "ns3/system-mutex.h"
#include "ns3/uinteger.h"
#include <sys/ioctl.h>
@@ -33,6 +32,7 @@
#include <sys/signal.h>
#include <unistd.h>
#include <mutex>
#include <poll.h>
#include <rte_eal.h>
@@ -474,7 +474,7 @@ DpdkNetDevice::Write (uint8_t *buffer, size_t length)
void
DpdkNetDevice::DoFinishStoppingDevice (void)
{
CriticalSection cs (m_pendingReadMutex);
std::unique_lock lock {m_pendingReadMutex};
while (!m_pendingQueue.empty ())
{

View File

@@ -313,7 +313,7 @@ FdNetDevice::ReceiveCallback (uint8_t *buf, ssize_t len)
bool skip = false;
{
CriticalSection cs (m_pendingReadMutex);
std::unique_lock lock {m_pendingReadMutex};
if (m_pendingQueue.size () >= m_maxPendingReads)
{
NS_LOG_WARN ("Packet dropped");
@@ -429,7 +429,7 @@ FdNetDevice::ForwardUp (void)
}
{
CriticalSection cs (m_pendingReadMutex);
std::unique_lock lock {m_pendingReadMutex};
std::pair<uint8_t *, ssize_t> next = m_pendingQueue.front ();
m_pendingQueue.pop ();

View File

@@ -34,8 +34,8 @@
#include "ns3/system-condition.h"
#include "ns3/traced-callback.h"
#include "ns3/unix-fd-reader.h"
#include "ns3/system-mutex.h"
#include <mutex>
#include <utility>
#include <queue>
@@ -236,7 +236,7 @@ protected:
/**
* Mutex to increase pending read counter.
*/
SystemMutex m_pendingReadMutex;
std::mutex m_pendingReadMutex;
/**
* Number of packets that were received and scheduled for read but not yet read.