mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
49 Commits
feature/ti
...
boost-1.67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d268106bf8 | ||
|
|
040481760c | ||
|
|
e848363029 | ||
|
|
e3358e0925 | ||
|
|
13a1f3daaa | ||
|
|
3a95ba8559 | ||
|
|
0871d0b0a6 | ||
|
|
7edd340995 | ||
|
|
8633d7532d | ||
|
|
03acfa57a2 | ||
|
|
9be0996062 | ||
|
|
71231fb2ae | ||
|
|
526c72cb4b | ||
|
|
426636b1d0 | ||
|
|
cb322cfa86 | ||
|
|
36807a438a | ||
|
|
f83e887d53 | ||
|
|
56c17adf7e | ||
|
|
65681f4033 | ||
|
|
961a0689f3 | ||
|
|
739f8eeb81 | ||
|
|
a02f0ec577 | ||
|
|
32229388f5 | ||
|
|
333365aefe | ||
|
|
5363e099e4 | ||
|
|
f79d51f099 | ||
|
|
336259c36a | ||
|
|
3391bf87c6 | ||
|
|
bc6b31e1f7 | ||
|
|
84720b7664 | ||
|
|
7879a4c286 | ||
|
|
11f18980ca | ||
|
|
12e2c8aaca | ||
|
|
046d716bbf | ||
|
|
5b9c1fad85 | ||
|
|
58c6b384cc | ||
|
|
7c1570328e | ||
|
|
97895e410f | ||
|
|
2494f3fc7a | ||
|
|
159868ac77 | ||
|
|
f65e89a85a | ||
|
|
bb47c16939 | ||
|
|
02fd2d041b | ||
|
|
2661c06698 | ||
|
|
83f877a238 | ||
|
|
47f615d073 | ||
|
|
7079a80edf | ||
|
|
dbf28a4ac4 | ||
|
|
2866734b15 |
@@ -238,6 +238,10 @@ rule usage-requirements ( properties * )
|
||||
# in that case?
|
||||
}
|
||||
}
|
||||
if <threadapi>win32 in $(properties)
|
||||
{
|
||||
result += <define>BOOST_THREAD_WIN32 ;
|
||||
}
|
||||
|
||||
#if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
|
||||
#{
|
||||
@@ -272,6 +276,10 @@ rule requirements ( properties * )
|
||||
result += <library>/boost/atomic//boost_atomic ;
|
||||
}
|
||||
} else {
|
||||
if <threadapi>win32 in $(properties)
|
||||
{
|
||||
result += <define>BOOST_THREAD_WIN32 ;
|
||||
}
|
||||
result += <define>BOOST_THREAD_USES_CHRONO ;
|
||||
result += <library>/boost/chrono//boost_chrono ;
|
||||
}
|
||||
@@ -284,6 +292,7 @@ alias thread_sources
|
||||
win32/thread.cpp
|
||||
win32/tss_dll.cpp
|
||||
win32/tss_pe.cpp
|
||||
win32/thread_primitives.cpp
|
||||
future.cpp
|
||||
: ## requirements ##
|
||||
<threadapi>win32
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
/// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
|
||||
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
//#endif
|
||||
|
||||
// Default version
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#elif defined(__CYGWIN__)
|
||||
# define BOOST_THREAD_CYGWIN
|
||||
#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
|
||||
#if ! defined BOOST_THREAD_WIN32
|
||||
# define BOOST_THREAD_WIN32
|
||||
#endif
|
||||
#elif defined(__BEOS__)
|
||||
# define BOOST_THREAD_BEOS
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||
|
||||
@@ -429,7 +429,7 @@ inline FP init_steady_clock(kern_return_t & err)
|
||||
#else
|
||||
// Use GetTickCount64() because it's more reliable on older
|
||||
// systems like Windows XP and Windows Server 2003.
|
||||
win32::ticks_type msec = win32::GetTickCount64_()();
|
||||
win32::ticks_type msec = win32::gettickcount64();
|
||||
return mono_platform_timepoint(msec * 1000000);
|
||||
#endif
|
||||
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
|
||||
|
||||
@@ -513,7 +513,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
inline bool timed_join(TimeDuration const& rel_time)
|
||||
bool timed_join(TimeDuration const& rel_time)
|
||||
{
|
||||
detail::platform_duration d(rel_time);
|
||||
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
|
||||
|
||||
@@ -577,11 +577,6 @@ namespace boost
|
||||
detail::shared_state_base(ex), result()
|
||||
{}
|
||||
|
||||
|
||||
~shared_state()
|
||||
{
|
||||
}
|
||||
|
||||
// locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
|
||||
BOOST_THREAD_DO_CONTINUATION
|
||||
|
||||
@@ -766,10 +761,6 @@ namespace boost
|
||||
detail::shared_state_base(ex), result(0)
|
||||
{}
|
||||
|
||||
~shared_state()
|
||||
{
|
||||
}
|
||||
|
||||
// locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
|
||||
BOOST_THREAD_DO_CONTINUATION
|
||||
|
||||
@@ -3189,7 +3180,7 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
@@ -3531,7 +3522,7 @@ namespace boost
|
||||
{}
|
||||
|
||||
// construction and destruction
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
@@ -3621,7 +3612,7 @@ namespace boost
|
||||
#endif
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
template <class Allocator>
|
||||
packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
|
||||
{
|
||||
@@ -3642,7 +3633,7 @@ namespace boost
|
||||
task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
|
||||
future_obtained = false;
|
||||
}
|
||||
#endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class F, class Allocator>
|
||||
@@ -3859,7 +3850,7 @@ namespace detail
|
||||
// future<R> async(launch policy, F&&, ArgTypes&&...);
|
||||
////////////////////////////////
|
||||
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
template <class R, class... ArgTypes>
|
||||
@@ -3918,7 +3909,7 @@ namespace detail
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
#endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
|
||||
@@ -4147,7 +4138,7 @@ namespace detail {
|
||||
//#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
template <class Executor, class R, class... ArgTypes>
|
||||
BOOST_THREAD_FUTURE<R>
|
||||
@@ -4163,7 +4154,7 @@ namespace detail {
|
||||
)
|
||||
));
|
||||
}
|
||||
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
template <class Executor, class F, class ...ArgTypes>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
|
||||
@@ -4182,7 +4173,7 @@ namespace detail {
|
||||
}
|
||||
|
||||
#else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
template <class Executor, class R>
|
||||
BOOST_THREAD_FUTURE<R>
|
||||
@@ -4212,7 +4203,7 @@ namespace detail {
|
||||
)
|
||||
));
|
||||
}
|
||||
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
|
||||
template <class Executor, class F>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
|
||||
@@ -4268,7 +4259,7 @@ namespace detail {
|
||||
// future<R> async(F&&, ArgTypes&&...);
|
||||
////////////////////////////////
|
||||
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
|
||||
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
template <class R, class... ArgTypes>
|
||||
BOOST_THREAD_FUTURE<R>
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
inline void sleep(TimeDuration const& rel_time)
|
||||
void sleep(TimeDuration const& rel_time)
|
||||
{
|
||||
mutex mx;
|
||||
unique_lock<mutex> lock(mx);
|
||||
@@ -275,7 +275,7 @@ namespace boost
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
mutex mut;
|
||||
unique_lock<mutex> lk(mut);
|
||||
@@ -284,7 +284,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
inline void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
mutex mut;
|
||||
unique_lock<mutex> lk(mut);
|
||||
@@ -322,7 +322,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
inline void sleep(TimeDuration const& rel_time)
|
||||
void sleep(TimeDuration const& rel_time)
|
||||
{
|
||||
hidden::sleep_for_internal(detail::platform_duration(rel_time));
|
||||
}
|
||||
@@ -330,19 +330,19 @@ namespace boost
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
inline void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
hidden::sleep_for_internal(detail::platform_duration(d));
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
{
|
||||
sleep_for(t - chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
|
||||
common_duration d(t - Clock::now());
|
||||
@@ -370,7 +370,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
inline void sleep(TimeDuration const& rel_time)
|
||||
void sleep(TimeDuration const& rel_time)
|
||||
{
|
||||
this_thread::sleep(rel_time);
|
||||
}
|
||||
@@ -378,13 +378,13 @@ namespace boost
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
this_thread::sleep_until(t);
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
inline void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
this_thread::sleep_for(d);
|
||||
}
|
||||
|
||||
@@ -230,8 +230,7 @@ namespace boost {
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_lock_until(
|
||||
bool try_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
@@ -246,14 +245,12 @@ namespace boost {
|
||||
bool try_lock_shared();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_lock_shared_until(
|
||||
bool try_lock_shared_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
@@ -275,8 +272,7 @@ namespace boost {
|
||||
|
||||
// Exclusive ownership
|
||||
|
||||
inline void
|
||||
shared_mutex::lock()
|
||||
inline void shared_mutex::lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
gate1_.wait(lk, boost::bind(&shared_mutex::no_writer, boost::ref(*this)));
|
||||
@@ -284,8 +280,7 @@ namespace boost {
|
||||
gate2_.wait(lk, boost::bind(&shared_mutex::no_readers, boost::ref(*this)));
|
||||
}
|
||||
|
||||
inline bool
|
||||
shared_mutex::try_lock()
|
||||
inline bool shared_mutex::try_lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!no_writer_no_readers())
|
||||
@@ -298,8 +293,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
shared_mutex::try_lock_until(
|
||||
bool shared_mutex::try_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -321,8 +315,7 @@ namespace boost {
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename T>
|
||||
inline bool
|
||||
shared_mutex::timed_lock(T const & abs_or_rel_time)
|
||||
bool shared_mutex::timed_lock(T const & abs_or_rel_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
|
||||
@@ -341,8 +334,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
shared_mutex::unlock()
|
||||
inline void shared_mutex::unlock()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_writer());
|
||||
@@ -355,8 +347,7 @@ namespace boost {
|
||||
|
||||
// Shared ownership
|
||||
|
||||
inline void
|
||||
shared_mutex::lock_shared()
|
||||
inline void shared_mutex::lock_shared()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
gate1_.wait(lk, boost::bind(&shared_mutex::no_writer_no_max_readers, boost::ref(*this)));
|
||||
@@ -365,8 +356,7 @@ namespace boost {
|
||||
state_ |= num_readers;
|
||||
}
|
||||
|
||||
inline bool
|
||||
shared_mutex::try_lock_shared()
|
||||
inline bool shared_mutex::try_lock_shared()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!no_writer_no_max_readers())
|
||||
@@ -381,8 +371,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
shared_mutex::try_lock_shared_until(
|
||||
bool shared_mutex::try_lock_shared_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -400,8 +389,7 @@ namespace boost {
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename T>
|
||||
inline bool
|
||||
shared_mutex::timed_lock_shared(T const & abs_or_rel_time)
|
||||
bool shared_mutex::timed_lock_shared(T const & abs_or_rel_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
|
||||
@@ -416,8 +404,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
shared_mutex::unlock_shared()
|
||||
inline void shared_mutex::unlock_shared()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_or_more_readers());
|
||||
@@ -543,8 +530,7 @@ namespace boost {
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_lock_until(
|
||||
bool try_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
@@ -559,14 +545,12 @@ namespace boost {
|
||||
bool try_lock_shared();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_lock_shared_until(
|
||||
bool try_lock_shared_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
@@ -581,15 +565,13 @@ namespace boost {
|
||||
bool try_lock_upgrade();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_lock_upgrade_for(
|
||||
bool try_lock_upgrade_for(
|
||||
const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_lock_upgrade_until(
|
||||
bool try_lock_upgrade_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
@@ -605,15 +587,13 @@ namespace boost {
|
||||
bool try_unlock_shared_and_lock();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_for(
|
||||
bool try_unlock_shared_and_lock_for(
|
||||
const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_until(
|
||||
bool try_unlock_shared_and_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#endif
|
||||
@@ -626,15 +606,13 @@ namespace boost {
|
||||
bool try_unlock_shared_and_lock_upgrade();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_for(
|
||||
bool try_unlock_shared_and_lock_upgrade_for(
|
||||
const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_until(
|
||||
bool try_unlock_shared_and_lock_upgrade_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
#endif
|
||||
@@ -646,15 +624,13 @@ namespace boost {
|
||||
bool try_unlock_upgrade_and_lock();
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_for(
|
||||
bool try_unlock_upgrade_and_lock_for(
|
||||
const boost::chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_upgrade_and_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_until(
|
||||
bool try_unlock_upgrade_and_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
||||
#endif
|
||||
void unlock_and_lock_upgrade();
|
||||
@@ -674,8 +650,7 @@ namespace boost {
|
||||
|
||||
// Exclusive ownership
|
||||
|
||||
inline void
|
||||
upgrade_mutex::lock()
|
||||
inline void upgrade_mutex::lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_upgrader, boost::ref(*this)));
|
||||
@@ -683,8 +658,7 @@ namespace boost {
|
||||
gate2_.wait(lk, boost::bind(&upgrade_mutex::no_readers, boost::ref(*this)));
|
||||
}
|
||||
|
||||
inline bool
|
||||
upgrade_mutex::try_lock()
|
||||
inline bool upgrade_mutex::try_lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!no_writer_no_upgrader_no_readers())
|
||||
@@ -697,8 +671,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_lock_until(
|
||||
bool upgrade_mutex::try_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -720,8 +693,7 @@ namespace boost {
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename T>
|
||||
inline bool
|
||||
upgrade_mutex::timed_lock(T const & abs_or_rel_time)
|
||||
bool upgrade_mutex::timed_lock(T const & abs_or_rel_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
|
||||
@@ -740,8 +712,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock()
|
||||
inline void upgrade_mutex::unlock()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_writer());
|
||||
@@ -755,8 +726,7 @@ namespace boost {
|
||||
|
||||
// Shared ownership
|
||||
|
||||
inline void
|
||||
upgrade_mutex::lock_shared()
|
||||
inline void upgrade_mutex::lock_shared()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_max_readers, boost::ref(*this)));
|
||||
@@ -765,8 +735,7 @@ namespace boost {
|
||||
state_ |= num_readers;
|
||||
}
|
||||
|
||||
inline bool
|
||||
upgrade_mutex::try_lock_shared()
|
||||
inline bool upgrade_mutex::try_lock_shared()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!no_writer_no_max_readers())
|
||||
@@ -781,8 +750,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_lock_shared_until(
|
||||
bool upgrade_mutex::try_lock_shared_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -800,8 +768,7 @@ namespace boost {
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename T>
|
||||
inline bool
|
||||
upgrade_mutex::timed_lock_shared(T const & abs_or_rel_time)
|
||||
bool upgrade_mutex::timed_lock_shared(T const & abs_or_rel_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
|
||||
@@ -816,8 +783,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_shared()
|
||||
inline void upgrade_mutex::unlock_shared()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_or_more_readers());
|
||||
@@ -838,8 +804,7 @@ namespace boost {
|
||||
|
||||
// Upgrade ownership
|
||||
|
||||
inline void
|
||||
upgrade_mutex::lock_upgrade()
|
||||
inline void upgrade_mutex::lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_upgrader_no_max_readers, boost::ref(*this)));
|
||||
@@ -848,8 +813,7 @@ namespace boost {
|
||||
state_ |= upgradable_entered_ | num_readers;
|
||||
}
|
||||
|
||||
inline bool
|
||||
upgrade_mutex::try_lock_upgrade()
|
||||
inline bool upgrade_mutex::try_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!no_writer_no_upgrader_no_max_readers())
|
||||
@@ -864,8 +828,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_lock_upgrade_until(
|
||||
bool upgrade_mutex::try_lock_upgrade_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -883,8 +846,7 @@ namespace boost {
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename T>
|
||||
inline bool
|
||||
upgrade_mutex::timed_lock_upgrade(T const & abs_or_rel_time)
|
||||
bool upgrade_mutex::timed_lock_upgrade(T const & abs_or_rel_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
|
||||
@@ -899,8 +861,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_upgrade()
|
||||
inline void upgrade_mutex::unlock_upgrade()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(no_writer());
|
||||
@@ -917,8 +878,7 @@ namespace boost {
|
||||
// Shared <-> Exclusive
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_shared_and_lock()
|
||||
inline bool upgrade_mutex::try_unlock_shared_and_lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
BOOST_ASSERT(one_or_more_readers());
|
||||
@@ -932,8 +892,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_shared_and_lock_until(
|
||||
bool upgrade_mutex::try_unlock_shared_and_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -959,8 +918,7 @@ namespace boost {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_and_lock_shared()
|
||||
inline void upgrade_mutex::unlock_and_lock_shared()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_writer());
|
||||
@@ -975,8 +933,7 @@ namespace boost {
|
||||
// Shared <-> Upgrade
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
|
||||
inline bool upgrade_mutex::try_unlock_shared_and_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
BOOST_ASSERT(one_or_more_readers());
|
||||
@@ -990,8 +947,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
|
||||
bool upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -1007,8 +963,7 @@ namespace boost {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_upgrade_and_lock_shared()
|
||||
inline void upgrade_mutex::unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(no_writer());
|
||||
@@ -1023,8 +978,7 @@ namespace boost {
|
||||
|
||||
// Upgrade <-> Exclusive
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_upgrade_and_lock()
|
||||
inline void upgrade_mutex::unlock_upgrade_and_lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
BOOST_ASSERT(no_writer());
|
||||
@@ -1036,8 +990,7 @@ namespace boost {
|
||||
gate2_.wait(lk, boost::bind(&upgrade_mutex::no_readers, boost::ref(*this)));
|
||||
}
|
||||
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_upgrade_and_lock()
|
||||
inline bool upgrade_mutex::try_unlock_upgrade_and_lock()
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
BOOST_ASSERT(no_writer());
|
||||
@@ -1053,8 +1006,7 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Clock, class Duration>
|
||||
inline bool
|
||||
upgrade_mutex::try_unlock_upgrade_and_lock_until(
|
||||
bool upgrade_mutex::try_unlock_upgrade_and_lock_until(
|
||||
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
@@ -1076,8 +1028,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
upgrade_mutex::unlock_and_lock_upgrade()
|
||||
inline void upgrade_mutex::unlock_and_lock_upgrade()
|
||||
{
|
||||
boost::lock_guard<mutex_t> _(mut_);
|
||||
BOOST_ASSERT(one_writer());
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace boost
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
inline void call_once(once_flag& flag, void (*f)())
|
||||
{
|
||||
// Try for a quick win: if the procedure has already been called
|
||||
@@ -709,7 +709,7 @@ namespace boost
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
|
||||
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
|
||||
inline void call_once(once_flag& flag, void (*f)())
|
||||
{
|
||||
// Try for a quick win: if the procedure has already been called
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace boost
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
|
||||
BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
|
||||
{
|
||||
interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
|
||||
}
|
||||
@@ -205,19 +205,19 @@ namespace boost
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
inline void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
{
|
||||
sleep_for(t - chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
|
||||
common_duration d(t - Clock::now());
|
||||
@@ -236,7 +236,7 @@ namespace boost
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
|
||||
BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
|
||||
{
|
||||
non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
|
||||
}
|
||||
@@ -256,19 +256,19 @@ namespace boost
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
inline void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
|
||||
{
|
||||
sleep_for(t - chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
|
||||
common_duration d(t - Clock::now());
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
|
||||
#include <boost/winapi/config.hpp>
|
||||
#include <boost/winapi/basic_types.hpp>
|
||||
#include <boost/winapi/semaphore.hpp>
|
||||
#include <boost/winapi/dll.hpp>
|
||||
#include <boost/winapi/system.hpp>
|
||||
#include <boost/winapi/time.hpp>
|
||||
#include <boost/winapi/event.hpp>
|
||||
#include <boost/winapi/thread.hpp>
|
||||
#include <boost/winapi/get_current_thread.hpp>
|
||||
@@ -48,8 +47,7 @@ namespace boost
|
||||
{
|
||||
typedef ::boost::winapi::HANDLE_ handle;
|
||||
typedef ::boost::winapi::SYSTEM_INFO_ system_info;
|
||||
typedef unsigned __int64 ticks_type;
|
||||
typedef ::boost::winapi::FARPROC_ farproc_t;
|
||||
typedef ::boost::winapi::ULONGLONG_ ticks_type;
|
||||
unsigned const infinite=::boost::winapi::INFINITE_;
|
||||
unsigned const timeout=::boost::winapi::WAIT_TIMEOUT_;
|
||||
handle const invalid_handle_value=::boost::winapi::INVALID_HANDLE_VALUE_;
|
||||
@@ -72,96 +70,8 @@ namespace boost
|
||||
{
|
||||
namespace win32
|
||||
{
|
||||
namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
extern "C"
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
long _InterlockedCompareExchange(long volatile *, long, long);
|
||||
#pragma intrinsic(_InterlockedCompareExchange)
|
||||
#elif defined(__MINGW64_VERSION_MAJOR)
|
||||
long _InterlockedCompareExchange(long volatile *, long, long);
|
||||
#else
|
||||
// Mingw doesn't provide intrinsics
|
||||
#define _InterlockedCompareExchange InterlockedCompareExchange
|
||||
#endif
|
||||
}
|
||||
// Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
|
||||
inline ticks_type __stdcall GetTickCount64emulation()
|
||||
{
|
||||
static long count = -1l;
|
||||
unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
|
||||
ticks_type current_tick64;
|
||||
|
||||
previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
|
||||
current_tick32 = ::boost::winapi::GetTickCount();
|
||||
|
||||
if(previous_count == (unsigned long)-1l)
|
||||
{
|
||||
// count has never been written
|
||||
unsigned long initial_count;
|
||||
initial_count = current_tick32 >> 28;
|
||||
previous_count = (unsigned long) _InterlockedCompareExchange(&count, (long)initial_count, -1l);
|
||||
|
||||
current_tick64 = initial_count;
|
||||
current_tick64 <<= 28;
|
||||
current_tick64 += current_tick32 & 0x0FFFFFFF;
|
||||
return current_tick64;
|
||||
}
|
||||
|
||||
previous_count_zone = previous_count & 15;
|
||||
current_tick32_zone = current_tick32 >> 28;
|
||||
|
||||
if(current_tick32_zone == previous_count_zone)
|
||||
{
|
||||
// The top four bits of the 32-bit tick count haven't changed since count was last written.
|
||||
current_tick64 = previous_count;
|
||||
current_tick64 <<= 28;
|
||||
current_tick64 += current_tick32 & 0x0FFFFFFF;
|
||||
return current_tick64;
|
||||
}
|
||||
|
||||
if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
|
||||
{
|
||||
// The top four bits of the 32-bit tick count have been incremented since count was last written.
|
||||
unsigned long new_count = previous_count + 1;
|
||||
_InterlockedCompareExchange(&count, (long)new_count, (long)previous_count);
|
||||
current_tick64 = new_count;
|
||||
current_tick64 <<= 28;
|
||||
current_tick64 += current_tick32 & 0x0FFFFFFF;
|
||||
return current_tick64;
|
||||
}
|
||||
|
||||
// Oops, we weren't called often enough, we're stuck
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
inline detail::gettickcount64_t GetTickCount64_()
|
||||
{
|
||||
static detail::gettickcount64_t gettickcount64impl;
|
||||
if(gettickcount64impl)
|
||||
return gettickcount64impl;
|
||||
|
||||
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
|
||||
// and kernel32 isn't used in Windows Phone.
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
gettickcount64impl = &::boost::winapi::GetTickCount64;
|
||||
#else
|
||||
farproc_t addr=GetProcAddress(
|
||||
#if !defined(BOOST_NO_ANSI_APIS)
|
||||
::boost::winapi::GetModuleHandleA("KERNEL32.DLL"),
|
||||
#else
|
||||
::boost::winapi::GetModuleHandleW(L"KERNEL32.DLL"),
|
||||
#endif
|
||||
"GetTickCount64");
|
||||
if(addr)
|
||||
gettickcount64impl=(detail::gettickcount64_t) addr;
|
||||
else
|
||||
gettickcount64impl=&GetTickCount64emulation;
|
||||
#endif
|
||||
return gettickcount64impl;
|
||||
}
|
||||
namespace detail { typedef ticks_type (WINAPI *gettickcount64_t)(); }
|
||||
extern BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64;
|
||||
|
||||
enum event_type
|
||||
{
|
||||
|
||||
140
src/win32/thread_primitives.cpp
Normal file
140
src/win32/thread_primitives.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
// thread_primitives.cpp
|
||||
//
|
||||
// (C) Copyright 2018 Andrey Semashev
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/winapi/config.hpp>
|
||||
#include <boost/winapi/dll.hpp>
|
||||
#include <boost/winapi/time.hpp>
|
||||
#include <boost/winapi/event.hpp>
|
||||
#include <boost/winapi/handles.hpp>
|
||||
#include <boost/winapi/thread_pool.hpp>
|
||||
#include <cstdlib>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/atomic.hpp>
|
||||
#include <boost/thread/win32/interlocked_read.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace win32 {
|
||||
|
||||
#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
|
||||
|
||||
// Directly use API from Vista and later
|
||||
BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64 = &::boost::winapi::GetTickCount64;
|
||||
|
||||
#else // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
|
||||
|
||||
namespace {
|
||||
|
||||
enum init_state
|
||||
{
|
||||
uninitialized = 0,
|
||||
in_progress,
|
||||
initialized
|
||||
};
|
||||
|
||||
struct get_tick_count64_state
|
||||
{
|
||||
boost::atomic< uint64_t > ticks;
|
||||
boost::atomic< init_state > init;
|
||||
boost::winapi::HANDLE_ wait_event;
|
||||
boost::winapi::HANDLE_ wait_handle;
|
||||
};
|
||||
|
||||
// Zero-initialized initially
|
||||
BOOST_ALIGNMENT(64) static get_tick_count64_state g_state;
|
||||
|
||||
//! Artifical implementation of GetTickCount64
|
||||
ticks_type WINAPI get_tick_count64()
|
||||
{
|
||||
uint64_t old_state = g_state.ticks.load(boost::memory_order_acquire);
|
||||
|
||||
uint32_t new_ticks = boost::winapi::GetTickCount();
|
||||
|
||||
uint32_t old_ticks = static_cast< uint32_t >(old_state & UINT64_C(0x00000000ffffffff));
|
||||
uint64_t new_state = ((old_state & UINT64_C(0xffffffff00000000)) + (static_cast< uint64_t >(new_ticks < old_ticks) << 32)) | static_cast< uint64_t >(new_ticks);
|
||||
|
||||
g_state.ticks.store(new_state, boost::memory_order_release);
|
||||
|
||||
return new_state;
|
||||
}
|
||||
|
||||
//! The function is called periodically in the system thread pool to make sure g_state.ticks is timely updated
|
||||
void NTAPI refresh_get_tick_count64(boost::winapi::PVOID_, boost::winapi::BOOLEAN_)
|
||||
{
|
||||
get_tick_count64();
|
||||
}
|
||||
|
||||
//! Cleanup function to stop get_tick_count64 refreshes
|
||||
void cleanup_get_tick_count64()
|
||||
{
|
||||
if (g_state.wait_handle)
|
||||
{
|
||||
boost::winapi::UnregisterWait(g_state.wait_handle);
|
||||
g_state.wait_handle = NULL;
|
||||
}
|
||||
|
||||
if (g_state.wait_event)
|
||||
{
|
||||
boost::winapi::CloseHandle(g_state.wait_event);
|
||||
g_state.wait_event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ticks_type WINAPI get_tick_count_init()
|
||||
{
|
||||
boost::winapi::HMODULE_ hKernel32 = boost::winapi::GetModuleHandleW(L"kernel32.dll");
|
||||
if (hKernel32)
|
||||
{
|
||||
boost::detail::win32::detail::gettickcount64_t p =
|
||||
(boost::detail::win32::detail::gettickcount64_t)boost::winapi::get_proc_address(hKernel32, "GetTickCount64");
|
||||
if (p)
|
||||
{
|
||||
// Use native API
|
||||
boost::detail::interlocked_write_release((void**)&gettickcount64, (void*)p);
|
||||
return p();
|
||||
}
|
||||
}
|
||||
|
||||
// No native API available. Use emulation with periodic refreshes to make sure the GetTickCount wrap arounds are properly counted.
|
||||
init_state old_init = uninitialized;
|
||||
if (g_state.init.compare_exchange_strong(old_init, in_progress, boost::memory_order_acq_rel, boost::memory_order_relaxed))
|
||||
{
|
||||
if (!g_state.wait_event)
|
||||
g_state.wait_event = boost::winapi::create_anonymous_event(NULL, false, false);
|
||||
if (g_state.wait_event)
|
||||
{
|
||||
boost::winapi::BOOL_ res = boost::winapi::RegisterWaitForSingleObject(&g_state.wait_handle, g_state.wait_event, &refresh_get_tick_count64, NULL, 0x7fffffff, boost::winapi::WT_EXECUTEINWAITTHREAD_);
|
||||
if (res)
|
||||
{
|
||||
std::atexit(&cleanup_get_tick_count64);
|
||||
|
||||
boost::detail::interlocked_write_release((void**)&gettickcount64, (void*)&get_tick_count64);
|
||||
g_state.init.store(initialized, boost::memory_order_release);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
g_state.init.store(uninitialized, boost::memory_order_release);
|
||||
}
|
||||
|
||||
finish:
|
||||
return get_tick_count64();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64 = &get_tick_count_init;
|
||||
|
||||
#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
|
||||
|
||||
} // namespace win32
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
Reference in New Issue
Block a user