2
0
mirror of https://github.com/boostorg/thread.git synced 2026-01-23 06:02:14 +00:00

merged from trunk

[SVN r45503]
This commit is contained in:
Eric Niebler
2008-05-18 23:31:14 +00:00
parent c619569a81
commit aaee6da3b6
3 changed files with 305 additions and 2 deletions

View File

@@ -631,6 +631,264 @@ namespace boost
typedef typename base::bool_type bool_type;
using base::operator bool_type;
};
template<typename MutexType1,typename MutexType2>
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
{
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
if(!l1)
{
return 1;
}
if(!m2.try_lock())
{
return 2;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3>
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3)
{
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
if(!l1)
{
return 1;
}
if(unsigned const failed_lock=try_lock_internal(m2,m3))
{
return failed_lock+1;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4>
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4)
{
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
if(!l1)
{
return 1;
}
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
{
return failed_lock+1;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4,typename MutexType5>
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4,MutexType5& m5)
{
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
if(!l1)
{
return 1;
}
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
{
return failed_lock+1;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2>
unsigned lock_helper(MutexType1& m1,MutexType2& m2)
{
boost::unique_lock<MutexType1> l1(m1);
if(!m2.try_lock())
{
return 1;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3>
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3)
{
boost::unique_lock<MutexType1> l1(m1);
if(unsigned const failed_lock=try_lock_internal(m2,m3))
{
return failed_lock;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4>
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4)
{
boost::unique_lock<MutexType1> l1(m1);
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
{
return failed_lock;
}
l1.release();
return 0;
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4,typename MutexType5>
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4,MutexType5& m5)
{
boost::unique_lock<MutexType1> l1(m1);
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
{
return failed_lock;
}
l1.release();
return 0;
}
}
template<typename MutexType1,typename MutexType2>
void lock(MutexType1& m1,MutexType2& m2)
{
unsigned const lock_count=2;
unsigned lock_first=0;
while(true)
{
switch(lock_first)
{
case 0:
lock_first=detail::lock_helper(m1,m2);
if(!lock_first)
return;
break;
case 1:
lock_first=detail::lock_helper(m2,m1);
if(!lock_first)
return;
lock_first=(lock_first+1)%lock_count;
break;
}
}
}
template<typename MutexType1,typename MutexType2,typename MutexType3>
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
{
unsigned const lock_count=3;
unsigned lock_first=0;
while(true)
{
switch(lock_first)
{
case 0:
lock_first=detail::lock_helper(m1,m2,m3);
if(!lock_first)
return;
break;
case 1:
lock_first=detail::lock_helper(m2,m3,m1);
if(!lock_first)
return;
lock_first=(lock_first+1)%lock_count;
break;
case 2:
lock_first=detail::lock_helper(m3,m1,m2);
if(!lock_first)
return;
lock_first=(lock_first+2)%lock_count;
break;
}
}
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4>
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4)
{
unsigned const lock_count=4;
unsigned lock_first=0;
while(true)
{
switch(lock_first)
{
case 0:
lock_first=detail::lock_helper(m1,m2,m3,m4);
if(!lock_first)
return;
break;
case 1:
lock_first=detail::lock_helper(m2,m3,m4,m1);
if(!lock_first)
return;
lock_first=(lock_first+1)%lock_count;
break;
case 2:
lock_first=detail::lock_helper(m3,m4,m1,m2);
if(!lock_first)
return;
lock_first=(lock_first+2)%lock_count;
break;
case 3:
lock_first=detail::lock_helper(m4,m1,m2,m3);
if(!lock_first)
return;
lock_first=(lock_first+3)%lock_count;
break;
}
}
}
template<typename MutexType1,typename MutexType2,typename MutexType3,
typename MutexType4,typename MutexType5>
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
MutexType4& m4,MutexType5& m5)
{
unsigned const lock_count=5;
unsigned lock_first=0;
while(true)
{
switch(lock_first)
{
case 0:
lock_first=detail::lock_helper(m1,m2,m3,m4,m5);
if(!lock_first)
return;
break;
case 1:
lock_first=detail::lock_helper(m2,m3,m4,m5,m1);
if(!lock_first)
return;
lock_first=(lock_first+1)%lock_count;
break;
case 2:
lock_first=detail::lock_helper(m3,m4,m5,m1,m2);
if(!lock_first)
return;
lock_first=(lock_first+2)%lock_count;
break;
case 3:
lock_first=detail::lock_helper(m4,m5,m1,m2,m3);
if(!lock_first)
return;
lock_first=(lock_first+3)%lock_count;
break;
case 4:
lock_first=detail::lock_helper(m5,m1,m2,m3,m4);
if(!lock_first)
return;
lock_first=(lock_first+4)%lock_count;
break;
}
}
}
}

View File

@@ -174,13 +174,18 @@ namespace boost
{
F f;
#ifdef BOOST_HAS_RVALUE_REFS
thread_data(F&& f_):
f(static_cast<F&&>(f_))
{}
#else
thread_data(F f_):
f(f_)
{}
thread_data(detail::thread_move_t<F> f_):
f(f_)
{}
#endif
void run()
{
f();
@@ -201,27 +206,50 @@ namespace boost
detail::thread_data_ptr get_thread_info() const;
#ifdef BOOST_HAS_RVALUE_REFS
template<typename F>
static inline detail::thread_data_ptr make_thread_info(F&& f)
{
return detail::heap_new<thread_data<F> >(static_cast<F&&>(f));
}
#else
template<typename F>
static inline detail::thread_data_ptr make_thread_info(F f)
{
return detail::heap_new<thread_data<F> >(f);
}
template<typename F>
static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f)
{
return detail::heap_new<thread_data<F> >(f);
}
#endif
public:
thread();
~thread();
#ifdef BOOST_HAS_RVALUE_REFS
template <class F>
thread(F&& f):
thread_info(make_thread_info(static_cast<F&&>(f)))
{
start_thread();
}
#else
template <class F>
explicit thread(F f):
thread_info(make_thread_info(f))
{
start_thread();
}
template <class F>
thread(detail::thread_move_t<F> f):
thread_info(make_thread_info(f))
{
start_thread();
}
#endif
template <class F,class A1>
thread(F f,A1 a1):

View File

@@ -84,6 +84,23 @@ namespace boost
}
}
#ifdef BOOST_HAS_RVALUE_REFS
template<typename T,typename A1>
T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
catch(...)
{
free_raw_heap_memory(heap_memory);
throw;
}
}
#else
template<typename T,typename A1>
T* heap_new(A1 a1)
{
@@ -99,7 +116,7 @@ namespace boost
throw;
}
}
#endif
template<typename T,typename A1,typename A2>
T* heap_new(A1 a1,A2 a2)
{