-//$$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/int_algo.h>
-
+#include <cds/algo/int_algo.h>
#include <boost/mpl/if.hpp>
namespace cds { namespace lock {
: 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
// Only for internal use!!!
array()
- : m_arrLocks( null_ptr<lock_type *>() )
+ : m_arrLocks( nullptr )
, m_nCapacity(0)
{}
array( select_cell_policy const& policy )
- : m_arrLocks( null_ptr<lock_type *>() )
+ : m_arrLocks( nullptr )
, m_nCapacity(0)
, m_SelectCellPolicy( policy )
{}
array(
size_t nCapacity ///< [in] Array size
)
- : m_arrLocks( null_ptr<lock_type *>() )
+ : m_arrLocks( nullptr )
, m_nCapacity( nCapacity )
{
m_arrLocks = create_lock_array( nCapacity );
size_t nCapacity, ///< [in] Array size
select_cell_policy const& policy ///< Cell selection policy (copy-constructible)
)
- : m_arrLocks( null_ptr<lock_type *>() )
+ : m_arrLocks( nullptr )
, m_nCapacity( nCapacity )
, m_SelectCellPolicy( policy )
{
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.
size_t nCapacity, ///< [in] Array size
select_cell_policy&& policy ///< Cell selection policy (move-constructible)
)
- : m_arrLocks( null_ptr<lock_type *>() )
+ : m_arrLocks( nullptr )
, m_nCapacity( nCapacity )
, m_SelectCellPolicy( std::forward<select_cell_policy>( policy ))
{
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