]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/port/win/port_win.h
update source to Ceph Pacific 16.2.2
[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 #include <windows.h>
20 #include <string>
21 #include <string.h>
22 #include <mutex>
23 #include <limits>
24 #include <condition_variable>
25 #include <malloc.h>
26 #include <intrin.h>
27
28 #include <stdint.h>
29
30 #include "port/win/win_thread.h"
31
32 #include "rocksdb/options.h"
33
34 #undef min
35 #undef max
36 #undef DeleteFile
37 #undef GetCurrentTime
38
39
40 #ifndef strcasecmp
41 #define strcasecmp _stricmp
42 #endif
43
44 #undef GetCurrentTime
45 #undef DeleteFile
46
47 #ifndef _SSIZE_T_DEFINED
48 typedef SSIZE_T ssize_t;
49 #endif
50
51 // size_t printf formatting named in the manner of C99 standard formatting
52 // strings such as PRIu64
53 // in fact, we could use that one
54 #ifndef ROCKSDB_PRIszt
55 #define ROCKSDB_PRIszt "Iu"
56 #endif
57
58 #ifdef _MSC_VER
59 #define __attribute__(A)
60
61 // Thread local storage on Linux
62 // There is thread_local in C++11
63 #ifndef __thread
64 #define __thread __declspec(thread)
65 #endif
66
67 #endif
68
69 namespace ROCKSDB_NAMESPACE {
70
71 #define PREFETCH(addr, rw, locality)
72
73 extern const bool kDefaultToAdaptiveMutex;
74
75 namespace port {
76
77 // VS < 2015
78 #if defined(_MSC_VER) && (_MSC_VER < 1900)
79
80 // VS 15 has snprintf
81 #define snprintf _snprintf
82
83 #define ROCKSDB_NOEXCEPT
84 // std::numeric_limits<size_t>::max() is not constexpr just yet
85 // therefore, use the same limits
86
87 // For use at db/file_indexer.h kLevelMaxIndex
88 const uint32_t kMaxUint32 = UINT32_MAX;
89 const int kMaxInt32 = INT32_MAX;
90 const int kMinInt32 = INT32_MIN;
91 const int64_t kMaxInt64 = INT64_MAX;
92 const int64_t kMinInt64 = INT64_MIN;
93 const uint64_t kMaxUint64 = UINT64_MAX;
94
95 #ifdef _WIN64
96 const size_t kMaxSizet = UINT64_MAX;
97 #else
98 const size_t kMaxSizet = UINT_MAX;
99 #endif
100
101 #else // VS >= 2015 or MinGW
102
103 #define ROCKSDB_NOEXCEPT noexcept
104
105 // For use at db/file_indexer.h kLevelMaxIndex
106 const uint32_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
107 const int kMaxInt32 = std::numeric_limits<int>::max();
108 const int kMinInt32 = std::numeric_limits<int>::min();
109 const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
110 const int64_t kMaxInt64 = std::numeric_limits<int64_t>::max();
111 const int64_t kMinInt64 = std::numeric_limits<int64_t>::min();
112
113 const size_t kMaxSizet = std::numeric_limits<size_t>::max();
114
115 #endif //_MSC_VER
116
117 // "Windows is designed to run on little-endian computer architectures."
118 // https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-value-types
119 constexpr bool kLittleEndian = true;
120 #undef PLATFORM_IS_LITTLE_ENDIAN
121
122 class CondVar;
123
124 class Mutex {
125 public:
126
127 /* implicit */ Mutex(bool adaptive = kDefaultToAdaptiveMutex)
128 #ifndef NDEBUG
129 : locked_(false)
130 #endif
131 { }
132
133 ~Mutex();
134
135 void Lock() {
136 mutex_.lock();
137 #ifndef NDEBUG
138 locked_ = true;
139 #endif
140 }
141
142 void Unlock() {
143 #ifndef NDEBUG
144 locked_ = false;
145 #endif
146 mutex_.unlock();
147 }
148
149 // this will assert if the mutex is not locked
150 // it does NOT verify that mutex is held by a calling thread
151 void AssertHeld() {
152 #ifndef NDEBUG
153 assert(locked_);
154 #endif
155 }
156
157 // Mutex is move only with lock ownership transfer
158 Mutex(const Mutex&) = delete;
159 void operator=(const Mutex&) = delete;
160
161 private:
162
163 friend class CondVar;
164
165 std::mutex& getLock() {
166 return mutex_;
167 }
168
169 std::mutex mutex_;
170 #ifndef NDEBUG
171 bool locked_;
172 #endif
173 };
174
175 class RWMutex {
176 public:
177 RWMutex() { InitializeSRWLock(&srwLock_); }
178 // No copying allowed
179 RWMutex(const RWMutex&) = delete;
180 void operator=(const RWMutex&) = delete;
181
182 void ReadLock() { AcquireSRWLockShared(&srwLock_); }
183
184 void WriteLock() { AcquireSRWLockExclusive(&srwLock_); }
185
186 void ReadUnlock() { ReleaseSRWLockShared(&srwLock_); }
187
188 void WriteUnlock() { ReleaseSRWLockExclusive(&srwLock_); }
189
190 // Empty as in POSIX
191 void AssertHeld() {}
192
193 private:
194 SRWLOCK srwLock_;
195 };
196
197 class CondVar {
198 public:
199 explicit CondVar(Mutex* mu) : mu_(mu) {
200 }
201
202 ~CondVar();
203 void Wait();
204 bool TimedWait(uint64_t expiration_time);
205 void Signal();
206 void SignalAll();
207
208 // Condition var is not copy/move constructible
209 CondVar(const CondVar&) = delete;
210 CondVar& operator=(const CondVar&) = delete;
211
212 CondVar(CondVar&&) = delete;
213 CondVar& operator=(CondVar&&) = delete;
214
215 private:
216 std::condition_variable cv_;
217 Mutex* mu_;
218 };
219
220 // Wrapper around the platform efficient
221 // or otherwise preferrable implementation
222 using Thread = WindowsThread;
223
224 // OnceInit type helps emulate
225 // Posix semantics with initialization
226 // adopted in the project
227 struct OnceType {
228
229 struct Init {};
230
231 OnceType() {}
232 OnceType(const Init&) {}
233 OnceType(const OnceType&) = delete;
234 OnceType& operator=(const OnceType&) = delete;
235
236 std::once_flag flag_;
237 };
238
239 #define LEVELDB_ONCE_INIT port::OnceType::Init()
240 extern void InitOnce(OnceType* once, void (*initializer)());
241
242 #ifndef CACHE_LINE_SIZE
243 #define CACHE_LINE_SIZE 64U
244 #endif
245
246 #ifdef ROCKSDB_JEMALLOC
247 // Separate inlines so they can be replaced if needed
248 void* jemalloc_aligned_alloc(size_t size, size_t alignment) ROCKSDB_NOEXCEPT;
249 void jemalloc_aligned_free(void* p) ROCKSDB_NOEXCEPT;
250 #endif
251
252 inline void *cacheline_aligned_alloc(size_t size) {
253 #ifdef ROCKSDB_JEMALLOC
254 return jemalloc_aligned_alloc(size, CACHE_LINE_SIZE);
255 #else
256 return _aligned_malloc(size, CACHE_LINE_SIZE);
257 #endif
258 }
259
260 inline void cacheline_aligned_free(void *memblock) {
261 #ifdef ROCKSDB_JEMALLOC
262 jemalloc_aligned_free(memblock);
263 #else
264 _aligned_free(memblock);
265 #endif
266 }
267
268 extern const size_t kPageSize;
269
270 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 for MINGW32
271 // could not be worked around with by -mno-ms-bitfields
272 #ifndef __MINGW32__
273 #define ALIGN_AS(n) __declspec(align(n))
274 #else
275 #define ALIGN_AS(n)
276 #endif
277
278 static inline void AsmVolatilePause() {
279 #if defined(_M_IX86) || defined(_M_X64)
280 YieldProcessor();
281 #endif
282 // it would be nice to get "wfe" on ARM here
283 }
284
285 extern int PhysicalCoreID();
286
287 // For Thread Local Storage abstraction
288 typedef DWORD pthread_key_t;
289
290 inline int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)) {
291 // Not used
292 (void)destructor;
293
294 pthread_key_t k = TlsAlloc();
295 if (TLS_OUT_OF_INDEXES == k) {
296 return ENOMEM;
297 }
298
299 *key = k;
300 return 0;
301 }
302
303 inline int pthread_key_delete(pthread_key_t key) {
304 if (!TlsFree(key)) {
305 return EINVAL;
306 }
307 return 0;
308 }
309
310 inline int pthread_setspecific(pthread_key_t key, const void* value) {
311 if (!TlsSetValue(key, const_cast<void*>(value))) {
312 return ENOMEM;
313 }
314 return 0;
315 }
316
317 inline void* pthread_getspecific(pthread_key_t key) {
318 void* result = TlsGetValue(key);
319 if (!result) {
320 if (GetLastError() != ERROR_SUCCESS) {
321 errno = EINVAL;
322 } else {
323 errno = NOERROR;
324 }
325 }
326 return result;
327 }
328
329 // UNIX equiv although errno numbers will be off
330 // using C-runtime to implement. Note, this does not
331 // feel space with zeros in case the file is extended.
332 int truncate(const char* path, int64_t length);
333 int Truncate(std::string path, int64_t length);
334 void Crash(const std::string& srcfile, int srcline);
335 extern int GetMaxOpenFiles();
336 std::string utf16_to_utf8(const std::wstring& utf16);
337 std::wstring utf8_to_utf16(const std::string& utf8);
338
339 } // namespace port
340
341
342 #ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES
343
344 #define RX_FILESTRING std::wstring
345 #define RX_FN(a) ROCKSDB_NAMESPACE::port::utf8_to_utf16(a)
346 #define FN_TO_RX(a) ROCKSDB_NAMESPACE::port::utf16_to_utf8(a)
347 #define RX_FNLEN(a) ::wcslen(a)
348
349 #define RX_DeleteFile DeleteFileW
350 #define RX_CreateFile CreateFileW
351 #define RX_CreateFileMapping CreateFileMappingW
352 #define RX_GetFileAttributesEx GetFileAttributesExW
353 #define RX_FindFirstFileEx FindFirstFileExW
354 #define RX_FindNextFile FindNextFileW
355 #define RX_WIN32_FIND_DATA WIN32_FIND_DATAW
356 #define RX_CreateDirectory CreateDirectoryW
357 #define RX_RemoveDirectory RemoveDirectoryW
358 #define RX_GetFileAttributesEx GetFileAttributesExW
359 #define RX_MoveFileEx MoveFileExW
360 #define RX_CreateHardLink CreateHardLinkW
361 #define RX_PathIsRelative PathIsRelativeW
362 #define RX_GetCurrentDirectory GetCurrentDirectoryW
363 #define RX_GetDiskFreeSpaceEx GetDiskFreeSpaceExW
364
365 #else
366
367 #define RX_FILESTRING std::string
368 #define RX_FN(a) a
369 #define FN_TO_RX(a) a
370 #define RX_FNLEN(a) strlen(a)
371
372 #define RX_DeleteFile DeleteFileA
373 #define RX_CreateFile CreateFileA
374 #define RX_CreateFileMapping CreateFileMappingA
375 #define RX_GetFileAttributesEx GetFileAttributesExA
376 #define RX_FindFirstFileEx FindFirstFileExA
377 #define RX_CreateDirectory CreateDirectoryA
378 #define RX_FindNextFile FindNextFileA
379 #define RX_WIN32_FIND_DATA WIN32_FIND_DATA
380 #define RX_CreateDirectory CreateDirectoryA
381 #define RX_RemoveDirectory RemoveDirectoryA
382 #define RX_GetFileAttributesEx GetFileAttributesExA
383 #define RX_MoveFileEx MoveFileExA
384 #define RX_CreateHardLink CreateHardLinkA
385 #define RX_PathIsRelative PathIsRelativeA
386 #define RX_GetCurrentDirectory GetCurrentDirectoryA
387 #define RX_GetDiskFreeSpaceEx GetDiskFreeSpaceExA
388
389 #endif
390
391 using port::pthread_key_t;
392 using port::pthread_key_create;
393 using port::pthread_key_delete;
394 using port::pthread_setspecific;
395 using port::pthread_getspecific;
396 using port::truncate;
397
398 } // namespace ROCKSDB_NAMESPACE