diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 8cf7b7e27..fbaf13721 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -4620,6 +4620,34 @@ public: CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body); +/////////////////////////// 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; +}; + } #endif // __cplusplus diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp index 4274caf34..3e21417f7 100644 --- a/modules/core/src/parallel.cpp +++ b/modules/core/src/parallel.cpp @@ -42,6 +42,16 @@ #include "precomp.hpp" +#if !defined HAVE_TBB && !defined HAVE_OPENMP && !defined HAVE_GCD && !defined HAVE_CONCURRENCY + +#ifdef __APPLE__ +#define HAVE_GCD +#elif defined __MSC_VER && __MSC_VER >= 1600 +#define HAVE_CONCURRENCY +#endif + +#endif + #ifdef HAVE_CONCURRENCY # include #elif defined HAVE_OPENMP diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 42bf6593d..e1d57ef8c 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -930,4 +930,104 @@ BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ) } #endif +namespace cv +{ + +#if defined WIN32 || defined _WIN32 || defined WINCE + +struct Mutex::Impl +{ + Impl() { InitializeCriticalSection(&cs); refcount = 1; } + ~Impl() { DeleteCriticalSection(&cs); } + + void lock() { EnterCriticalSection(&cs); } + bool trylock() { return TryEnterCriticalSection(&cs) != 0; } + void unlock() { LeaveCriticalSection(&cs); } + + CRITICAL_SECTION cs; + int refcount; +}; + +#elif defined __APPLE__ + +#include + +struct Mutex::Impl +{ + Impl() { sl = OS_SPINLOCK_INIT; refcount = 1; } + ~Impl() {} + + void lock() { OSSpinLockLock(&sl); } + bool trylock() { return OSSpinLockTry(&sl); } + void unlock() { OSSpinLockUnlock(&sl); } + + OSSpinLock sl; + int refcount; +}; + +#elif defined __linux__ + +struct Mutex::Impl +{ + Impl() { pthread_spin_init(&sl, 0); refcount = 1; } + ~Impl() { pthread_spin_destroy(&sl); } + + void lock() { pthread_spin_lock(&sl); } + bool trylock() { return pthread_spin_trylock(&sl) == 0; } + void unlock() { pthread_spin_unlock(&sl); } + + pthread_spinlock_t sl; + int refcount; +}; + +#else + +struct Mutex::Impl +{ + Impl() { pthread_mutex_init(&sl, 0); refcount = 1; } + ~Impl() { pthread_mutex_destroy(&sl); } + + void lock() { pthread_mutex_lock(&sl); } + bool trylock() { return pthread_mutex_trylock(&sl) == 0; } + void unlock() { pthread_mutex_unlock(&sl); } + + pthread_mutex_t sl; + int refcount; +}; + +#endif + +Mutex::Mutex() +{ + impl = new Mutex::Impl; +} + +Mutex::~Mutex() +{ + if( CV_XADD(&impl->refcount, -1) == 1 ) + delete impl; + impl = 0; +} + +Mutex::Mutex(const Mutex& m) +{ + impl = m.impl; + CV_XADD(&impl->refcount, 1); +} + +Mutex& Mutex::operator = (const Mutex& m) +{ + CV_XADD(&m.impl->refcount, 1); + if( CV_XADD(&impl->refcount, -1) == 1 ) + delete impl; + impl = m.impl; + return *this; +} + +void Mutex::lock() { impl->lock(); } +void Mutex::unlock() { impl->unlock(); } +bool Mutex::trylock() { return impl->trylock(); } + +} + /* End of file. */ \ No newline at end of file