From d1a81710119ee3c3da661b4a13e4abe64d3d05ed Mon Sep 17 00:00:00 2001 From: Maxim Kostin <maxim.kostin@akvelon.com> Date: Wed, 18 Mar 2015 15:13:08 +0300 Subject: [PATCH] Added WinRT concurrency support. --- modules/core/src/parallel.cpp | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp index 4dde2adeae..582c7cd039 100644 --- a/modules/core/src/parallel.cpp +++ b/modules/core/src/parallel.cpp @@ -69,7 +69,7 @@ #define HAVE_GCD #endif -#if defined _MSC_VER && _MSC_VER >= 1600 && !defined(WINRT) +#if defined _MSC_VER && _MSC_VER >= 1600 #define HAVE_CONCURRENCY #endif @@ -78,7 +78,8 @@ 2. HAVE_CSTRIPES - 3rdparty library, should be explicitly enabled 3. HAVE_OPENMP - integrated to compiler, should be explicitly enabled 4. HAVE_GCD - system wide, used automatically (APPLE only) - 5. HAVE_CONCURRENCY - part of runtime, used automatically (Windows only - MSVS 10, MSVS 11) + 5. WINRT - system wide, used automatically (Windows RT only) + 6. HAVE_CONCURRENCY - part of runtime, used automatically (Windows only - MSVS 10, MSVS 11) */ #if defined HAVE_TBB @@ -105,6 +106,8 @@ #elif defined HAVE_GCD #include <dispatch/dispatch.h> #include <pthread.h> + #elif defined WINRT + #include <ppltasks.h> #elif defined HAVE_CONCURRENCY #include <ppl.h> #endif @@ -118,6 +121,8 @@ # define CV_PARALLEL_FRAMEWORK "openmp" #elif defined HAVE_GCD # define CV_PARALLEL_FRAMEWORK "gcd" +#elif defined WINRT +# define CV_PARALLEL_FRAMEWORK "winrt-concurrency" #elif defined HAVE_CONCURRENCY # define CV_PARALLEL_FRAMEWORK "ms-concurrency" #endif @@ -179,7 +184,7 @@ namespace ProxyLoopBody* ptr_body = static_cast<ProxyLoopBody*>(context); (*ptr_body)(cv::Range((int)index, (int)index + 1)); } -#elif defined HAVE_CONCURRENCY +#elif defined WINRT || defined HAVE_CONCURRENCY class ProxyLoopBody : public ParallelLoopBodyWrapper { public: @@ -206,7 +211,10 @@ static tbb::task_scheduler_init tbbScheduler(tbb::task_scheduler_init::deferred) static int numThreadsMax = omp_get_max_threads(); #elif defined HAVE_GCD // nothing for GCD +#elif defined WINRT +// nothing for WINRT #elif defined HAVE_CONCURRENCY + class SchedPtr { Concurrency::Scheduler* sched_; @@ -224,6 +232,7 @@ public: ~SchedPtr() { *this = 0; } }; static SchedPtr pplScheduler; + #endif #endif // CV_PARALLEL_FRAMEWORK @@ -272,6 +281,10 @@ void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body, dispatch_queue_t concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply_f(stripeRange.end - stripeRange.start, concurrent_queue, &pbody, block_function); +#elif defined WINRT + + Concurrency::parallel_for(stripeRange.start, stripeRange.end, pbody); + #elif defined HAVE_CONCURRENCY if(!pplScheduler || pplScheduler->Id() == Concurrency::CurrentScheduler::Id()) @@ -330,11 +343,15 @@ int cv::getNumThreads(void) return 512; // the GCD thread pool limit +#elif defined WINRT + + return 0; + #elif defined HAVE_CONCURRENCY return 1 + (pplScheduler == 0 - ? Concurrency::CurrentScheduler::Get()->GetNumberOfVirtualProcessors() - : pplScheduler->GetNumberOfVirtualProcessors()); + ? Concurrency::CurrentScheduler::Get()->GetNumberOfVirtualProcessors() + : pplScheduler->GetNumberOfVirtualProcessors()); #else @@ -371,6 +388,10 @@ void cv::setNumThreads( int threads ) // unsupported // there is only private dispatch_queue_set_width() and only for desktop +#elif defined WINRT + + return; + #elif defined HAVE_CONCURRENCY if (threads <= 0) @@ -407,6 +428,8 @@ int cv::getThreadNum(void) return omp_get_thread_num(); #elif defined HAVE_GCD return (int)(size_t)(void*)pthread_self(); // no zero-based indexing +#elif defined WINRT + return 0; #elif defined HAVE_CONCURRENCY return std::max(0, (int)Concurrency::Context::VirtualProcessorId()); // zero for master thread, unique number for others but not necessary 1,2,3,... #else