diff --git a/src/core/model/default-simulator-impl.cc b/src/core/model/default-simulator-impl.cc index c342c89e2..c88777efd 100644 --- a/src/core/model/default-simulator-impl.cc +++ b/src/core/model/default-simulator-impl.cc @@ -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; } diff --git a/src/core/model/default-simulator-impl.h b/src/core/model/default-simulator-impl.h index 473dac89b..8c6bc13f2 100644 --- a/src/core/model/default-simulator-impl.h +++ b/src/core/model/default-simulator-impl.h @@ -23,9 +23,9 @@ #include "simulator-impl.h" #include "system-thread.h" -#include "system-mutex.h" #include +#include /** * \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 DestroyEvents; diff --git a/src/core/model/des-metrics.cc b/src/core/model/des-metrics.cc index 2e2701c95..343b50ab9 100644 --- a/src/core/model/des-metrics.cc +++ b/src/core/model/des-metrics.cc @@ -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 (); } diff --git a/src/core/model/des-metrics.h b/src/core/model/des-metrics.h index abe8d1c03..9ec905a09 100644 --- a/src/core/model/des-metrics.h +++ b/src/core/model/des-metrics.h @@ -29,10 +29,10 @@ #include "nstime.h" #include "singleton.h" -#include "system-mutex.h" #include // uint32_t #include +#include #include #include @@ -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 diff --git a/src/core/model/realtime-simulator-impl.cc b/src/core/model/realtime-simulator-impl.cc index e4bb08703..03b94a4ea 100644 --- a/src/core/model/realtime-simulator-impl.cc +++ b/src/core/model/realtime-simulator-impl.cc @@ -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 - +#include /** * \file @@ -146,7 +145,7 @@ RealtimeSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory) Ptr scheduler = schedulerFactory.Create (); { - 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 (); diff --git a/src/core/model/realtime-simulator-impl.h b/src/core/model/realtime-simulator-impl.h index 962fa603a..afd4db57f 100644 --- a/src/core/model/realtime-simulator-impl.h +++ b/src/core/model/realtime-simulator-impl.h @@ -29,9 +29,9 @@ #include "ptr.h" #include "assert.h" #include "log.h" -#include "system-mutex.h" #include +#include /** * \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 m_synchronizer; diff --git a/src/core/model/system-mutex.h b/src/core/model/system-mutex.h deleted file mode 100644 index 974dc43ad..000000000 --- a/src/core/model/system-mutex.h +++ /dev/null @@ -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 - */ - -#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 */ diff --git a/src/core/model/time.cc b/src/core/model/time.cc index ecc54e83f..13bf8711c 100644 --- a/src/core/model/time.cc +++ b/src/core/model/time.cc @@ -21,10 +21,10 @@ */ #include "nstime.h" #include "abort.h" -#include "system-mutex.h" #include "log.h" #include // pow #include // showpos +#include #include /** @@ -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 (); diff --git a/src/core/model/unix-system-mutex.cc b/src/core/model/unix-system-mutex.cc deleted file mode 100644 index 41d6d5473..000000000 --- a/src/core/model/unix-system-mutex.cc +++ /dev/null @@ -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 - */ - -#include -#include -#include // 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 diff --git a/src/fd-net-device/model/dpdk-net-device.cc b/src/fd-net-device/model/dpdk-net-device.cc index 3d2b4c42b..4a999cacf 100644 --- a/src/fd-net-device/model/dpdk-net-device.cc +++ b/src/fd-net-device/model/dpdk-net-device.cc @@ -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 @@ -33,6 +32,7 @@ #include #include +#include #include #include @@ -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 ()) { diff --git a/src/fd-net-device/model/fd-net-device.cc b/src/fd-net-device/model/fd-net-device.cc index d83a9e6fe..dfa3f851a 100644 --- a/src/fd-net-device/model/fd-net-device.cc +++ b/src/fd-net-device/model/fd-net-device.cc @@ -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 next = m_pendingQueue.front (); m_pendingQueue.pop (); diff --git a/src/fd-net-device/model/fd-net-device.h b/src/fd-net-device/model/fd-net-device.h index 368bd0242..99cc80d28 100644 --- a/src/fd-net-device/model/fd-net-device.h +++ b/src/fd-net-device/model/fd-net-device.h @@ -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 #include #include @@ -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.