diff --git a/src/mlpack/config.hpp b/src/mlpack/config.hpp index e538c5d219..a8a03c3c93 100644 --- a/src/mlpack/config.hpp +++ b/src/mlpack/config.hpp @@ -72,6 +72,15 @@ #define MLPACK_CERR_STREAM std::cerr #endif + +// +// MLPACK_NO_STD_MUTEX is used to disable mutex usage inside mlpack. Assuming +// the system has one core only. +// +#ifdef MLPACK_NO_STD_MUTEX + #define ARMA_DO_NOT_USE_STD_MUTEX +#endif + // // Perform autodetection of STB if possible. // diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 91598c3556..9923774f8b 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -269,8 +269,10 @@ class IO static util::Timers& GetTimers(); private: +#ifndef MLPACK_NO_STD_MUTEX //! Ensure only one thread can call Add() at a time to modify the map. std::mutex mapMutex; +#endif //! Map from alias values to names, for each binding name. std::map> aliases; //! Map of parameters, for each binding name. @@ -281,8 +283,10 @@ class IO void (*)(util::ParamData&, const void*, void*)>>; FunctionMapType functionMap; +#ifndef MLPACK_NO_STD_MUTEX //! Ensure only one thread can modify the docs map at a time. std::mutex docMutex; +#endif //! Map of binding details. std::map docs; diff --git a/src/mlpack/core/util/io_impl.hpp b/src/mlpack/core/util/io_impl.hpp index e1ddb6273e..0492f40616 100644 --- a/src/mlpack/core/util/io_impl.hpp +++ b/src/mlpack/core/util/io_impl.hpp @@ -81,7 +81,9 @@ inline void IO::AddParameter(const std::string& bindingName, } // Add the alias, if necessary. +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().mapMutex); +#endif if (data.alias != '\0') bindingAliases[data.alias] = data.name; @@ -99,7 +101,9 @@ inline void IO::AddFunction(const std::string& type, const std::string& name, void (*func)(util::ParamData&, const void*, void*)) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().mapMutex); +#endif GetSingleton().functionMap[type][name] = func; } @@ -112,7 +116,9 @@ inline void IO::AddFunction(const std::string& type, inline void IO::AddBindingName(const std::string& bindingName, const std::string& name) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().mapMutex); +#endif GetSingleton().docs[bindingName].name = name; } @@ -125,7 +131,9 @@ inline void IO::AddBindingName(const std::string& bindingName, inline void IO::AddShortDescription(const std::string& bindingName, const std::string& shortDescription) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().docMutex); +#endif GetSingleton().docs[bindingName].shortDescription = shortDescription; } @@ -139,7 +147,9 @@ inline void IO::AddLongDescription( const std::string& bindingName, const std::function& longDescription) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().docMutex); +#endif GetSingleton().docs[bindingName].longDescription = longDescription; } @@ -152,7 +162,9 @@ inline void IO::AddLongDescription( inline void IO::AddExample(const std::string& bindingName, const std::function& example) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().docMutex); +#endif GetSingleton().docs[bindingName].example.push_back(std::move(example)); } @@ -167,7 +179,9 @@ inline void IO::AddSeeAlso(const std::string& bindingName, const std::string& description, const std::string& link) { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(GetSingleton().docMutex); +#endif GetSingleton().docs[bindingName].seeAlso.push_back( std::make_pair(description, link)); } diff --git a/src/mlpack/core/util/timers.hpp b/src/mlpack/core/util/timers.hpp index 42d1fefd58..215f9c6e9b 100644 --- a/src/mlpack/core/util/timers.hpp +++ b/src/mlpack/core/util/timers.hpp @@ -19,7 +19,9 @@ #include #include #include +#ifndef MLPACK_NO_STD_MUTEX #include +#endif #include #include // std::thread is used for thread safety. @@ -169,8 +171,10 @@ class Timers private: //! A map of all the timers that are being tracked. std::map timers; +#ifndef MLPACK_NO_STD_MUTEX //! A mutex for modifying the timers. std::mutex timersMutex; +#endif //! A map for the starting values of the timers. std::map> timerStartTime; diff --git a/src/mlpack/core/util/timers_impl.hpp b/src/mlpack/core/util/timers_impl.hpp index 16de70c13f..a5d7c3cf86 100644 --- a/src/mlpack/core/util/timers_impl.hpp +++ b/src/mlpack/core/util/timers_impl.hpp @@ -74,15 +74,19 @@ namespace util { // Reset a Timers object. inline void Timers::Reset() { +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(timersMutex); +#endif timers.clear(); timerStartTime.clear(); } inline std::map Timers::GetAllTimers() { +#ifndef MLPACK_NO_STD_MUTEX // Make a copy of the timer. std::lock_guard lock(timersMutex); +#endif return timers; } @@ -91,7 +95,9 @@ inline std::chrono::microseconds Timers::Get(const std::string& timerName) if (!enabled) return std::chrono::microseconds(0); +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(timersMutex); +#endif return timers[timerName]; } @@ -166,7 +172,9 @@ inline void Timers::StopAllTimers() { // Terminate the program timers. Don't use StopTimer() since that modifies // the map and would invalidate our iterators. +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(timersMutex); +#endif std::chrono::high_resolution_clock::time_point currTime = std::chrono::high_resolution_clock::now(); @@ -191,7 +199,9 @@ inline void Timers::Start(const std::string& timerName, if (!enabled) return; +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(timersMutex); +#endif if ((timerStartTime.count(threadId) > 0) && (timerStartTime[threadId].count(timerName))) @@ -221,7 +231,9 @@ inline void Timers::Stop(const std::string& timerName, if (!enabled) return; +#ifndef MLPACK_NO_STD_MUTEX std::lock_guard lock(timersMutex); +#endif if ((timerStartTime.count(threadId) == 0) || (timerStartTime[threadId].count(timerName) == 0))