]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/thread/src/pthread/once_atomic.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / thread / src / pthread / once_atomic.cpp
CommitLineData
7c673cae
FG
1// (C) Copyright 2013 Andrey Semashev
2// (C) Copyright 2013 Vicente J. Botet Escriba
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7//#define __STDC_CONSTANT_MACROS
8#include <boost/thread/detail/config.hpp>
9#include <boost/thread/once.hpp>
10#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
11#include <boost/assert.hpp>
12#include <boost/static_assert.hpp>
13#include <boost/atomic.hpp>
14#include <boost/memory_order.hpp>
15#include <pthread.h>
16
17namespace boost
18{
19 namespace thread_detail
20 {
21
22 enum flag_states
23 {
24 uninitialized, in_progress, initialized
25 };
26
27
28#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
29 BOOST_STATIC_ASSERT_MSG(sizeof(atomic_int_type) == sizeof(atomic_type), "Boost.Thread: unsupported platform");
30#endif
31
32 static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;
33 static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER;
34
35 BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT
36 {
37 atomic_type& f = get_atomic_storage(flag);
38 if (f.load(memory_order_acquire) != initialized)
39 {
40 pthread::pthread_mutex_scoped_lock lk(&once_mutex);
41 if (f.load(memory_order_acquire) != initialized)
42 {
b32b8144 43 for (;;)
7c673cae
FG
44 {
45 atomic_int_type expected = uninitialized;
46 if (f.compare_exchange_strong(expected, in_progress, memory_order_acq_rel, memory_order_acquire))
47 {
48 // We have set the flag to in_progress
49 return true;
50 }
51 else if (expected == initialized)
52 {
53 // Another thread managed to complete the initialization
54 return false;
55 }
56 else
57 {
58 // Wait until the initialization is complete
59 //pthread::pthread_mutex_scoped_lock lk(&once_mutex);
60 BOOST_VERIFY(!pthread_cond_wait(&once_cv, &once_mutex));
61 }
62 }
63 }
64 }
65 return false;
66 }
67
68 BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT
69 {
70 atomic_type& f = get_atomic_storage(flag);
71 {
72 pthread::pthread_mutex_scoped_lock lk(&once_mutex);
73 f.store(initialized, memory_order_release);
74 }
75 BOOST_VERIFY(!pthread_cond_broadcast(&once_cv));
76 }
77
78 BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT
79 {
80 atomic_type& f = get_atomic_storage(flag);
81 {
82 pthread::pthread_mutex_scoped_lock lk(&once_mutex);
83 f.store(uninitialized, memory_order_release);
84 }
85 BOOST_VERIFY(!pthread_cond_broadcast(&once_cv));
86 }
87
88 } // namespace thread_detail
89
90} // namespace boost