CGAL_Core MemoryPool<T> will always use Boost.Thread with g++

Because of bug in gcc, even if the C++11 `thread_local` keyword can be
used, it cannot be used for the TLS static member of the class template
`MemoryPool<T>`. That triggers a bug in gcc (tested with g++ 6.3.1):
```
.../include/CGAL/CORE/MemoryPool.h:113:25: error: redefinition of 'bool __tls_guard'
 MemoryPool<T, nObjects> MemoryPool<T, nObjects>::memPool;
                         ^~~~~~~~~~~~~~~~~~~~~~~
.../include/CGAL/CORE/MemoryPool.h:113:25: note: 'bool __tls_guard' previously declared here
.../include/CGAL/CORE/MemoryPool.h:113: confused by earlier errors, bailing out
Preprocessed source stored into /tmp/cc4xCWuR.out file, please attach this to your bugreport.
```

The bug seems to be from g++ >= 5:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54948
This commit is contained in:
Laurent Rineau 2017-02-08 17:05:13 +01:00
parent 4e1b250b9c
commit b73a88babc
4 changed files with 26 additions and 7 deletions

View File

@ -34,10 +34,19 @@
#ifndef _CORE_MEMORYPOOL_H_ #ifndef _CORE_MEMORYPOOL_H_
#define _CORE_MEMORYPOOL_H_ #define _CORE_MEMORYPOOL_H_
#include <CGAL/config.h>
#include <CGAL/tss.h>
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS)&&__GNUC__)
// Force the use of Boost.Thread with g++ and C++11, because of the PR66944
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66944
// See also CGAL PR #1888
// https://github.com/CGAL/cgal/pull/1888#issuecomment-278284232
# include <boost/thread/tss.hpp>
#endif
#include <new> // for placement new #include <new> // for placement new
#include <cassert> #include <cassert>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <CGAL/tss.h>
#include <vector> #include <vector>
namespace CORE { namespace CORE {
@ -81,7 +90,7 @@ public:
// Access the corresponding static global allocator. // Access the corresponding static global allocator.
static MemoryPool<T,nObjects>& global_allocator() { static MemoryPool<T,nObjects>& global_allocator() {
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST #if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS)&&__GNUC__)
if(memPool_ptr.get() == NULL) {memPool_ptr.reset(new Self());} if(memPool_ptr.get() == NULL) {memPool_ptr.reset(new Self());}
Self& memPool = * memPool_ptr.get(); Self& memPool = * memPool_ptr.get();
#endif #endif
@ -92,7 +101,7 @@ private:
Thunk* head; // next available block in the pool Thunk* head; // next available block in the pool
std::vector<void*> blocks; std::vector<void*> blocks;
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST #if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS)&&__GNUC__)
static boost::thread_specific_ptr<Self> memPool_ptr; static boost::thread_specific_ptr<Self> memPool_ptr;
#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation #elif defined(CGAL_HAS_THREADS) // use the C++11 implementation
static thread_local Self memPool; static thread_local Self memPool;
@ -101,7 +110,7 @@ private:
#endif // not CGAL_HAS_THREADS #endif // not CGAL_HAS_THREADS
}; };
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST #if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS)&&__GNUC__)
template <class T, int nObjects > template <class T, int nObjects >
boost::thread_specific_ptr<MemoryPool<T, nObjects> > boost::thread_specific_ptr<MemoryPool<T, nObjects> >
MemoryPool<T, nObjects>::memPool_ptr; MemoryPool<T, nObjects>::memPool_ptr;

View File

@ -299,7 +299,7 @@ We next list the libraries and essential 3rd party software
| Library | CMake Variable | Functionality | Dependencies | | Library | CMake Variable | Functionality | Dependencies |
| :-------- | :------------- | :------------ | :----------- | | :-------- | :------------- | :------------ | :----------- |
| `%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` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers), Boost.Thread and Boost.System (library) for compilers not supporting the keywords `thread_local` and the class `std::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_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_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} | | `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \sc{Qt}5-based demos | \sc{Qt}5 and \sc{OpenGL} |
@ -372,7 +372,11 @@ installed as binaries.
\cgal requires the \sc{Boost} libraries. In particular the header files \cgal requires the \sc{Boost} libraries. In particular the header files
and the threading library (`Boost.Thread` and 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). for compilers not supporting the keyword `thread_local` and the class `std::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).
As an exception, because of a bug in the \gcc compiler about the \cpp 11
keyword `thread_local`, the `CGAL_Core` library always requires
`Boost.Thread` if the \gcc compiler is used.
On Windows, as auto-linking is used, you also need the binaries of On Windows, as auto-linking is used, you also need the binaries of
`Boost.Serialization` and `Boost.DateTime`, but the `Boost.Serialization` and `Boost.DateTime`, but the

View File

@ -147,6 +147,9 @@ and <code>src/</code> directories).
valid commercial license for the packages they used. This can also be used valid commercial license for the packages they used. This can also be used
to make sure only LGPL header files are used. to make sure only LGPL header files are used.
</li> </li>
<li>Because of a bug in the g++ compiler about the C++11
keyword <code>thread_local</code>, the CGAL_Core library now always
requires <code>Boost.Thread</code> if the g++ compiler is used.</li>
</ul> </ul>
<!-- New packages --> <!-- New packages -->

View File

@ -279,7 +279,10 @@ if( NOT CGAL_MACROS_FILE_INCLUDED )
add_to_list( CGAL_3RD_PARTY_DEFINITIONS ${CGAL_${component}_3RD_PARTY_DEFINITIONS} ) add_to_list( CGAL_3RD_PARTY_DEFINITIONS ${CGAL_${component}_3RD_PARTY_DEFINITIONS} )
add_to_list( CGAL_3RD_PARTY_LIBRARIES_DIRS ${CGAL_${component}_3RD_PARTY_LIBRARIES_DIRS} ) add_to_list( CGAL_3RD_PARTY_LIBRARIES_DIRS ${CGAL_${component}_3RD_PARTY_LIBRARIES_DIRS} )
# Nothing to add for Core if (${component} STREQUAL "Core")
find_package( Boost 1.48 REQUIRED thread system )
add_to_list( CGAL_3RD_PARTY_LIBRARIES ${Boost_LIBRARIES} )
endif()
if (${component} STREQUAL "ImageIO") if (${component} STREQUAL "ImageIO")
find_package( ZLIB QUIET ) find_package( ZLIB QUIET )