Merge remote-tracking branch 'upstream/3.4' into merge-3.4
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 29 Oct 2019 20:46:51 +0000 (20:46 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 29 Oct 2019 20:46:51 +0000 (20:46 +0000)
1  2 
modules/core/include/opencv2/core/private.hpp
modules/core/include/opencv2/core/utility.hpp
modules/core/include/opencv2/core/utils/tls.hpp
modules/core/src/ocl.cpp
modules/core/src/precomp.hpp
modules/core/src/rand.cpp
modules/core/src/system.cpp
modules/core/src/umatrix.cpp
modules/imgproc/src/histogram.cpp
modules/objdetect/src/hog.cpp

@@@ -697,59 -673,35 +673,11 @@@ void Mat::forEach_impl(const Functor& o
  
  /////////////////////////// Synchronization Primitives ///////////////////////////////
  
 -class CV_EXPORTS Mutex
 -{
 -public:
 -    Mutex();
 -    ~Mutex();
 -    Mutex(const Mutex& m);
 -    Mutex& operator = (const Mutex& m);
 -
 -    void lock();
 -    bool trylock();
 -    void unlock();
 -
 -    struct Impl;
 -protected:
 -    Impl* impl;
 -};
 -
 -class CV_EXPORTS AutoLock
 -{
 -public:
 -    AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); }
 -    ~AutoLock() { mutex->unlock(); }
 -protected:
 -    Mutex* mutex;
 -private:
 -    AutoLock(const AutoLock&);
 -    AutoLock& operator = (const AutoLock&);
 -};
 +#if !defined(_M_CEE)
 +typedef std::recursive_mutex Mutex;
 +typedef std::lock_guard<cv::Mutex> AutoLock;
 +#endif
  
