Skip to content

Commit 47c4dcc

Browse files
committed
Merge pull request opencv#8204 from terfendail:ovx_tlcontext
2 parents 7878404 + 9a4b5a4 commit 47c4dcc

File tree

18 files changed

+88
-26
lines changed

18 files changed

+88
-26
lines changed

3rdparty/openvx/hal/openvx_hal.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,17 @@ struct Tick
5252

5353
inline ivx::Context& getOpenVXHALContext()
5454
{
55-
// not thread safe
56-
static ivx::Context instance = ivx::Context::create();
55+
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
56+
//CXX11
57+
static thread_local ivx::Context instance = ivx::Context::create();
58+
#else //__cplusplus >= 201103L || _MSC_VER >= 1800
59+
//CXX98
60+
#ifdef WIN32
61+
static __declspec(thread) ivx::Context instance = ivx::Context::create();
62+
#else
63+
static __thread ivx::Context instance = ivx::Context::create();
64+
#endif
65+
#endif
5766
return instance;
5867
}
5968

modules/core/include/opencv2/core/openvx/ovx_defs.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
#define IVX_USE_OPENCV
2121
#include "ivx.hpp"
2222

23+
namespace cv{
24+
namespace ovx{
25+
// Get common thread local OpenVX context
26+
CV_EXPORTS_W ivx::Context& getOpenVXContext();
27+
}}
28+
2329
#define CV_OVX_RUN(condition, func, ...) \
2430
if (cv::useOpenVX() && (condition) && func) \
2531
{ \

modules/core/include/opencv2/core/utility.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,9 @@ class CV_EXPORTS TLSDataContainer
627627
virtual void deleteDataInstance(void* pData) const = 0;
628628

629629
int key_;
630+
631+
public:
632+
void cleanup(); //! Release created TLS data container objects. It is similar to release() call, but it keeps TLS container valid.
630633
};
631634

632635
// Main TLS data class
@@ -638,13 +641,15 @@ class TLSData : protected TLSDataContainer
638641
inline ~TLSData() { release(); } // Release key and delete associated data
639642
inline T* get() const { return (T*)getData(); } // Get data associated with key
640643

641-
// Get data from all threads
644+
// Get data from all threads
642645
inline void gather(std::vector<T*> &data) const
643646
{
644647
std::vector<void*> &dataVoid = reinterpret_cast<std::vector<void*>&>(data);
645648
gatherData(dataVoid);
646649
}
647650

651+
inline void cleanup() { TLSDataContainer::cleanup(); }
652+
648653
private:
649654
virtual void* createDataInstance() const {return new T;} // Wrapper to allocate data by template
650655
virtual void deleteDataInstance(void* pData) const {delete (T*)pData;} // Wrapper to release data by template

