Merge pull request #493 from afabri/CGLAL-thread_local_storage-GF

Remove boost thread dependency
This commit is contained in:
Sebastien Loriot 2016-01-04 16:49:26 +01:00
commit 2b49997c7e
20 changed files with 249 additions and 277 deletions

View File

@ -31,7 +31,7 @@
#include <boost/optional.hpp>
#ifdef CGAL_HAS_THREADS
#include <boost/thread/mutex.hpp>
#include <CGAL/mutex.h>
#endif
/// \file AABB_tree.h
@ -500,7 +500,7 @@ public:
{
#ifdef CGAL_HAS_THREADS
//this ensures that this is done once at a time
boost::mutex::scoped_lock scoped_lock(kd_tree_mutex);
CGAL_SCOPED_LOCK(kd_tree_mutex);
#endif
clear_search_tree();
return accelerate_distance_queries_impl(first,beyond);
@ -599,8 +599,8 @@ public:
// single root node
Node* m_p_root_node;
#ifdef CGAL_HAS_THREADS
mutable boost::mutex internal_tree_mutex;//mutex used to protect const calls inducing build()
mutable boost::mutex kd_tree_mutex;//mutex used to protect calls to accelerate_distance_queries
mutable CGAL_MUTEX internal_tree_mutex;//mutex used to protect const calls inducing build()
mutable CGAL_MUTEX kd_tree_mutex;//mutex used to protect calls to accelerate_distance_queries
#endif
const Node* root_node() const {
@ -608,7 +608,7 @@ public:
if(m_need_build){
#ifdef CGAL_HAS_THREADS
//this ensures that build() will be called once
boost::mutex::scoped_lock scoped_lock(internal_tree_mutex);
CGAL_SCOPED_LOCK(internal_tree_mutex);
if(m_need_build)
#endif
const_cast< AABB_tree<AABBTraits>* >(this)->build();
@ -1046,7 +1046,7 @@ public:
if(m_primitives.empty()) return true;
#ifdef CGAL_HAS_THREADS
//this ensures that this function will be done once
boost::mutex::scoped_lock scoped_lock(kd_tree_mutex);
CGAL_SCOPED_LOCK(kd_tree_mutex);
#endif
//we only redo computation only if needed

View File

@ -0,0 +1,20 @@
/*!
\page devman_multithreading Multithreading
\author Andreas Fabri
\section Developer_manualThreadlocal Thread Local Storage
The header file <CGAL/tss.h> provides a macro `CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE,VAR,ARG1)`
that creates a thread local variable `VAR` of type `TYPE`, and passes `ARG1` to the
constructor. The variable is either `threadlocal`, or a `boost::thread_specific_ptr`,
or just a local variable if `CGAL_HAS_THREADS` is not defined.
\section Developer_manualMutex Mutex
The header file <CGAL/mutex.h> provides a macro `CGAL_MUTEX` and a macro `CGAL_SCOPED_LOCK(M)` that is either a `std::unique_lock<std::mutex>` or a `boost::mutex::scoped_lock`.
*/

View File

@ -10,6 +10,7 @@
- \subpage devman_reference_counting
- \subpage devman_memory_management
- \subpage devman_namespaces
- \subpage devman_multithreading
- \subpage devman_polyret
- \subpage devman_iterators_and_circulators
- \subpage devman_robustness

View File

@ -293,7 +293,7 @@ We next list the libraries and essential 3rd party software
| Library | CMake Variable | Functionality | Dependencies |
| :-------- | :------------- | :------------ | :----------- |
| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers), Boost.Thread and Boost.System (library) |
| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers), Boost.Thread and Boost.System (library) for compilers not supporting the keywords `threadlocal` and the class `mutex` |
| `CGAL_Core` | `WITH_CGAL_Core` | The CORE library for algebraic numbers.\cgalFootnote{CGAL_Core is not part of \cgal, but a custom version of the \sc{Core} library distributed by \cgal for the user convenience and it has it's own license.} | \sc{Gmp} and \sc{Mpfr} |
| `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \sc{OpenGL}, \sc{zlib}, \sc{Vtk}(optional) |
| `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \sc{Qt}5-based demos | \sc{Qt}5 and \sc{OpenGL} |
@ -350,7 +350,8 @@ installed as binaries.
\cgal requires the \sc{Boost} libraries. In particular the header files
and the threading library (`Boost.Thread` and
`Boost.System` binaries). Version 1.48 (or higher) are needed.
`Boost.System` binaries). Version 1.48 (or higher) are needed
for compilers not supporting the keywords `threadlocal` and the class `mutex` (This is supported for \gcc 4.8 and later when using the \cpp 11 standard, and for Visual C++ starting with 2015, that is VC14).
On Windows, as auto-linking is used, you also need the binaries of
`Boost.Serialization` and `Boost.DateTime`, but the
@ -360,9 +361,9 @@ not depend on the DLL's of those two libraries.
In \cgal some demos and examples depend on `Boost.Program_options`.
In case the \sc{Boost} libraries are not installed on your system already, you
can obtain them from <A HREF="http://www.boost.org/">`http://www.boost.org/`</A>. For Windows you can download precompiled libraries
from <A HREF="http://boost.teeks99.com/">`http://boost.teeks99.com/`</A>.
Since `Boost.Thread` is required, make sure to either install the precompiled
can obtain them from <A HREF="http://www.boost.org/">`http://www.boost.org/`</A>. For Visual C++ you can download precompiled libraries
from <A HREF="http://sourceforge.net/projects/boost/files/boost-binaries/">`http://sourceforge.net/projects/boost/files/boost-binaries/`</A>.
For Visual C++ versions prior to 2015 `Boost.Thread` is required, so make sure to either install the precompiled
libraries for your compiler or build `libboost-thread` and `libboost-system`.
As on Windows there is no canonical directory for where to find

View File

@ -33,10 +33,7 @@
#include <CGAL/Bbox_3.h>
#include <vector>
#include <CGAL/Default.h>
#ifdef CGAL_HAS_THREADS
# include <boost/thread/tss.hpp>
#endif
#include<CGAL/tss.h>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
@ -787,16 +784,10 @@ private:
// which is in particular heavily used for pruning DAGs.
static const Self & zero()
{
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr<Self> z;
if (z.get() == NULL) {
z.reset(new Self(new Lazy_rep_0<AT, ET, E2A>()));
}
return * z.get();
#else
static const Self z = new Lazy_rep_0<AT, ET, E2A>();
// Note that the new only happens inside an if() inside the macro
// So it would be a mistake to put the new before the macro
CGAL_STATIC_THREAD_LOCAL_VARIABLE(Self,z,(new Lazy_rep_0<AT, ET, E2A>()));
return z;
#endif
}
Self_rep * ptr() const { return (Self_rep*) PTR; }

View File

@ -127,6 +127,14 @@ and <code>src/</code> directories).
</li>
</ul>
<h3>Installation</h3>
<ul>
<li>Starting with Visual C++ 2015 we no longer require <code>Boost.Thread</code>
as we use the keyword <code>threadlocal</code> and the class <code>mutex</code>
from the header file <code><thread></code>.</li>
<li>The same holds for g++ 4.8 or later when the c++11 standard is used.</li>
</ul>
<!-- New packages -->
<!-- Major and breaking changes -->
<!-- Arithmetic and Algebra -->

