added cross-platform Mutex implementation; enable platform-native (GDC/Concurrency) parallel_for_ implementation when TBB is not installed.

This commit is contained in:
Vadim Pisarevsky 2012-08-17 17:32:06 +04:00
parent 2e685dcf0a
commit 41b6d25bdd
3 changed files with 138 additions and 0 deletions

View File

@ -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

View File

@ -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 <ppl.h>
#elif defined HAVE_OPENMP

View File

@ -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 <libkern/OSAtomic.h>
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. */