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