View File

@ -1,9 +1,30 @@
if ( NOT CGAL_Boost_Setup )
include(CGAL_TweakFindBoost)
set ( CGAL_requires_Boost_libs TRUE )
if ( DEFINED MSVC_VERSION AND "${MSVC_VERSION}" GREATER 1800)
set ( CGAL_requires_Boost_libs FALSE )
endif()
if ( CMAKE_COMPILER_IS_GNUCXX
AND(
#GCC 4.8+ with c++11 on
( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8
AND CMAKE_CXX_FLAGS MATCHES "\\-std=(c|gnu)\\+\\+[01][14yxz]")
#GCC 6.0+ without c++03 on
OR ( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0
AND NOT CMAKE_CXX_FLAGS MATCHES "\\-std=(c|gnu)\\+\\+[90][83]")
) )
set ( CGAL_requires_Boost_libs FALSE )
endif()
# In the documentation, we say we require Boost-1.48, but technically we
# require 1.39. Some packages may require more recent versions, though.
find_package( Boost 1.39 REQUIRED thread system )
if (CGAL_requires_Boost_libs)
find_package( Boost 1.39 REQUIRED thread system )
else()
find_package( Boost 1.39 REQUIRED )
endif()
if(Boost_FOUND)
if(DEFINED Boost_DIR AND NOT Boost_DIR)

View File

@ -434,6 +434,18 @@ using std::max;
# endif
#endif
#if ( defined(__GNUC__) && defined(__GNUC_MINOR__) \
&& (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 \
&& __cplusplus >= 201103L ) || ( _MSC_VER >= 1900 )
#define CGAL_CAN_USE_CXX11_THREAD_LOCAL
#endif
#if ( defined(__GNUC__) && defined(__GNUC_MINOR__) \
&& (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 \
&& __cplusplus >= 201103L ) || ( _MSC_VER >= 1700 )
#define CGAL_CAN_USE_CXX11_MUTEX
#endif
// Support for LEDA with threads
// Not that, if CGAL_HAS_THREADS is defined, and you want to use LEDA,
// you must link with a version of LEDA libraries that support threads.

View File

@ -0,0 +1,34 @@
// Copyright (c) 2016 GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
#ifndef CGAL_MUTEX_H
#define CGAL_MUTEX_H
#include <CGAL/config.h>
#ifdef CGAL_HAS_THREADS
#ifdef CGAL_CAN_USE_CXX11_MUTEX
#include <mutex>
#define CGAL_MUTEX std::mutex
#define CGAL_SCOPED_LOCK(M) std::unique_lock<std::mutex> scoped_lock(M)
#else
#include <boost/thread/mutex.hpp>
#define CGAL_MUTEX boost::mutex
#define CGAL_SCOPED_LOCK(M) boost::mutex::scoped_lock scoped_lock(M)
#endif
#endif
#endif // CGAL_MUTEX_H

View File

@ -0,0 +1,53 @@
// Copyright (c) 2016 GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
#ifndef CGAL_TSS_H
#define CGAL_TSS_H
#include <CGAL/config.h>
#if defined( CGAL_HAS_THREADS )
# ifdef CGAL_CAN_USE_CXX11_THREAD_LOCAL
//# pragma message ( "Use keyword thread_local" )
# else
//# pragma message ("Use thread_local from boost")
# define CGAL_USE_BOOST_THREAD
# include <boost/thread/tss.hpp>
# endif
# ifdef CGAL_USE_BOOST_THREAD
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == NULL) {VAR##_ptr.reset(new TYPE(ARG1));} \
TYPE& VAR = * VAR##_ptr.get()
# else
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \
static thread_local TYPE VAR(ARG1)
# endif
#else
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR,ARG1) static TYPE VAR(ARG1)
#endif
#endif // CGAL_TSS_H

View File

@ -31,7 +31,7 @@
#include <boost/optional.hpp>
#ifdef CGAL_HAS_THREADS
#include <boost/thread/mutex.hpp>
#include <CGAL/mutex.h>
#endif
/// \file AABB_tree.h
@ -506,7 +506,7 @@ public:
{
#ifdef CGAL_HAS_THREADS
//this ensures that this is done once at a time
boost::mutex::scoped_lock scoped_lock(kd_tree_mutex);
CGAL_SCOPED_LOCK(kd_tree_mutex);
#endif
clear_search_tree();
return accelerate_distance_queries_impl(first,beyond);
@ -623,8 +623,8 @@ public:
// single root node
Node* m_p_root_node;
#ifdef CGAL_HAS_THREADS
mutable boost::mutex internal_tree_mutex;//mutex used to protect const calls inducing build()
mutable boost::mutex kd_tree_mutex;//mutex used to protect calls to accelerate_distance_queries
mutable CGAL_MUTEX internal_tree_mutex;//mutex used to protect const calls inducing build()
mutable CGAL_MUTEX kd_tree_mutex;//mutex used to protect calls to accelerate_distance_queries
#endif
const Node* root_node() const {
@ -632,7 +632,7 @@ public:
if(m_need_build){
#ifdef CGAL_HAS_THREADS
//this ensures that build() will be called once
boost::mutex::scoped_lock scoped_lock(internal_tree_mutex);
CGAL_SCOPED_LOCK(internal_tree_mutex);
if(m_need_build)
#endif
const_cast< AABB_tree_with_join<AABBTraits>* >(this)->build();
@ -1070,7 +1070,7 @@ public:
if(m_primitives.empty()) return true;
#ifdef CGAL_HAS_THREADS
//this ensures that this function will be done once
boost::mutex::scoped_lock scoped_lock(kd_tree_mutex);
CGAL_SCOPED_LOCK(kd_tree_mutex);
#endif
//we only redo computation only if needed

View File

@ -22,13 +22,12 @@
#define CGAL_RESIDUE_TYPE_H
#include <CGAL/basic.h>
#include <CGAL/tss.h>
#include <cfloat>
#include <boost/operators.hpp>
#ifdef CGAL_HAS_THREADS
# include <boost/thread/tss.hpp>
#endif
namespace CGAL {
@ -71,96 +70,40 @@ private:
static const double& get_static_CST_CUT()
{ return Residue::CST_CUT; }
#endif // CGAL_HEADER_ONLY
#ifdef CGAL_HAS_THREADS
#ifdef CGAL_HEADER_ONLY
static boost::thread_specific_ptr<int>& get_static_prime_int_()
static int& prime_int_internal()
{
static boost::thread_specific_ptr<int> prime_int_;
return prime_int_;
}
static boost::thread_specific_ptr<double>& get_static_prime_()
{
static boost::thread_specific_ptr<double> prime_;
return prime_;
}
static boost::thread_specific_ptr<double>& get_static_prime_inv_()
{
static boost::thread_specific_ptr<double> prime_inv_;
return prime_inv_;
}
#else // CGAL_HEADER_ONLY
CGAL_EXPORT static boost::thread_specific_ptr<int> prime_int_;
CGAL_EXPORT static boost::thread_specific_ptr<double> prime_;
CGAL_EXPORT static boost::thread_specific_ptr<double> prime_inv_;
static boost::thread_specific_ptr<int>& get_static_prime_int_()
{ return Residue::prime_int_; }
static boost::thread_specific_ptr<double>& get_static_prime_()
{ return Residue::prime_; }
static boost::thread_specific_ptr<double>& get_static_prime_inv_()
{ return Residue::prime_inv_; }
#endif // CGAL_HEADER_ONLY
static void init_class_for_thread(){
CGAL_precondition(get_static_prime_int_().get() == NULL);
CGAL_precondition(get_static_prime_().get() == NULL);
CGAL_precondition(get_static_prime_inv_().get() == NULL);
get_static_prime_int_().reset(new int(67111067));
get_static_prime_().reset(new double(67111067.0));
get_static_prime_inv_().reset(new double(1.0/67111067.0));
CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, prime_int, 67111067);
return prime_int;
}
static inline int get_prime_int(){
if (get_static_prime_int_().get() == NULL)
init_class_for_thread();
return *get_static_prime_int_().get();
return prime_int_internal();
}
static inline double get_prime(){
if (get_static_prime_().get() == NULL)
init_class_for_thread();
return *get_static_prime_().get();
}
static inline double get_prime_inv(){
if (get_static_prime_inv_().get() == NULL)
init_class_for_thread();
return *get_static_prime_inv_().get();
}
#else // CGAL_HAS_THREADS
#ifdef CGAL_HEADER_ONLY
static int& get_static_prime_int()
static double& prime_internal()
{
static int prime_int = 67111067;
return prime_int;
}
static double& get_static_prime()
{
static double prime = 67111067.0;
CGAL_STATIC_THREAD_LOCAL_VARIABLE(double, prime, 67111067.0);
return prime;
}
static double& get_static_prime_inv()
static inline double get_prime(){
return prime_internal();
}
static double& prime_inv_internal()
{
static double prime_inv = 1/67111067.0;
CGAL_STATIC_THREAD_LOCAL_VARIABLE(double, prime_inv, 0.000000014900672045640400859667452463541);
return prime_inv;
}
#else //
CGAL_EXPORT static int prime_int;
CGAL_EXPORT static double prime;
CGAL_EXPORT static double prime_inv;
static int& get_static_prime_int()
{ return Residue::prime_int; }
static double& get_static_prime()
{ return Residue::prime; }
static double& get_static_prime_inv()
{ return Residue::prime_inv; }
#endif // CGAL_HEADER_ONLY
static int get_prime_int(){ return get_static_prime_int();}
static double get_prime() { return get_static_prime();}
static double get_prime_inv(){ return get_static_prime_inv();}
#endif
static inline double get_prime_inv(){
return prime_inv_internal();
}
/* Quick integer rounding, valid if a<2^51. for double */
static inline
@ -255,15 +198,10 @@ public:
static int
set_current_prime(int p){
int old_prime = get_prime_int();
#ifdef CGAL_HAS_THREADS
*get_static_prime_int_().get() = p;
*get_static_prime_().get() = double(p);
*get_static_prime_inv_().get() = 1.0/double(p);
#else
get_static_prime_int() = p;
get_static_prime() = double(p);
get_static_prime_inv() = 1.0 / prime;
#endif
prime_int_internal() = p;
prime_internal() = double(p);
prime_inv_internal() = 1.0 / double(p);
return old_prime;
}
@ -289,10 +227,11 @@ public:
}
//! constructor of Residue, from long
Residue(long n){
Residue (long n) {
x_= RES_soft_reduce (static_cast< double > (n % get_prime_int()));
}
//! constructor of Residue, from long long
Residue (long long n) {
x_= RES_soft_reduce (static_cast< double > (n % get_prime_int()));

View File

@ -23,16 +23,7 @@
#include <CGAL/Modular_arithmetic/Residue_type.h>
namespace CGAL{
#ifdef CGAL_HAS_THREADS
boost::thread_specific_ptr<int> Residue::prime_int_;
boost::thread_specific_ptr<double> Residue::prime_;
boost::thread_specific_ptr<double> Residue::prime_inv_;
#else
int Residue::prime_int = 67111067;
double Residue::prime = 67111067.0;
double Residue::prime_inv =1/67111067.0;
#endif
const double Residue::CST_CUT = std::ldexp( 3., 51 );

View File

@ -26,9 +26,8 @@
#include <mpfi.h>
#include <boost/operators.hpp>
#include <CGAL/Uncertain.h>
#ifdef CGAL_HAS_THREADS
# include <boost/thread/tss.hpp>
#endif
#include <CGAL/tss.h>
#include <limits>
#include <algorithm>
@ -80,11 +79,8 @@ Uncertain<bool> operator==(const Gmpfi&,const Gmpq&);
// the default precision is a variable local to each thread in multithreaded
// environments, or a global variable otherwise
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr<mp_prec_t> Gmpfi_default_precision_;
#else
static mp_prec_t Gmpfi_default_precision=CGAL_GMPFI_DEFAULT_PRECISION;
#endif
class Gmpfi:
boost::ordered_euclidian_ring_operators1<Gmpfi,
@ -109,6 +105,13 @@ class Gmpfi:
Gmpfr _left,_right;
mutable __mpfi_struct _interval;
static mp_prec_t& default_precision()
{
CGAL_STATIC_THREAD_LOCAL_VARIABLE(mp_prec_t, Gmpfi_default_precision, CGAL_GMPFI_DEFAULT_PRECISION);
return Gmpfi_default_precision;
}
bool is_unique(){
#ifdef CGAL_GMPFR_NO_REFCOUNT
return true;
@ -296,9 +299,7 @@ CGAL_GMPFI_CONSTRUCTOR_FROM_SCALAR(Gmpz);
// default precision
#ifdef CGAL_HAS_THREADS
static void init_precision_for_thread();
#endif
static Gmpfi::Precision_type get_default_precision();
static Gmpfi::Precision_type set_default_precision(
Gmpfi::Precision_type prec);
@ -400,35 +401,20 @@ CGAL_GMPFI_CONSTRUCTOR_FROM_SCALAR(Gmpz);
// --------------
// default precision
#ifdef CGAL_HAS_THREADS
inline
void Gmpfi::init_precision_for_thread(){
CGAL_precondition(Gmpfi_default_precision_.get()==NULL);
Gmpfi_default_precision_.reset(
new mp_prec_t(CGAL_GMPFI_DEFAULT_PRECISION));
}
#endif
inline
Gmpfi::Precision_type Gmpfi::get_default_precision(){
#ifdef CGAL_HAS_THREADS
if(Gmpfi_default_precision_.get()==NULL)
Gmpfi::init_precision_for_thread();
return *Gmpfi_default_precision_.get();
#else
return Gmpfi_default_precision;
#endif
return default_precision();
}
inline
Gmpfi::Precision_type Gmpfi::set_default_precision(Gmpfi::Precision_type prec){
Gmpfi::Precision_type old_prec=Gmpfi::get_default_precision();
Gmpfi::Precision_type old_prec= default_precision();
CGAL_assertion(prec>=MPFR_PREC_MIN&&prec<=MPFR_PREC_MAX);
#ifdef CGAL_HAS_THREADS
*Gmpfi_default_precision_.get()=prec;
#else
Gmpfi_default_precision=prec;
#endif
default_precision() = prec;
return old_prec;
}

View File

@ -108,11 +108,6 @@ CGAL_CLANG_PUSH_AND_IGNORE_UNUSED_LOCAL_TYPEDEF
// int to bool performance
#endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) \
&& (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 \
&& __cplusplus >= 201103L
#define CGAL_CAN_USE_CXX11_THREAD_LOCAL
#endif
/*
#ifdef CGAL_MPZF_NO_USE_CACHE

View File

@ -11,7 +11,9 @@ int main(){
typedef PT_2::Innermost_coefficient_type Integer;
PT_2::Construct_polynomial construct_polynomial;
Poly_2 dc;
// constructing a constant polynomial from int
Poly_2 two(2); // = 2
std::cout << "A constant polynomial: " << two << std::endl;

View File

@ -46,10 +46,7 @@ typename CGAL::internal::Innermost_coefficient_type<T>::Type , 2>::Type
#include <CGAL/Polynomial/misc.h>
#include <CGAL/use.h>
#ifdef CGAL_HAS_THREADS
# include <boost/thread/tss.hpp>
#endif
#include <CGAL/tss.h>
namespace CGAL {
@ -268,15 +265,8 @@ protected:
//
private:
static Self& get_default_instance(){
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< Self > safe_x_ptr;
if (safe_x_ptr.get() == NULL)
safe_x_ptr.reset(new Self(0));
return *safe_x_ptr.get();
#else
static Self x = Self(0);
return x;
#endif
CGAL_STATIC_THREAD_LOCAL_VARIABLE(Self, x, 0);
return x;
}
public:

View File

@ -35,7 +35,7 @@
#include <boost/optional.hpp>
#ifdef CGAL_HAS_THREADS
#include <boost/thread/mutex.hpp>
#include <CGAL/mutex.h>
#endif
namespace CGAL {
@ -100,7 +100,7 @@ private:
#ifdef CGAL_HAS_THREADS
mutable boost::mutex building_mutex;//mutex used to protect const calls inducing build()
mutable CGAL_MUTEX building_mutex;//mutex used to protect const calls inducing build()
#endif
bool built_;
@ -284,7 +284,7 @@ private:
void const_build() const {
#ifdef CGAL_HAS_THREADS
//this ensure that build() will be called once
boost::mutex::scoped_lock scoped_lock(building_mutex);
CGAL_SCOPED_LOCK(building_mutex);
if(!is_built())
#endif
const_cast<Self*>(this)->build(); //THIS IS NOT THREADSAFE

View File

@ -51,14 +51,6 @@
#include <CGAL/internal/Triangulation_ds_iterators_3.h>
#include <CGAL/internal/Triangulation_ds_circulators_3.h>
#ifdef CGAL_HAS_THREADS
# ifdef CGAL_LINKED_WITH_TBB
# include <tbb/enumerable_thread_specific.h>
# else
# include <boost/thread/tss.hpp>
# endif
#endif
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/scalable_allocator.h>
#endif

View File

@ -31,7 +31,7 @@
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
#include <CGAL/Spatial_sort_traits_adapter_2.h>
#include <CGAL/internal/info_check.h>
#include <CGAL/tss.h>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/mpl/and.hpp>
@ -1053,27 +1053,11 @@ remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit)
afi++) *fit++ = afi;
}
else {
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< int > maxd_ptr;
static boost::thread_specific_ptr< std::vector<Face_handle> > f_ptr;
static boost::thread_specific_ptr< std::vector<int> > i_ptr;
static boost::thread_specific_ptr< std::vector<Vertex_handle> > w_ptr;
if (maxd_ptr.get() == NULL) {
maxd_ptr.reset(new int(30));
f_ptr.reset(new std::vector<Face_handle>(*maxd_ptr));
i_ptr.reset(new std::vector<int>(*maxd_ptr));
w_ptr.reset(new std::vector<Vertex_handle>(*maxd_ptr));
}
int& maxd=*maxd_ptr;
std::vector<Face_handle>& f=*f_ptr;
std::vector<int>& i=*i_ptr;
std::vector<Vertex_handle>& w=*w_ptr;
#else
static int maxd=30;
static std::vector<Face_handle> f(maxd);
static std::vector<int> i(maxd);
static std::vector<Vertex_handle> w(maxd);
#endif
CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, maxd,30);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Face_handle> , f, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<int>, i, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Vertex_handle>, w, maxd);
int d;
remove_degree_init(v,f,w,i,d,maxd);
remove_degree_triangulate(v,f,w,i,d);
@ -1097,27 +1081,11 @@ remove(Vertex_handle v)
if ( this->dimension() <= 1) { Triangulation::remove(v); return; }
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< int > maxd_ptr;
static boost::thread_specific_ptr< std::vector<Face_handle> > f_ptr;
static boost::thread_specific_ptr< std::vector<int> > i_ptr;
static boost::thread_specific_ptr< std::vector<Vertex_handle> > w_ptr;
if (maxd_ptr.get() == NULL) {
maxd_ptr.reset(new int(30));
f_ptr.reset(new std::vector<Face_handle>(*maxd_ptr));
i_ptr.reset(new std::vector<int>(*maxd_ptr));
w_ptr.reset(new std::vector<Vertex_handle>(*maxd_ptr));
}
int& maxd=*maxd_ptr;
std::vector<Face_handle>& f=*f_ptr;
std::vector<int>& i=*i_ptr;
std::vector<Vertex_handle>& w=*w_ptr;
#else
static int maxd=30;
static std::vector<Face_handle> f(maxd);
static std::vector<int> i(maxd);
static std::vector<Vertex_handle> w(maxd);
#endif
CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, maxd,30);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Face_handle> , f, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<int>, i, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Vertex_handle>, w, maxd);
remove_degree_init(v,f,w,i,d,maxd);
if (d == 0) return; // dim is going down
remove_degree_triangulate(v,f,w,i,d);
@ -2260,27 +2228,11 @@ move_if_no_collision(Vertex_handle v, const Point &p) {
{
int d;
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< int > maxd_ptr;
static boost::thread_specific_ptr< std::vector<Face_handle> > f_ptr;
static boost::thread_specific_ptr< std::vector<int> > i_ptr;
static boost::thread_specific_ptr< std::vector<Vertex_handle> > w_ptr;
if (maxd_ptr.get() == NULL) {
maxd_ptr.reset(new int(30));
f_ptr.reset(new std::vector<Face_handle>(*maxd_ptr));
i_ptr.reset(new std::vector<int>(*maxd_ptr));
w_ptr.reset(new std::vector<Vertex_handle>(*maxd_ptr));
}
int& maxd=*maxd_ptr;
std::vector<Face_handle>& f=*f_ptr;
std::vector<int>& i=*i_ptr;
std::vector<Vertex_handle>& w=*w_ptr;
#else
static int maxd=30;
static std::vector<Face_handle> f(maxd);
static std::vector<int> i(maxd);
static std::vector<Vertex_handle> w(maxd);
#endif
CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, maxd,30);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Face_handle> , f, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<int>, i, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Vertex_handle>, w, maxd);
remove_degree_init(v,f,w,i,d,maxd);
remove_degree_triangulate(v,f,w,i,d);
}
@ -2494,27 +2446,11 @@ move_if_no_collision_and_give_new_faces(Vertex_handle v,
{
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< int > maxd_ptr;
static boost::thread_specific_ptr< std::vector<Face_handle> > f_ptr;
static boost::thread_specific_ptr< std::vector<int> > i_ptr;
static boost::thread_specific_ptr< std::vector<Vertex_handle> > w_ptr;
if (maxd_ptr.get() == NULL) {
maxd_ptr.reset(new int(30));
f_ptr.reset(new std::vector<Face_handle>(*maxd_ptr));
i_ptr.reset(new std::vector<int>(*maxd_ptr));
w_ptr.reset(new std::vector<Vertex_handle>(*maxd_ptr));
}
int& maxd=*maxd_ptr;
std::vector<Face_handle>& f=*f_ptr;
std::vector<int>& i=*i_ptr;
std::vector<Vertex_handle>& w=*w_ptr;
#else
static int maxd=30;
static std::vector<Face_handle> f(maxd);
static std::vector<int> i(maxd);
static std::vector<Vertex_handle> w(maxd);
#endif
CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, maxd,30);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Face_handle> , f, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<int>, i, maxd);
CGAL_STATIC_THREAD_LOCAL_VARIABLE(std::vector<Vertex_handle>, w, maxd);
int d;
remove_degree_init(v,f,w,i,d,maxd);
remove_degree_triangulate(v,f,w,i,d);