- // TLS interface
- class CV_EXPORTS TLSDataContainer
- {
- protected:
-     TLSDataContainer();
-     virtual ~TLSDataContainer();
-     void  gatherData(std::vector<void*> &data) const;
-     void* getData() const;
-     void  release();
- private:
-     virtual void* createDataInstance() const = 0;
-     virtual void  deleteDataInstance(void* pData) const = 0;
-     int key_;
- public:
-     void cleanup(); //! Release created TLS data container objects. It is similar to release() call, but it keeps TLS container valid.
- };
- // Main TLS data class
- template <typename T>
- class TLSData : protected TLSDataContainer
- {
- public:
-     inline TLSData()        {}
-     inline ~TLSData()       { release();            } // Release key and delete associated data
-     inline T* get() const   { return (T*)getData(); } // Get data associated with key
-     inline T& getRef() const { T* ptr = (T*)getData(); CV_Assert(ptr); return *ptr; } // Get data associated with key
-     // Get data from all threads
-     inline void gather(std::vector<T*> &data) const
-     {
-         std::vector<void*> &dataVoid = reinterpret_cast<std::vector<void*>&>(data);
-         gatherData(dataVoid);
-     }
-     inline void cleanup() { TLSDataContainer::cleanup(); }
- private:
-     virtual void* createDataInstance() const CV_OVERRIDE {return new T;}                // Wrapper to allocate data by template
-     virtual void  deleteDataInstance(void* pData) const CV_OVERRIDE {delete (T*)pData;} // Wrapper to release data by template
-     // Disable TLS copy operations
-     TLSData(TLSData &) {}
-     TLSData& operator =(const TLSData &) {return *this;}
- };
  
  /** @brief Designed for command line parsing
  
@@@ -1315,4 -1194,15 +1161,11 @@@ CV_EXPORTS int getThreadID()
  
  } //namespace cv
  
 -#ifndef DISABLE_OPENCV_24_COMPATIBILITY
 -#include "opencv2/core/core_c.h"
 -#endif
 -
+ #ifdef CV_COLLECT_IMPL_DATA
+ #include "opencv2/core/utils/instrumentation.hpp"
+ #else
+ /// Collect implementation data on OpenCV function call. Requires ENABLE_IMPL_COLLECTION build option.
+ #define CV_IMPL_ADD(impl)
+ #endif
  #endif //OPENCV_CORE_UTILITY_H
index 0000000,b5f1138..697a7b0
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,237 +1,233 @@@
 -#if OPENCV_ABI_COMPATIBILITY > 300
+ // This file is part of OpenCV project.
+ // It is subject to the license terms in the LICENSE file found in the top-level directory
+ // of this distribution and at http://opencv.org/license.html.
+ #ifndef OPENCV_UTILS_TLS_HPP
+ #define OPENCV_UTILS_TLS_HPP
+ #include <opencv2/core/utility.hpp>
+ namespace cv {
+ //! @addtogroup core_utils
+ //! @{
+ namespace details { class TlsStorage; }
+ /** TLS container base implementation
+  *
+  * Don't use directly.
+  *
+  * @sa TLSData, TLSDataAccumulator templates
+  */
+ class CV_EXPORTS TLSDataContainer
+ {
+ protected:
+     TLSDataContainer();
+     virtual ~TLSDataContainer();
+     /// @deprecated use detachData() instead
+     void  gatherData(std::vector<void*> &data) const;
+     /// get TLS data and detach all data from threads (similar to cleanup() call)
+     void  detachData(std::vector<void*>& data);
+     void* getData() const;
+     void  release();
+ protected:
+     virtual void* createDataInstance() const = 0;
+     virtual void  deleteDataInstance(void* pData) const = 0;
 -#else
 -public:
 -#endif
+ private:
 -    TLSDataContainer(TLSDataContainer &);
 -    TLSDataContainer& operator =(const TLSDataContainer &);
+     int key_;
+     friend class cv::details::TlsStorage;  // core/src/system.cpp
+ public:
+     void cleanup(); //!< Release created TLS data container objects. It is similar to release() call, but it keeps TLS container valid.
+ private:
+     // Disable copy/assign (noncopyable pattern)
++    TLSDataContainer(TLSDataContainer &) = delete;
++    TLSDataContainer& operator =(const TLSDataContainer &) = delete;
+ };
+ /** @brief Simple TLS data class
+  *
+  * @sa TLSDataAccumulator
+  */
+ template <typename T>
+ class TLSData : protected TLSDataContainer
+ {
+ public:
+     inline TLSData() {}
+     inline ~TLSData() { release(); }
+     inline T* get() const   { return (T*)getData(); }  //!< Get data associated with key
+     inline T& getRef() const { T* ptr = (T*)getData(); CV_DbgAssert(ptr); return *ptr; }  //!< Get data associated with key
+     /// Release associated thread data
+     inline void cleanup()
+     {
+         TLSDataContainer::cleanup();
+     }
+ protected:
+     /// Wrapper to allocate data by template
+     virtual void* createDataInstance() const CV_OVERRIDE { return new T; }
+     /// Wrapper to release data by template
+     virtual void  deleteDataInstance(void* pData) const CV_OVERRIDE { delete (T*)pData; }
+ };
+ /// TLS data accumulator with gathering methods
+ template <typename T>
+ class TLSDataAccumulator : public TLSData<T>
+ {
+     mutable cv::Mutex mutex;
+     mutable std::vector<T*> dataFromTerminatedThreads;
+     std::vector<T*> detachedData;
+     bool cleanupMode;
+ public:
+     TLSDataAccumulator() : cleanupMode(false) {}
+     ~TLSDataAccumulator()
+     {
+         release();
+     }
+     /** @brief Get data from all threads
+      * @deprecated replaced by detachData()
+      *
+      * Lifetime of vector data is valid until next detachData()/cleanup()/release() calls
+      *
+      * @param[out] data result buffer (should be empty)
+      */
+     void gather(std::vector<T*> &data) const
+     {
+         CV_Assert(cleanupMode == false);  // state is not valid
+         CV_Assert(data.empty());
+         {
+             std::vector<void*> &dataVoid = reinterpret_cast<std::vector<void*>&>(data);
+             TLSDataContainer::gatherData(dataVoid);
+         }
+         {
+             AutoLock lock(mutex);
+             data.reserve(data.size() + dataFromTerminatedThreads.size());
+             for (typename std::vector<T*>::const_iterator i = dataFromTerminatedThreads.begin(); i != dataFromTerminatedThreads.end(); ++i)
+             {
+                 data.push_back((T*)*i);
+             }
+         }
+     }
+     /** @brief Get and detach data from all threads
+      *
+      * Call cleanupDetachedData() when returned vector is not needed anymore.
+      *
+      * @return Vector with associated data. Content is preserved (including lifetime of attached data pointers) until next detachData()/cleanupDetachedData()/cleanup()/release() calls
+      */
+     std::vector<T*>& detachData()
+     {
+         CV_Assert(cleanupMode == false);  // state is not valid
+         std::vector<void*> dataVoid;
+         {
+             TLSDataContainer::detachData(dataVoid);
+         }
+         {
+             AutoLock lock(mutex);
+             detachedData.reserve(dataVoid.size() + dataFromTerminatedThreads.size());
+             for (typename std::vector<T*>::const_iterator i = dataFromTerminatedThreads.begin(); i != dataFromTerminatedThreads.end(); ++i)
+             {
+                 detachedData.push_back((T*)*i);
+             }
+             dataFromTerminatedThreads.clear();
+             for (typename std::vector<void*>::const_iterator i = dataVoid.begin(); i != dataVoid.end(); ++i)
+             {
+                 detachedData.push_back((T*)(void*)*i);
+             }
+         }
+         dataVoid.clear();
+         return detachedData;
+     }
+     /// Release associated thread data returned by detachData() call
+     void cleanupDetachedData()
+     {
+         AutoLock lock(mutex);
+         cleanupMode = true;
+         _cleanupDetachedData();
+         cleanupMode = false;
+     }
+     /// Release associated thread data
+     void cleanup()
+     {
+         cleanupMode = true;
+         TLSDataContainer::cleanup();
+         AutoLock lock(mutex);
+         _cleanupDetachedData();
+         _cleanupTerminatedData();
+         cleanupMode = false;
+     }
+     /// Release associated thread data and free TLS key
+     void release()
+     {
+         cleanupMode = true;
+         TLSDataContainer::release();
+         {
+             AutoLock lock(mutex);
+             _cleanupDetachedData();
+             _cleanupTerminatedData();
+         }
+     }
+ protected:
+     // synchronized
+     void _cleanupDetachedData()
+     {
+         for (typename std::vector<T*>::iterator i = detachedData.begin(); i != detachedData.end(); ++i)
+         {
+             deleteDataInstance((T*)*i);
+         }
+         detachedData.clear();
+     }
+     // synchronized
+     void _cleanupTerminatedData()
+     {
+         for (typename std::vector<T*>::iterator i = dataFromTerminatedThreads.begin(); i != dataFromTerminatedThreads.end(); ++i)
+         {
+             deleteDataInstance((T*)*i);
+         }
+         dataFromTerminatedThreads.clear();
+     }
+ protected:
+     virtual void* createDataInstance() const CV_OVERRIDE
+     {
+         // Note: we can collect all allocated data here, but this would require raced mutex locks
+         return new T;
+     }
+     virtual void  deleteDataInstance(void* pData) const CV_OVERRIDE
+     {
+         if (cleanupMode)
+         {
+             delete (T*)pData;
+         }
+         else
+         {
+             AutoLock lock(mutex);
+             dataFromTerminatedThreads.push_back((T*)pData);
+         }
+     }
+ };
+ //! @}
+ } // namespace
+ #endif // OPENCV_UTILS_TLS_HPP
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge