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