Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Nektar
Nektar
Commits
48c3a4c0
Commit
48c3a4c0
authored
Apr 02, 2019
by
Dave Moxey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-enable thread safe mutexes only if NEKTAR_USE_THREAD_SAFETY is enabled
parent
8d4fd72a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
121 additions
and
3 deletions
+121
-3
CMakeLists.txt
CMakeLists.txt
+8
-0
library/LibUtilities/BasicUtils/NekFactory.hpp
library/LibUtilities/BasicUtils/NekFactory.hpp
+44
-1
library/LibUtilities/BasicUtils/NekManager.hpp
library/LibUtilities/BasicUtils/NekManager.hpp
+45
-0
library/LibUtilities/BasicUtils/Vmath.cpp
library/LibUtilities/BasicUtils/Vmath.cpp
+8
-0
library/LibUtilities/Memory/ThreadSpecificPool.hpp
library/LibUtilities/Memory/ThreadSpecificPool.hpp
+16
-2
No files found.
CMakeLists.txt
View file @
48c3a4c0
...
...
@@ -169,6 +169,14 @@ OPTION(NEKTAR_USE_MEMORY_POOLS
"Use memory pools to accelerate memory allocation."
ON
)
MARK_AS_ADVANCED
(
NEKTAR_USE_MEMORY_POOLS
)
# Thread safety
OPTION
(
NEKTAR_USE_THREAD_SAFETY
"Guarantee thread safety in certain core Nektar++ classes."
OFF
)
MARK_AS_ADVANCED
(
NEKTAR_USE_THREAD_SAFETY
)
IF
(
NEKTAR_USE_THREAD_SAFETY
)
ADD_DEFINITIONS
(
-DNEKTAR_USE_THREAD_SAFETY
)
ENDIF
()
IF
(
MSVC
)
# Needed for M_PI to be visible in visual studio.
ADD_DEFINITIONS
(
-D_USE_MATH_DEFINES
)
...
...
library/LibUtilities/BasicUtils/NekFactory.hpp
View file @
48c3a4c0
...
...
@@ -41,6 +41,11 @@
#include <string>
#include <memory>
#ifdef NEKTAR_USE_THREAD_SAFETY
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
#endif
#include <LibUtilities/BasicUtils/ErrorUtil.hpp>
namespace
Nektar
...
...
@@ -48,6 +53,12 @@ namespace Nektar
namespace
LibUtilities
{
#ifdef NEKTAR_USE_THREAD_SAFETY
// Generate parameter typenames with default type of 'none'
typedef
boost
::
unique_lock
<
boost
::
shared_mutex
>
WriteLock
;
typedef
boost
::
shared_lock
<
boost
::
shared_mutex
>
ReadLock
;
#endif
/**
* @class NekFactory
*
...
...
@@ -121,7 +132,7 @@ public:
typedef
std
::
map
<
tKey
,
ModuleEntry
,
tPredicator
>
TMapFactory
;
public:
NekFactory
()
{}
NekFactory
()
=
default
;
/**
* @brief Create an instance of the class referred to by \c idKey.
...
...
@@ -134,6 +145,10 @@ public:
*/
tBaseSharedPtr
CreateInstance
(
tKey
idKey
,
tParam
...
args
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
vReadLock
(
m_mutex
);
#endif
// Now try and find the key in the map.
auto
it
=
getMapFactory
()
->
find
(
idKey
);
...
...
@@ -142,6 +157,9 @@ public:
if
(
it
!=
getMapFactory
()
->
end
())
{
ModuleEntry
*
tmp
=
&
(
it
->
second
);
#ifdef NEKTAR_USE_THREAD_SAFETY
vReadLock
.
unlock
();
#endif
if
(
tmp
->
m_func
)
{
...
...
@@ -183,6 +201,10 @@ public:
tKey
RegisterCreatorFunction
(
tKey
idKey
,
CreatorFunction
classCreator
,
tDescription
pDesc
=
""
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
WriteLock
vWriteLock
(
m_mutex
);
#endif
ModuleEntry
e
(
classCreator
,
pDesc
);
getMapFactory
()
->
insert
(
std
::
pair
<
tKey
,
ModuleEntry
>
(
idKey
,
e
));
return
idKey
;
...
...
@@ -194,6 +216,10 @@ public:
*/
bool
ModuleExists
(
tKey
idKey
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
vReadLock
(
m_mutex
);
#endif
// Now try and find the key in the map.
auto
it
=
getMapFactory
()
->
find
(
idKey
);
...
...
@@ -210,6 +236,10 @@ public:
*/
void
PrintAvailableClasses
(
std
::
ostream
&
pOut
=
std
::
cout
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
vReadLock
(
m_mutex
);
#endif
pOut
<<
std
::
endl
<<
"Available classes: "
<<
std
::
endl
;
for
(
auto
&
it
:
*
getMapFactory
())
{
...
...
@@ -232,6 +262,10 @@ public:
*/
tKey
GetKey
(
tDescription
pDesc
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
vReadLock
(
m_mutex
);
#endif
for
(
auto
&
it
:
*
getMapFactory
())
{
if
(
it
.
second
.
m_desc
==
pDesc
)
...
...
@@ -251,6 +285,10 @@ public:
*/
std
::
string
GetClassDescription
(
tKey
idKey
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
vReadLock
(
m_mutex
);
#endif
// Now try and find the key in the map.
auto
it
=
getMapFactory
()
->
find
(
idKey
);
...
...
@@ -275,6 +313,11 @@ private:
NekFactory
&
operator
=
(
const
NekFactory
&
rhs
);
TMapFactory
mMapFactory
;
#ifdef NEKTAR_USE_THREAD_SAFETY
boost
::
shared_mutex
m_mutex
;
#endif
};
}
...
...
library/LibUtilities/BasicUtils/NekManager.hpp
View file @
48c3a4c0
...
...
@@ -40,6 +40,11 @@
#include <memory>
#include <functional>
#ifdef NEKTAR_USE_THREAD_SAFETY
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
#endif
#include <LibUtilities/BasicUtils/ErrorUtil.hpp>
namespace
Nektar
...
...
@@ -48,6 +53,11 @@ namespace Nektar
{
using
namespace
std
;
#ifdef NEKTAR_USE_THREAD_SAFETY
typedef
boost
::
unique_lock
<
boost
::
shared_mutex
>
WriteLock
;
typedef
boost
::
shared_lock
<
boost
::
shared_mutex
>
ReadLock
;
#endif
template
<
typename
KeyType
>
struct
defOpLessCreator
{
...
...
@@ -110,6 +120,9 @@ namespace Nektar
{
if
(
!
whichPool
.
empty
())
{
#ifdef NEKTAR_USE_THREAD_SAFETY
ReadLock
v_rlock
(
m_mutex
);
// reading static members
#endif
auto
iter
=
m_ValueContainerPool
.
find
(
whichPool
);
if
(
iter
!=
m_ValueContainerPool
.
end
())
{
...
...
@@ -118,6 +131,17 @@ namespace Nektar
}
else
{
#ifdef NEKTAR_USE_THREAD_SAFETY
v_rlock
.
unlock
();
// now writing static members. Apparently
// upgrade_lock has less desirable properties than
// just dropping read lock, grabbing write lock.
// write will block until all reads are done, but
// reads cannot be acquired if write lock is
// blocking. In this context writes are supposed to
// be rare.
WriteLock
v_wlock
(
m_mutex
);
#endif
m_values
=
ValueContainerShPtr
(
new
ValueContainer
);
m_ValueContainerPool
[
whichPool
]
=
m_values
;
if
(
m_managementEnabledContainerPool
.
find
(
whichPool
)
==
m_managementEnabledContainerPool
.
end
())
...
...
@@ -222,6 +246,9 @@ namespace Nektar
{
if
(
!
whichPool
.
empty
())
{
#ifdef NEKTAR_USE_THREAD_SAFETY
WriteLock
v_wlock
(
m_mutex
);
#endif
auto
x
=
m_ValueContainerPool
.
find
(
whichPool
);
ASSERTL1
(
x
!=
m_ValueContainerPool
.
end
(),
"Could not find pool "
+
whichPool
);
...
...
@@ -229,6 +256,10 @@ namespace Nektar
}
else
{
#ifdef NEKTAR_USE_THREAD_SAFETY
WriteLock
v_wlock
(
m_mutex
);
#endif
for
(
auto
&
x
:
m_ValueContainerPool
)
{
x
.
second
->
clear
();
...
...
@@ -251,6 +282,10 @@ namespace Nektar
{
if
(
!
whichPool
.
empty
())
{
#ifdef NEKTAR_USE_THREAD_SAFETY
WriteLock
v_wlock
(
m_mutex
);
#endif
auto
x
=
m_managementEnabledContainerPool
.
find
(
whichPool
);
if
(
x
!=
m_managementEnabledContainerPool
.
end
())
{
...
...
@@ -267,6 +302,9 @@ namespace Nektar
{
if
(
!
whichPool
.
empty
())
{
#ifdef NEKTAR_USE_THREAD_SAFETY
WriteLock
v_wlock
(
m_mutex
);
#endif
auto
x
=
m_managementEnabledContainerPool
.
find
(
whichPool
);
if
(
x
!=
m_managementEnabledContainerPool
.
end
())
{
...
...
@@ -289,9 +327,16 @@ namespace Nektar
static
FlagContainerPool
m_managementEnabledContainerPool
;
CreateFuncType
m_globalCreateFunc
;
CreateFuncContainer
m_keySpecificCreateFuncs
;
#ifdef NEKTAR_USE_THREAD_SAFETY
static
boost
::
shared_mutex
m_mutex
;
#endif
};
template
<
typename
KeyType
,
typename
ValueT
,
typename
opLessCreator
>
typename
NekManager
<
KeyType
,
ValueT
,
opLessCreator
>::
ValueContainerPool
NekManager
<
KeyType
,
ValueT
,
opLessCreator
>::
m_ValueContainerPool
;
template
<
typename
KeyType
,
typename
ValueT
,
typename
opLessCreator
>
typename
NekManager
<
KeyType
,
ValueT
,
opLessCreator
>::
FlagContainerPool
NekManager
<
KeyType
,
ValueT
,
opLessCreator
>::
m_managementEnabledContainerPool
;
#ifdef NEKTAR_USE_THREAD_SAFETY
template
<
typename
KeyType
,
typename
ValueT
,
typename
opLessCreator
>
typename
boost
::
shared_mutex
NekManager
<
KeyType
,
ValueT
,
opLessCreator
>::
m_mutex
;
#endif
}
}
...
...
library/LibUtilities/BasicUtils/Vmath.cpp
View file @
48c3a4c0
...
...
@@ -131,12 +131,20 @@ namespace Vmath
#undef EPS
#undef RNMX
#ifdef NEKTAR_USE_THREAD_SAFETY
static
boost
::
mutex
mutex
;
#endif
template
LIB_UTILITIES_EXPORT
Nektar
::
NekDouble
ran2
(
long
*
idum
);
/// \brief Fills a vector with white noise.
template
<
class
T
>
void
FillWhiteNoise
(
int
n
,
const
T
eps
,
T
*
x
,
const
int
incx
,
int
outseed
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
// Protect the static vars here and in ran2
boost
::
mutex
::
scoped_lock
l
(
mutex
);
#endif
// Define static variables for generating random numbers
static
int
iset
=
0
;
static
T
gset
;
...
...
library/LibUtilities/Memory/ThreadSpecificPool.hpp
View file @
48c3a4c0
...
...
@@ -44,6 +44,10 @@
#include <LibUtilities/BasicUtils/ErrorUtil.hpp>
#include <LibUtilities/LibUtilitiesDeclspec.h>
#ifdef NEKTAR_USE_THREAD_SAFETY
#include <boost/thread/mutex.hpp>
#endif
#include <cstring>
namespace
Nektar
...
...
@@ -80,8 +84,9 @@ namespace Nektar
m_pool
(),
m_blockSize
(
ByteSize
)
{
// We can do the new in the constructor list because the thread specific
// pointer doesn't have a supporting constructor.
// We can't do the new in the constructor list because the
// thread specific pointer doesn't have a supporting
// constructor.
m_pool
=
new
boost
::
pool
<>
(
m_blockSize
);
}
...
...
@@ -96,6 +101,9 @@ namespace Nektar
/// \throw std::bad_alloc if memory is exhausted.
void
*
Allocate
()
{
#ifdef NEKTAR_USE_THREAD_SAFETY
boost
::
mutex
::
scoped_lock
l
(
m_mutex
);
#endif
void
*
result
=
m_pool
->
malloc
();
#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
...
...
@@ -111,6 +119,9 @@ namespace Nektar
/// from this pool. Doing this will result in undefined behavior.
void
Deallocate
(
const
void
*
p
)
{
#ifdef NEKTAR_USE_THREAD_SAFETY
boost
::
mutex
::
scoped_lock
l
(
m_mutex
);
#endif
#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
// The idea here is to fill the returned memory with some known
// pattern, then detect that pattern on the allocate. If the
...
...
@@ -129,6 +140,9 @@ namespace Nektar
//boost::thread_specific_ptr<boost::pool<> > m_pool;
boost
::
pool
<>*
m_pool
;
size_t
m_blockSize
;
#ifdef NEKTAR_USE_THREAD_SAFETY
boost
::
mutex
m_mutex
;
#endif
};
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment