mirror of
https://git.suyu.dev/suyu/ext-boost.git
synced 2025-12-30 19:24:38 +01:00
externals: Update boost to 1.72 and add Boost Context
This commit is contained in:
parent
5e8300b76a
commit
77abe07b3b
618 changed files with 96299 additions and 14263 deletions
468
boost/thread/lock_algorithms.hpp
Normal file
468
boost/thread/lock_algorithms.hpp
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
|
||||
#ifndef BOOST_THREAD_LOCK_ALGORITHMS_HPP
|
||||
#define BOOST_THREAD_LOCK_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
#include <boost/thread/lockable_traits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool x>
|
||||
struct is_mutex_type_wrapper
|
||||
{
|
||||
};
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
void lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
|
||||
{
|
||||
unsigned const lock_count = 2;
|
||||
unsigned lock_first = 0;
|
||||
for (;;)
|
||||
{
|
||||
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 Iterator>
|
||||
void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
void lock(MutexType1& m1, MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
void lock(const MutexType1& m1, MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
void lock(MutexType1& m1, const MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
void lock(const MutexType1& m1, const MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2, typename MutexType3>
|
||||
void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
|
||||
{
|
||||
unsigned const lock_count = 3;
|
||||
unsigned lock_first = 0;
|
||||
for (;;)
|
||||
{
|
||||
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;
|
||||
for (;;)
|
||||
{
|
||||
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;
|
||||
for (;;)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Mutex, bool x = is_mutex_type<Mutex>::value>
|
||||
struct try_lock_impl_return
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct try_lock_impl_return<Iterator, false>
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
int try_lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
|
||||
{
|
||||
return ((int) detail::try_lock_internal(m1, m2)) - 1;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, const MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, const MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2, typename MutexType3>
|
||||
int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
|
||||
{
|
||||
return ((int) detail::try_lock_internal(m1, m2, m3)) - 1;
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
|
||||
int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
|
||||
{
|
||||
return ((int) detail::try_lock_internal(m1, m2, m3, m4)) - 1;
|
||||
}
|
||||
|
||||
template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
|
||||
int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
|
||||
{
|
||||
return ((int) detail::try_lock_internal(m1, m2, m3, m4, m5)) - 1;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct range_lock_guard
|
||||
{
|
||||
Iterator begin;
|
||||
Iterator end;
|
||||
|
||||
range_lock_guard(Iterator begin_, Iterator end_) :
|
||||
begin(begin_), end(end_)
|
||||
{
|
||||
boost::lock(begin, end);
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
~range_lock_guard()
|
||||
{
|
||||
for (; begin != end; ++begin)
|
||||
{
|
||||
begin->unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )
|
||||
|
||||
{
|
||||
if (begin == end)
|
||||
{
|
||||
return end;
|
||||
}
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
unique_lock<lock_type> guard(*begin, try_to_lock);
|
||||
|
||||
if (!guard.owns_lock())
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
Iterator const failed = boost::try_lock(++begin, end);
|
||||
if (failed == end)
|
||||
{
|
||||
guard.release();
|
||||
}
|
||||
|
||||
return failed;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Iterator>
|
||||
void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
|
||||
if (begin == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool start_with_begin = true;
|
||||
Iterator second = begin;
|
||||
++second;
|
||||
Iterator next = second;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unique_lock<lock_type> begin_lock(*begin, defer_lock);
|
||||
if (start_with_begin)
|
||||
{
|
||||
begin_lock.lock();
|
||||
Iterator const failed_lock = boost::try_lock(next, end);
|
||||
if (failed_lock == end)
|
||||
{
|
||||
begin_lock.release();
|
||||
return;
|
||||
}
|
||||
start_with_begin = false;
|
||||
next = failed_lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::range_lock_guard<Iterator> guard(next, end);
|
||||
if (begin_lock.try_lock())
|
||||
{
|
||||
Iterator const failed_lock = boost::try_lock(second, next);
|
||||
if (failed_lock == next)
|
||||
{
|
||||
begin_lock.release();
|
||||
guard.release();
|
||||
return;
|
||||
}
|
||||
start_with_begin = false;
|
||||
next = failed_lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_with_begin = true;
|
||||
next = second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue