-//$$CDS-header$$
+//$$CDS-header$$-2
#ifndef __CDS_LOCK_ARRAY_H
#define __CDS_LOCK_ARRAY_H
+#include <mutex> //unique_lock
#include <cds/details/allocator.h>
-#include <cds/lock/scoped_lock.h>
#include <cds/algo/int_algo.h>
-#include <boost/mpl/if.hpp>
-
namespace cds { namespace lock {
/// Trivial lock \ref array selection policy
: m_nMask( src.m_nMask )
{}
-# ifdef CDS_RVALUE_SUPPORT
/// Move constructor
pow2_select_policy( pow2_select_policy&& src )
: m_nMask( src.m_nMask )
{}
-# endif
/// Returns <tt>nWhat & (nPow2 - 1)</tt>
size_t operator()( size_t nWhat, size_t ) const
can be simultaneous.
Template arguments:
- - \p Lock - lock type, for example, \p boost::mutex, \p cds::lock::Spinlock
+ - \p Lock - lock type, for example, \p std::mutex, \p cds::lock::Spinlock
- \p SelectPolicy - array cell selection policy, the default is \ref mod_select_policy
Available policies: \ref trivial_select_policy, \ref pow2_select_policy, \ref mod_select_policy.
- \p Alloc - memory allocator for array
m_arrLocks = create_lock_array( m_nCapacity );
}
-# ifdef CDS_RVALUE_SUPPORT
/// Constructs array of lock and move cell selection policy
/**
Allocates the array and initializes all locks as unlocked.
{
m_arrLocks = create_lock_array( m_nCapacity );
}
-# endif
/// Destructs array of locks and frees used memory
~array()
{
size_t nCell = m_SelectCellPolicy( hint, size() );
assert( nCell < size() );
- lock_type& l = m_arrLocks[ nCell ];
- l.lock();
+ m_arrLocks[nCell].lock();
return nCell;
}
{
size_t nCell = m_SelectCellPolicy( hint, size() );
assert( nCell < size() );
- lock_type& l = m_arrLocks[ nCell ];
- if ( l.try_lock() )
+ if ( m_arrLocks[nCell].try_lock() )
return nCell;
return c_nUnspecifiedCell;
}
void lock_all()
{
lock_type * pLock = m_arrLocks;
- for ( size_t i = 0; i < size(); ++i, ++pLock )
+ for ( lock_type * pEnd = m_arrLocks + size(); pLock != pEnd; ++pLock )
pLock->lock();
}
void unlock_all()
{
lock_type * pLock = m_arrLocks;
- for ( size_t i = 0; i < size(); ++i, ++pLock )
+ for ( lock_type * pEnd = m_arrLocks + size(); pLock != pEnd; ++pLock )
pLock->unlock();
}
}
};
+}} // namespace cds::lock
+
+//@cond
+namespace std {
+
/// Specialization \ref scoped_lock for lock::array
template <typename Lock, typename SelectPolicy, class Alloc>
- class scoped_lock< cds::lock::array< Lock, SelectPolicy, Alloc > >: public cds::details::noncopyable
+ class unique_lock< cds::lock::array< Lock, SelectPolicy, Alloc > >
{
public:
- typedef cds::lock::array< Lock, SelectPolicy, Alloc > lock_array_type ; ///< Lock array type
+ typedef cds::lock::array< Lock, SelectPolicy, Alloc > lock_array_type; ///< Lock array type
private:
- //@cond
lock_array_type& m_arrLocks;
size_t m_nLockGuarded;
- static const size_t c_nLockAll = ~size_t(0);
- //@endcond
+ static const size_t c_nLockAll = ~size_t( 0 );
public:
/// Onws the lock array \p arrLocks and locks a cell determined by \p hint parameter
template <typename Q>
- scoped_lock( lock_array_type& arrLocks, Q const& hint )
+ unique_lock( lock_array_type& arrLocks, Q const& hint )
: m_arrLocks( arrLocks )
- , m_nLockGuarded( arrLocks.lock( hint ))
+ , m_nLockGuarded( arrLocks.lock( hint ) )
{}
/// Locks all from \p arrLocks array
- scoped_lock( lock_array_type& arrLocks )
+ unique_lock( lock_array_type& arrLocks )
: m_arrLocks( arrLocks )
, m_nLockGuarded( c_nLockAll )
{
arrLocks.lock_all();
}
- ~scoped_lock()
+ unique_lock() = delete;
+ unique_lock( unique_lock const& ) = delete;
+
+ ~unique_lock()
{
if ( m_nLockGuarded == c_nLockAll )
m_arrLocks.unlock_all();
m_arrLocks.unlock( m_nLockGuarded );
}
};
-
-}} // namespace cds::lock
+} // namespace std
+//@endcond
#endif // #ifndef __CDS_LOCK_ARRAY_H