]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/port/win/port_win.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rocksdb / port / win / port_win.h
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 //
10 // See port_example.h for documentation for the following types/functions.
11
12 #pragma once
13
14 // Always want minimum headers
15 #ifndef WIN32_LEAN_AND_MEAN
16 #define WIN32_LEAN_AND_MEAN
17 #endif
18
19 // Assume that for everywhere
20 #undef PLATFORM_IS_LITTLE_ENDIAN
21 #define PLATFORM_IS_LITTLE_ENDIAN true
22
23 #include <windows.h>
24 #include <string>
25 #include <string.h>
26 #include <mutex>
27 #include <limits>
28 #include <condition_variable>
29 #include <malloc.h>
30 #include <intrin.h>
31
32 #include <stdint.h>
33
34 #include "port/win/win_thread.h"
35
36 #include "rocksdb/options.h"
37
38 #undef min
39 #undef max
40 #undef DeleteFile
41 #undef GetCurrentTime
42
43
44 #ifndef strcasecmp
45 #define strcasecmp _stricmp
46 #endif
47
48 #undef GetCurrentTime
49 #undef DeleteFile
50
51 #ifndef _SSIZE_T_DEFINED
52 typedef SSIZE_T ssize_t;
53 #endif
54
55 // size_t printf formatting named in the manner of C99 standard formatting
56 // strings such as PRIu64
57 // in fact, we could use that one
58 #ifndef ROCKSDB_PRIszt
59 #define ROCKSDB_PRIszt "Iu"
60 #endif
61
62 #ifdef _MSC_VER
63 #define __attribute__(A)
64
65 // Thread local storage on Linux
66 // There is thread_local in C++11
67 #ifndef __thread
68 #define __thread __declspec(thread)
69 #endif
70
71 #endif
72
73 #ifndef PLATFORM_IS_LITTLE_ENDIAN
74 #define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
75 #endif
76
77 namespace rocksdb {
78
79 #define PREFETCH(addr, rw, locality)
80
81 namespace port {
82
83 // VS < 2015
84 #if defined(_MSC_VER) && (_MSC_VER < 1900)
85
86 // VS 15 has snprintf
87 #define snprintf _snprintf
88
89 #define ROCKSDB_NOEXCEPT
90 // std::numeric_limits<size_t>::max() is not constexpr just yet
91 // therefore, use the same limits
92
93 // For use at db/file_indexer.h kLevelMaxIndex
94 const uint32_t kMaxUint32 = UINT32_MAX;
95 const int kMaxInt32 = INT32_MAX;
96 const int64_t kMaxInt64 = INT64_MAX;
97 const uint64_t kMaxUint64 = UINT64_MAX;
98
99 #ifdef _WIN64
100 const size_t kMaxSizet = UINT64_MAX;
101 #else
102 const size_t kMaxSizet = UINT_MAX;
103 #endif
104
105 #else // VS >= 2015 or MinGW
106
107 #define ROCKSDB_NOEXCEPT noexcept
108
109 // For use at db/file_indexer.h kLevelMaxIndex
110 const uint32_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
111 const int kMaxInt32 = std::numeric_limits<int>::max();
112 const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
113 const int64_t kMaxInt64 = std::numeric_limits<int64_t>::max();
114
115 const size_t kMaxSizet = std::numeric_limits<size_t>::max();
116
117 #endif //_MSC_VER
118
119 const bool kLittleEndian = true;
120
121 class CondVar;
122
123 class Mutex {
124 public:
125
126 /* implicit */ Mutex(bool adaptive = false)
127 #ifndef NDEBUG
128 : locked_(false)
129 #endif
130 { }
131
132 ~Mutex();
133
134 void Lock() {
135 mutex_.lock();
136 #ifndef NDEBUG
137 locked_ = true;
138 #endif
139 }
140
141 void Unlock() {
142 #ifndef NDEBUG
143 locked_ = false;
144 #endif
145 mutex_.unlock();
146 }
147
148 // this will assert if the mutex is not locked
149 // it does NOT verify that mutex is held by a calling thread
150 void AssertHeld() {
151 #ifndef NDEBUG
152 assert(locked_);
153 #endif
154 }
155
156 // Mutex is move only with lock ownership transfer
157 Mutex(const Mutex&) = delete;
158 void operator=(const Mutex&) = delete;
159
160 private:
161
162 friend class CondVar;
163
164 std::mutex& getLock() {
165 return mutex_;
166 }
167
168 std::mutex mutex_;
169 #ifndef NDEBUG
170 bool locked_;
171 #endif
172 };
173
174 class RWMutex {
175 public:
176 RWMutex() { InitializeSRWLock(&srwLock_); }
177
178 void ReadLock() { AcquireSRWLockShared(&srwLock_); }
179
180 void WriteLock() { AcquireSRWLockExclusive(&srwLock_); }
181
182 void ReadUnlock() { ReleaseSRWLockShared(&srwLock_); }
183
184 void WriteUnlock() { ReleaseSRWLockExclusive(&srwLock_); }
185
186 // Empty as in POSIX
187 void AssertHeld() {}
188
189 private:
190 SRWLOCK srwLock_;
191 // No copying allowed
192 RWMutex(const RWMutex&);
193 void operator=(const RWMutex&);
194 };
195
196 class CondVar {
197 public:
198 explicit CondVar(Mutex* mu) : mu_(mu) {
199 }
200
201 ~CondVar();
202 void Wait();
203 bool TimedWait(uint64_t expiration_time);
204 void Signal();
205 void SignalAll();
206
207 // Condition var is not copy/move constructible
208 CondVar(const CondVar&) = delete;
209 CondVar& operator=(const CondVar&) = delete;
210
211 CondVar(CondVar&&) = delete;
212 CondVar& operator=(CondVar&&) = delete;
213
214 private:
215 std::condition_variable cv_;
216 Mutex* mu_;
217 };
218
219 // Wrapper around the platform efficient
220 // or otherwise preferrable implementation
221 using Thread = WindowsThread;
222
223 // OnceInit type helps emulate
224 // Posix semantics with initialization
225 // adopted in the project
226 struct OnceType {
227
228 struct Init {};
229
230 OnceType() {}
231 OnceType(const Init&) {}
232 OnceType(const OnceType&) = delete;
233 OnceType& operator=(const OnceType&) = delete;
234
235 std::once_flag flag_;
236 };
237
238 #define LEVELDB_ONCE_INIT port::OnceType::Init()
239 extern void InitOnce(OnceType* once, void (*initializer)());
240
241 #ifndef CACHE_LINE_SIZE
242 #define CACHE_LINE_SIZE 64U
243 #endif
244
245 #ifdef ROCKSDB_JEMALLOC
246 // Separate inlines so they can be replaced if needed
247 void* jemalloc_aligned_alloc(size_t size, size_t alignment) ROCKSDB_NOEXCEPT;
248 void jemalloc_aligned_free(void* p) ROCKSDB_NOEXCEPT;
249 #endif
250
251 inline void *cacheline_aligned_alloc(size_t size) {
252 #ifdef ROCKSDB_JEMALLOC
253 return jemalloc_aligned_alloc(size, CACHE_LINE_SIZE);
254 #else
255 return _aligned_malloc(size, CACHE_LINE_SIZE);
256 #endif
257 }
258
259 inline void cacheline_aligned_free(void *memblock) {
260 #ifdef ROCKSDB_JEMALLOC
261 jemalloc_aligned_free(memblock);
262 #else
263 _aligned_free(memblock);
264 #endif
265 }
266
267 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 for MINGW32
268 // could not be worked around with by -mno-ms-bitfields
269 #ifndef __MINGW32__
270 #define ALIGN_AS(n) __declspec(align(n))
271 #else
272 #define ALIGN_AS(n)
273 #endif
274
275 static inline void AsmVolatilePause() {
276 #if defined(_M_IX86) || defined(_M_X64)
277 YieldProcessor();
278 #endif
279 // it would be nice to get "wfe" on ARM here
280 }
281
282 extern int PhysicalCoreID();
283
284 // For Thread Local Storage abstraction
285 typedef DWORD pthread_key_t;
286
287 inline int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)) {
288 // Not used
289 (void)destructor;
290
291 pthread_key_t k = TlsAlloc();
292 if (TLS_OUT_OF_INDEXES == k) {
293 return ENOMEM;
294 }
295
296 *key = k;
297 return 0;
298 }
299
300 inline int pthread_key_delete(pthread_key_t key) {
301 if (!TlsFree(key)) {
302 return EINVAL;
303 }
304 return 0;
305 }
306
307 inline int pthread_setspecific(pthread_key_t key, const void* value) {
308 if (!TlsSetValue(key, const_cast<void*>(value))) {
309 return ENOMEM;
310 }
311 return 0;
312 }
313
314 inline void* pthread_getspecific(pthread_key_t key) {
315 void* result = TlsGetValue(key);
316 if (!result) {
317 if (GetLastError() != ERROR_SUCCESS) {
318 errno = EINVAL;
319 } else {
320 errno = NOERROR;
321 }
322 }
323 return result;
324 }
325
326 // UNIX equiv although errno numbers will be off
327 // using C-runtime to implement. Note, this does not
328 // feel space with zeros in case the file is extended.
329 int truncate(const char* path, int64_t length);
330 void Crash(const std::string& srcfile, int srcline);
331 extern int GetMaxOpenFiles();
332
333 } // namespace port
334
335 using port::pthread_key_t;
336 using port::pthread_key_create;
337 using port::pthread_key_delete;
338 using port::pthread_setspecific;
339 using port::pthread_getspecific;
340 using port::truncate;
341
342 } // namespace rocksdb