]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/log/src/windows/light_rw_mutex.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / src / windows / light_rw_mutex.cpp
CommitLineData
7c673cae
FG
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/detail/winapi/basic_types.hpp>
31#include <boost/detail/winapi/dll.hpp>
32
33#include <boost/log/detail/header.hpp>
34
35namespace boost {
36
37BOOST_LOG_OPEN_NAMESPACE
38
39namespace aux {
40
41BOOST_LOG_ANONYMOUS_NAMESPACE {
42
43struct BOOST_LOG_MAY_ALIAS mutex_impl { void* p; }; // has the same layout as SRWLOCK and light_rw_mutex::m_Mutex
44
45typedef void (WINAPI *init_fun_t)(mutex_impl*);
46typedef void (WINAPI *destroy_fun_t)(mutex_impl*);
47typedef void (WINAPI *lock_exclusive_fun_t)(mutex_impl*);
48typedef void (WINAPI *lock_shared_fun_t)(mutex_impl*);
49typedef void (WINAPI *unlock_exclusive_fun_t)(mutex_impl*);
50typedef void (WINAPI *unlock_shared_fun_t)(mutex_impl*);
51
52//! A complement stub function for InitializeSRWLock
53void WINAPI DeinitializeSRWLock(mutex_impl*)
54{
55}
56
57// The Boost.Thread-based implementation
58void 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
76void 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
83void WINAPI ExclusiveLockSharedMutex(mutex_impl* mtx)
84{
85 static_cast< shared_mutex* >(mtx->p)->lock();
86}
87
88void WINAPI SharedLockSharedMutex(mutex_impl* mtx)
89{
90 static_cast< shared_mutex* >(mtx->p)->lock_shared();
91}
92
93void WINAPI ExclusiveUnlockSharedMutex(mutex_impl* mtx)
94{
95 static_cast< shared_mutex* >(mtx->p)->unlock();
96}
97
98void WINAPI SharedUnlockSharedMutex(mutex_impl* mtx)
99{
100 static_cast< shared_mutex* >(mtx->p)->unlock_shared();
101}
102
103// Pointers to the actual implementation functions
104init_fun_t g_pInitializeLWRWMutex = NULL;
105destroy_fun_t g_pDestroyLWRWMutex = NULL;
106lock_exclusive_fun_t g_pLockExclusiveLWRWMutex = NULL;
107lock_shared_fun_t g_pLockSharedLWRWMutex = NULL;
108unlock_exclusive_fun_t g_pUnlockExclusiveLWRWMutex = NULL;
109unlock_shared_fun_t g_pUnlockSharedLWRWMutex = NULL;
110
111//! The function dynamically initializes the implementation pointers
112void init_light_rw_mutex_impl()
113{
114 boost::detail::winapi::HMODULE_ hKernel32 = boost::detail::winapi::GetModuleHandleW(L"kernel32.dll");
115 if (hKernel32)
116 {
117 g_pInitializeLWRWMutex =
118 (init_fun_t)boost::detail::winapi::get_proc_address(hKernel32, "InitializeSRWLock");
119 if (g_pInitializeLWRWMutex)
120 {
121 g_pLockExclusiveLWRWMutex =
122 (lock_exclusive_fun_t)boost::detail::winapi::get_proc_address(hKernel32, "AcquireSRWLockExclusive");
123 if (g_pLockExclusiveLWRWMutex)
124 {
125 g_pUnlockExclusiveLWRWMutex =
126 (unlock_exclusive_fun_t)boost::detail::winapi::get_proc_address(hKernel32, "ReleaseSRWLockExclusive");
127 if (g_pUnlockExclusiveLWRWMutex)
128 {
129 g_pLockSharedLWRWMutex =
130 (lock_shared_fun_t)boost::detail::winapi::get_proc_address(hKernel32, "AcquireSRWLockShared");
131 if (g_pLockSharedLWRWMutex)
132 {
133 g_pUnlockSharedLWRWMutex =
134 (unlock_shared_fun_t)boost::detail::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
157BOOST_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
166BOOST_LOG_API light_rw_mutex::~light_rw_mutex()
167{
168 g_pDestroyLWRWMutex((mutex_impl*)&m_Mutex);
169}
170
171BOOST_LOG_API void light_rw_mutex::lock_shared()
172{
173 g_pLockSharedLWRWMutex((mutex_impl*)&m_Mutex);
174}
175
176BOOST_LOG_API void light_rw_mutex::unlock_shared()
177{
178 g_pUnlockSharedLWRWMutex((mutex_impl*)&m_Mutex);
179}
180
181BOOST_LOG_API void light_rw_mutex::lock()
182{
183 g_pLockExclusiveLWRWMutex((mutex_impl*)&m_Mutex);
184}
185
186BOOST_LOG_API void light_rw_mutex::unlock()
187{
188 g_pUnlockExclusiveLWRWMutex((mutex_impl*)&m_Mutex);
189}
190
191} // namespace aux
192
193BOOST_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)