]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/src/windows/light_rw_mutex.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / log / src / windows / light_rw_mutex.cpp
1 /*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7 /*!
8 * \file light_rw_mutex.cpp
9 * \author Andrey Semashev
10 * \date 19.06.2010
11 *
12 * \brief This header is the Boost.Log library implementation, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 */
15
16 #include <boost/log/detail/config.hpp>
17 #include <boost/log/detail/light_rw_mutex.hpp>
18
19 #if !defined(BOOST_LOG_NO_THREADS)
20
21 #if !defined(BOOST_LOG_LWRWMUTEX_USE_PTHREAD) && !defined(BOOST_LOG_LWRWMUTEX_USE_SRWLOCK)
22
23 #include <cstddef>
24 #include <new>
25 #include <boost/assert.hpp>
26 #include <boost/align/aligned_alloc.hpp>
27 #include <boost/thread/shared_mutex.hpp>
28 #include <boost/log/utility/once_block.hpp>
29
30 #include <boost/winapi/basic_types.hpp>
31 #include <boost/winapi/dll.hpp>
32
33 #include <boost/log/detail/header.hpp>
34
35 namespace boost {
36
37 BOOST_LOG_OPEN_NAMESPACE
38
39 namespace aux {
40
41 BOOST_LOG_ANONYMOUS_NAMESPACE {
42
43 struct BOOST_LOG_MAY_ALIAS mutex_impl { void* p; }; // has the same layout as SRWLOCK and light_rw_mutex::m_Mutex
44
45 typedef void (WINAPI *init_fun_t)(mutex_impl*);
46 typedef void (WINAPI *destroy_fun_t)(mutex_impl*);
47 typedef void (WINAPI *lock_exclusive_fun_t)(mutex_impl*);
48 typedef void (WINAPI *lock_shared_fun_t)(mutex_impl*);
49 typedef void (WINAPI *unlock_exclusive_fun_t)(mutex_impl*);
50 typedef void (WINAPI *unlock_shared_fun_t)(mutex_impl*);
51
52 //! A complement stub function for InitializeSRWLock
53 void WINAPI DeinitializeSRWLock(mutex_impl*)
54 {
55 }
56
57 // The Boost.Thread-based implementation
58 void WINAPI InitializeSharedMutex(mutex_impl* mtx)
59 {
60 // To avoid cache line aliasing we do aligned memory allocation here
61 enum
62 {
63 // Allocation size is the minimum number of cache lines to accommodate shared_mutex
64 size =
65 (
66 sizeof(shared_mutex) / BOOST_LOG_CPU_CACHE_LINE_SIZE
67 + ((sizeof(shared_mutex) % BOOST_LOG_CPU_CACHE_LINE_SIZE) != 0)
68 )
69 * BOOST_LOG_CPU_CACHE_LINE_SIZE
70 };
71 mtx->p = alignment::aligned_alloc(BOOST_LOG_CPU_CACHE_LINE_SIZE, size);
72 BOOST_ASSERT(mtx->p != NULL);
73 new (mtx->p) shared_mutex();
74 }
75
76 void WINAPI DeinitializeSharedMutex(mutex_impl* mtx)
77 {
78 static_cast< shared_mutex* >(mtx->p)->~shared_mutex();
79 alignment::aligned_free(mtx->p);
80 mtx->p = NULL;
81 }
82
83 void WINAPI ExclusiveLockSharedMutex(mutex_impl* mtx)
84 {
85 static_cast< shared_mutex* >(mtx->p)->lock();
86 }
87
88 void WINAPI SharedLockSharedMutex(mutex_impl* mtx)
89 {
90 static_cast< shared_mutex* >(mtx->p)->lock_shared();
91 }
92
93 void WINAPI ExclusiveUnlockSharedMutex(mutex_impl* mtx)
94 {
95 static_cast< shared_mutex* >(mtx->p)->unlock();
96 }
97
98 void WINAPI SharedUnlockSharedMutex(mutex_impl* mtx)
99 {
100 static_cast< shared_mutex* >(mtx->p)->unlock_shared();
101 }
102
103 // Pointers to the actual implementation functions
104 init_fun_t g_pInitializeLWRWMutex = NULL;
105 destroy_fun_t g_pDestroyLWRWMutex = NULL;
106 lock_exclusive_fun_t g_pLockExclusiveLWRWMutex = NULL;
107 lock_shared_fun_t g_pLockSharedLWRWMutex = NULL;
108 unlock_exclusive_fun_t g_pUnlockExclusiveLWRWMutex = NULL;
109 unlock_shared_fun_t g_pUnlockSharedLWRWMutex = NULL;
110
111 //! The function dynamically initializes the implementation pointers
112 void init_light_rw_mutex_impl()
113 {
114 boost::winapi::HMODULE_ hKernel32 = boost::winapi::GetModuleHandleW(L"kernel32.dll");
115 if (hKernel32)
116 {
117 g_pInitializeLWRWMutex =
118 (init_fun_t)boost::winapi::get_proc_address(hKernel32, "InitializeSRWLock");
119 if (g_pInitializeLWRWMutex)
120 {
121 g_pLockExclusiveLWRWMutex =
122 (lock_exclusive_fun_t)boost::winapi::get_proc_address(hKernel32, "AcquireSRWLockExclusive");
123 if (g_pLockExclusiveLWRWMutex)
124 {
125 g_pUnlockExclusiveLWRWMutex =
126 (unlock_exclusive_fun_t)boost::winapi::get_proc_address(hKernel32, "ReleaseSRWLockExclusive");
127 if (g_pUnlockExclusiveLWRWMutex)
128 {
129 g_pLockSharedLWRWMutex =
130 (lock_shared_fun_t)boost::winapi::get_proc_address(hKernel32, "AcquireSRWLockShared");
131 if (g_pLockSharedLWRWMutex)
132 {
133 g_pUnlockSharedLWRWMutex =
134 (unlock_shared_fun_t)boost::winapi::get_proc_address(hKernel32, "ReleaseSRWLockShared");
135 if (g_pUnlockSharedLWRWMutex)
136 {
137 g_pDestroyLWRWMutex = &DeinitializeSRWLock;
138 return;
139 }
140 }
141 }
142 }
143 }
144 }
145
146 // Current OS doesn't have support for SRWLOCK, use Boost.Thread instead
147 g_pInitializeLWRWMutex = &InitializeSharedMutex;
148 g_pDestroyLWRWMutex = &DeinitializeSharedMutex;
149 g_pLockExclusiveLWRWMutex = &ExclusiveLockSharedMutex;
150 g_pUnlockExclusiveLWRWMutex = &ExclusiveUnlockSharedMutex;
151 g_pLockSharedLWRWMutex = &SharedLockSharedMutex;
152 g_pUnlockSharedLWRWMutex = &SharedUnlockSharedMutex;
153 }
154
155 } // namespace
156
157 BOOST_LOG_API light_rw_mutex::light_rw_mutex()
158 {
159 BOOST_LOG_ONCE_BLOCK()
160 {
161 init_light_rw_mutex_impl();
162 }
163 g_pInitializeLWRWMutex((mutex_impl*)&m_Mutex);
164 }
165
166 BOOST_LOG_API light_rw_mutex::~light_rw_mutex()
167 {
168 g_pDestroyLWRWMutex((mutex_impl*)&m_Mutex);
169 }
170
171 BOOST_LOG_API void light_rw_mutex::lock_shared()
172 {
173 g_pLockSharedLWRWMutex((mutex_impl*)&m_Mutex);
174 }
175
176 BOOST_LOG_API void light_rw_mutex::unlock_shared()
177 {
178 g_pUnlockSharedLWRWMutex((mutex_impl*)&m_Mutex);
179 }
180
181 BOOST_LOG_API void light_rw_mutex::lock()
182 {
183 g_pLockExclusiveLWRWMutex((mutex_impl*)&m_Mutex);
184 }
185
186 BOOST_LOG_API void light_rw_mutex::unlock()
187 {
188 g_pUnlockExclusiveLWRWMutex((mutex_impl*)&m_Mutex);
189 }
190
191 } // namespace aux
192
193 BOOST_LOG_CLOSE_NAMESPACE // namespace log
194
195 } // namespace boost
196
197 #include <boost/log/detail/footer.hpp>
198
199 #endif // !defined(BOOST_LOG_LWRWMUTEX_USE_PTHREAD) && !defined(BOOST_LOG_LWRWMUTEX_USE_SRWLOCK)
200
201 #endif // !defined(BOOST_LOG_NO_THREADS)