modules/core/src/convert.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4673,7 +4673,7 @@ static bool _openvx_cvt(const T* src, size_t sstep,
46734673

46744674
try
46754675
{
4676-
Context context = Context::create();
4676+
Context context = ovx::getOpenVXContext();
46774677

46784678
// Other conversions are marked as "experimental"
46794679
if(context.vendorID() == VX_ID_KHRONOS &&
@@ -5406,7 +5406,7 @@ static bool openvx_LUT(Mat src, Mat dst, Mat _lut)
54065406

54075407
try
54085408
{
5409-
ivx::Context ctx = ivx::Context::create();
5409+
ivx::Context ctx = ovx::getOpenVXContext();
54105410

54115411
ivx::Image
54125412
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,

modules/core/src/ovx.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,38 @@
1414
namespace cv
1515
{
1616

17+
namespace ovx
18+
{
19+
#ifdef HAVE_OPENVX
20+
21+
// Simple TLSData<ivx::Context> doesn't work, because default constructor doesn't create any OpenVX context.
22+
struct OpenVXTLSData
23+
{
24+
OpenVXTLSData() : ctx(ivx::Context::create()) {}
25+
ivx::Context ctx;
26+
};
27+
28+
static TLSData<OpenVXTLSData>& getOpenVXTLSData()
29+
{
30+
CV_SINGLETON_LAZY_INIT_REF(TLSData<OpenVXTLSData>, new TLSData<OpenVXTLSData>())
31+
}
32+
33+
struct OpenVXCleanupFunctor
34+
{
35+
~OpenVXCleanupFunctor() { getOpenVXTLSData().cleanup(); }
36+
};
37+
static OpenVXCleanupFunctor g_openvx_cleanup_functor;
38+
39+
ivx::Context& getOpenVXContext()
40+
{
41+
return getOpenVXTLSData().get()->ctx;
42+
}
43+
44+
#endif
45+
46+
} // namespace
47+
48+
1749
bool haveOpenVX()
1850
{
1951
#ifdef HAVE_OPENVX
@@ -22,7 +54,7 @@ bool haveOpenVX()
2254
{
2355
try
2456
{
25-
ivx::Context context = ivx::Context::create();
57+
ivx::Context context = ovx::getOpenVXContext();
2658
vx_uint16 vComp = ivx::compiledWithVersion();
2759
vx_uint16 vCurr = context.version();
2860
g_haveOpenVX =

modules/core/src/stat.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ namespace cv
16651665

16661666
try
16671667
{
1668-
ivx::Context ctx = ivx::Context::create();
1668+
ivx::Context ctx = ovx::getOpenVXContext();
16691669
#ifndef VX_VERSION_1_1
16701670
if (ctx.vendorID() == VX_ID_KHRONOS)
16711671
return false; // Do not use OpenVX meanStdDev estimation for sample 1.0.1 implementation due to lack of accuracy
@@ -2312,7 +2312,7 @@ static bool openvx_minMaxIdx(Mat &src, double* minVal, double* maxVal, int* minI
23122312

23132313
try
23142314
{
2315-
ivx::Context ctx = ivx::Context::create();
2315+
ivx::Context ctx = ovx::getOpenVXContext();
23162316
ivx::Image
23172317
ia = ivx::Image::createFromHandle(ctx, stype == CV_8UC1 ? VX_DF_IMAGE_U8 : VX_DF_IMAGE_S16,
23182318
ivx::Image::createAddressing(cols, rows, stype == CV_8UC1 ? 1 : 2, (vx_int32)(src.step[0])), src.ptr());

modules/core/src/system.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ class TlsStorage
10861086
}
10871087

10881088
// Release TLS storage index and pass associated data to caller
1089-
void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec)
1089+
void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec, bool keepSlot = false)
10901090
{
10911091
AutoLock guard(mtxGlobalAccess);
10921092
CV_Assert(tlsSlots.size() > slotIdx);
@@ -1099,12 +1099,13 @@ class TlsStorage
10991099
if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
11001100
{
11011101
dataVec.push_back(thread_slots[slotIdx]);
1102-
threads[i]->slots[slotIdx] = 0;
1102+
thread_slots[slotIdx] = NULL;
11031103
}
11041104
}
11051105
}
11061106

1107-
tlsSlots[slotIdx] = 0;
1107+
if (!keepSlot)
1108+
tlsSlots[slotIdx] = 0;
11081109
}
11091110

11101111
// Get data by TLS storage index
@@ -1196,9 +1197,18 @@ void TLSDataContainer::release()
11961197
std::vector<void*> data;
11971198
data.reserve(32);
11981199
getTlsStorage().releaseSlot(key_, data); // Release key and get stored data for proper destruction
1200+
key_ = -1;
1201+
for(size_t i = 0; i < data.size(); i++) // Delete all associated data
1202+
deleteDataInstance(data[i]);
1203+
}
1204+
1205+
void TLSDataContainer::cleanup()
1206+
{
1207+
std::vector<void*> data;
1208+
data.reserve(32);
1209+
getTlsStorage().releaseSlot(key_, data, true); // Extract stored data with removal from TLS tables
11991210
for(size_t i = 0; i < data.size(); i++) // Delete all associated data
12001211
deleteDataInstance(data[i]);
1201-
key_ = -1;
12021212
}
12031213

12041214
void* TLSDataContainer::getData() const

modules/features2d/src/fast.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ static bool openvx_FAST(InputArray _img, std::vector<KeyPoint>& keypoints,
354354

355355
try
356356
{
357-
Context context = Context::create();
357+
Context context = ovx::getOpenVXContext();
358358
Image img = Image::createFromHandle(context, Image::matTypeToFormat(imgMat.type()),
359359
Image::createAddressing(imgMat), (void*)imgMat.data);
360360
ivx::Scalar threshold = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _threshold);

modules/imgproc/src/accum.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ static bool openvx_accumulate(InputArray _src, InputOutputArray _dst, InputArray
19581958

19591959
try
19601960
{
1961-
ivx::Context context = ivx::Context::create();
1961+
ivx::Context context = ovx::getOpenVXContext();
19621962
ivx::Image srcImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(srcMat.type()),
19631963
ivx::Image::createAddressing(srcMat), srcMat.data);
19641964
ivx::Image dstImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(dstMat.type()),

modules/imgproc/src/canny.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ static bool openvx_canny(const Mat& src, Mat& dst, int loVal, int hiVal, int kSi
782782
{
783783
using namespace ivx;
784784

785-
Context context = Context::create();
785+
Context context = ovx::getOpenVXContext();
786786
try
787787
{
788788
Image _src = Image::createFromHandle(

0 commit comments

Comments
 (0)