mirror of
https://github.com/boostorg/thread.git
synced 2026-01-23 06:02:14 +00:00
Thread: name type for pthread/once epoch so that we can choose better an /atomic/ type for it
[SVN r79984]
This commit is contained in:
@@ -25,6 +25,12 @@ namespace boost
|
||||
|
||||
#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
|
||||
|
||||
namespace thread_detail
|
||||
{
|
||||
typedef unsigned long uintmax_atomic_t;
|
||||
#define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C(value) value##ul
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
|
||||
|
||||
struct once_flag
|
||||
@@ -34,7 +40,7 @@ namespace boost
|
||||
: epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
|
||||
{}
|
||||
private:
|
||||
boost::uintmax_t epoch;
|
||||
volatile thread_detail::uintmax_atomic_t epoch;
|
||||
template<typename Function>
|
||||
friend
|
||||
void call_once(once_flag& flag,Function f);
|
||||
@@ -44,7 +50,7 @@ namespace boost
|
||||
|
||||
struct once_flag
|
||||
{
|
||||
boost::uintmax_t epoch;
|
||||
volatile thread_detail::uintmax_atomic_t epoch;
|
||||
};
|
||||
|
||||
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
|
||||
@@ -52,8 +58,8 @@ namespace boost
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch();
|
||||
BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch;
|
||||
BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
|
||||
BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
|
||||
BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
|
||||
BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
|
||||
}
|
||||
@@ -63,10 +69,10 @@ namespace boost
|
||||
template<typename Function>
|
||||
void call_once(once_flag& flag,Function f)
|
||||
{
|
||||
static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
|
||||
static boost::uintmax_t const being_initialized=uninitialized_flag+1;
|
||||
boost::uintmax_t const epoch=flag.epoch;
|
||||
boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch();
|
||||
static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
|
||||
static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
|
||||
thread_detail::uintmax_atomic_t const epoch=flag.epoch;
|
||||
thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch();
|
||||
|
||||
if(epoch<this_thread_epoch)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0);
|
||||
BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C(~0);
|
||||
BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
|
||||
BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
@@ -55,17 +55,17 @@ namespace boost
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::uintmax_t& get_once_per_thread_epoch()
|
||||
thread_detail::uintmax_atomic_t& get_once_per_thread_epoch()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
|
||||
void* data=pthread_getspecific(epoch_tss_key);
|
||||
if(!data)
|
||||
{
|
||||
data=malloc(sizeof(boost::uintmax_t));
|
||||
data=malloc(sizeof(thread_detail::uintmax_atomic_t));
|
||||
BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
|
||||
*static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0);
|
||||
*static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C(~0);
|
||||
}
|
||||
return *static_cast<boost::uintmax_t*>(data);
|
||||
return *static_cast<thread_detail::uintmax_atomic_t*>(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user