1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPThreadLocalImpl.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkSMPThreadLocal - A TBB based thread local storage implementation.
#ifndef TBBvtkSMPThreadLocalImpl_h
#define TBBvtkSMPThreadLocalImpl_h
#include "SMP/Common/vtkSMPThreadLocalImplAbstract.h"
#ifdef _MSC_VER
#pragma push_macro("__TBB_NO_IMPLICIT_LINKAGE")
#define __TBB_NO_IMPLICIT_LINKAGE 1
#endif
#include <tbb/enumerable_thread_specific.h>
#ifdef _MSC_VER
#pragma pop_macro("__TBB_NO_IMPLICIT_LINKAGE")
#endif
#include <iterator>
#include <utility> // For std::move
namespace vtk
{
namespace detail
{
namespace smp
{
VTK_ABI_NAMESPACE_BEGIN
template <typename T>
class vtkSMPThreadLocalImpl<BackendType::TBB, T> : public vtkSMPThreadLocalImplAbstract<T>
{
typedef tbb::enumerable_thread_specific<T> TLS;
typedef typename TLS::iterator TLSIter;
typedef typename vtkSMPThreadLocalImplAbstract<T>::ItImpl ItImplAbstract;
public:
vtkSMPThreadLocalImpl() {}
explicit vtkSMPThreadLocalImpl(const T& exemplar)
: Internal(exemplar)
{
}
T& Local() override { return this->Internal.local(); }
size_t size() const override { return this->Internal.size(); }
class ItImpl : public vtkSMPThreadLocalImplAbstract<T>::ItImpl
{
public:
void Increment() override { ++this->Iter; }
bool Compare(ItImplAbstract* other) override
{
return this->Iter == static_cast<ItImpl*>(other)->Iter;
}
T& GetContent() override { return *this->Iter; }
T* GetContentPtr() override { return &*this->Iter; }
protected:
virtual ItImpl* CloneImpl() const override { return new ItImpl(*this); };
private:
TLSIter Iter;
friend class vtkSMPThreadLocalImpl<BackendType::TBB, T>;
};
std::unique_ptr<ItImplAbstract> begin() override
{
// XXX(c++14): use std::make_unique
auto iter = std::unique_ptr<ItImpl>(new ItImpl());
iter->Iter = this->Internal.begin();
// XXX(c++14): remove std::move and cast variable
std::unique_ptr<ItImplAbstract> abstractIt(std::move(iter));
return abstractIt;
};
std::unique_ptr<ItImplAbstract> end() override
{
// XXX(c++14): use std::make_unique
auto iter = std::unique_ptr<ItImpl>(new ItImpl());
iter->Iter = this->Internal.end();
// XXX(c++14): remove std::move and cast variable
std::unique_ptr<ItImplAbstract> abstractIt(std::move(iter));
return abstractIt;
}
private:
TLS Internal;
// disable copying
vtkSMPThreadLocalImpl(const vtkSMPThreadLocalImpl&) = delete;
void operator=(const vtkSMPThreadLocalImpl&) = delete;
};
VTK_ABI_NAMESPACE_END
} // namespace smp
} // namespace detail
} // namespace vtk
#endif
|