env_win.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  6. // Use of this source code is governed by a BSD-style license that can be
  7. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  8. //
  9. // An Env is an interface used by the rocksdb implementation to access
  10. // operating system functionality like the filesystem etc. Callers
  11. // may wish to provide a custom Env object when opening a database to
  12. // get fine gain control; e.g., to rate limit file system operations.
  13. //
  14. // All Env implementations are safe for concurrent access from
  15. // multiple threads without any external synchronization.
  16. #pragma once
  17. #include <stdint.h>
  18. #include <windows.h>
  19. #include <mutex>
  20. #include <string>
  21. #include <vector>
  22. #include "env/composite_env_wrapper.h"
  23. #include "port/port.h"
  24. #include "rocksdb/env.h"
  25. #include "rocksdb/file_system.h"
  26. #include "rocksdb/system_clock.h"
  27. #include "util/threadpool_imp.h"
  28. #undef GetCurrentTime
  29. #undef DeleteFile
  30. #undef LoadLibrary
  31. namespace ROCKSDB_NAMESPACE {
  32. namespace port {
  33. // Currently not designed for inheritance but rather a replacement
  34. class WinEnvThreads {
  35. public:
  36. explicit WinEnvThreads(Env* hosted_env);
  37. ~WinEnvThreads();
  38. WinEnvThreads(const WinEnvThreads&) = delete;
  39. WinEnvThreads& operator=(const WinEnvThreads&) = delete;
  40. void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
  41. void* tag, void (*unschedFunction)(void* arg));
  42. int UnSchedule(void* arg, Env::Priority pri);
  43. void StartThread(void (*function)(void* arg), void* arg);
  44. void WaitForJoin();
  45. unsigned int GetThreadPoolQueueLen(Env::Priority pri) const;
  46. int ReserveThreads(int threads_to_be_reserved, Env::Priority pri);
  47. int ReleaseThreads(int threads_to_be_released, Env::Priority pri);
  48. static uint64_t gettid();
  49. uint64_t GetThreadID() const;
  50. // Allow increasing the number of worker threads.
  51. void SetBackgroundThreads(int num, Env::Priority pri);
  52. int GetBackgroundThreads(Env::Priority pri);
  53. void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri);
  54. private:
  55. Env* hosted_env_;
  56. mutable std::mutex mu_;
  57. std::vector<ThreadPoolImpl> thread_pools_;
  58. std::vector<Thread> threads_to_join_;
  59. };
  60. class WinClock : public SystemClock {
  61. public:
  62. WinClock();
  63. virtual ~WinClock() {}
  64. static const char* kClassName() { return "WindowsClock"; }
  65. const char* Name() const override { return kDefaultName(); }
  66. const char* NickName() const override { return kClassName(); }
  67. uint64_t NowMicros() override;
  68. uint64_t NowNanos() override;
  69. // 0 indicates not supported
  70. uint64_t CPUMicros() override { return 0; }
  71. void SleepForMicroseconds(int micros) override;
  72. Status GetCurrentTime(int64_t* unix_time) override;
  73. // Converts seconds-since-Jan-01-1970 to a printable string
  74. std::string TimeToString(uint64_t time) override;
  75. uint64_t GetPerfCounterFrequency() const { return perf_counter_frequency_; }
  76. private:
  77. using FnGetSystemTimePreciseAsFileTime = VOID(WINAPI*)(LPFILETIME);
  78. uint64_t perf_counter_frequency_;
  79. uint64_t nano_seconds_per_period_;
  80. FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_;
  81. };
  82. class WinFileSystem : public FileSystem {
  83. public:
  84. static const std::shared_ptr<WinFileSystem>& Default();
  85. WinFileSystem(const std::shared_ptr<SystemClock>& clock);
  86. ~WinFileSystem() {}
  87. static const char* kClassName() { return "WinFS"; }
  88. const char* Name() const override { return kClassName(); }
  89. const char* NickName() const override { return kDefaultName(); }
  90. static size_t GetSectorSize(const std::string& fname);
  91. size_t GetPageSize() const { return page_size_; }
  92. size_t GetAllocationGranularity() const { return allocation_granularity_; }
  93. IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
  94. IODebugContext* dbg) override;
  95. // Truncate the named file to the specified size.
  96. IOStatus Truncate(const std::string& /*fname*/, size_t /*size*/,
  97. const IOOptions& /*options*/,
  98. IODebugContext* /*dbg*/) override;
  99. IOStatus NewSequentialFile(const std::string& fname,
  100. const FileOptions& file_opts,
  101. std::unique_ptr<FSSequentialFile>* result,
  102. IODebugContext* dbg) override;
  103. IOStatus NewRandomAccessFile(const std::string& fname,
  104. const FileOptions& options,
  105. std::unique_ptr<FSRandomAccessFile>* result,
  106. IODebugContext* /*dbg*/) override;
  107. IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
  108. std::unique_ptr<FSWritableFile>* r,
  109. IODebugContext* dbg) override;
  110. IOStatus ReopenWritableFile(const std::string& fname,
  111. const FileOptions& options,
  112. std::unique_ptr<FSWritableFile>* result,
  113. IODebugContext* dbg) override;
  114. IOStatus NewRandomRWFile(const std::string& fname,
  115. const FileOptions& file_opts,
  116. std::unique_ptr<FSRandomRWFile>* result,
  117. IODebugContext* dbg) override;
  118. IOStatus NewMemoryMappedFileBuffer(
  119. const std::string& fname,
  120. std::unique_ptr<MemoryMappedFileBuffer>* result) override;
  121. IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts,
  122. std::unique_ptr<FSDirectory>* result,
  123. IODebugContext* dbg) override;
  124. IOStatus FileExists(const std::string& f, const IOOptions& io_opts,
  125. IODebugContext* dbg) override;
  126. IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
  127. std::vector<std::string>* r,
  128. IODebugContext* dbg) override;
  129. IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
  130. IODebugContext* dbg) override;
  131. // Creates directory if missing. Return Ok if it exists, or successful in
  132. // Creating.
  133. IOStatus CreateDirIfMissing(const std::string& dirname,
  134. const IOOptions& options,
  135. IODebugContext* dbg) override;
  136. // Delete the specified directory.
  137. IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
  138. IODebugContext* dbg) override;
  139. // Store the size of fname in *file_size.
  140. IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
  141. uint64_t* file_size, IODebugContext* dbg) override;
  142. // Store the last modification time of fname in *file_mtime.
  143. IOStatus GetFileModificationTime(const std::string& fname,
  144. const IOOptions& options,
  145. uint64_t* file_mtime,
  146. IODebugContext* dbg) override;
  147. // Rename file src to target.
  148. IOStatus RenameFile(const std::string& src, const std::string& target,
  149. const IOOptions& options, IODebugContext* dbg) override;
  150. // Hard Link file src to target.
  151. IOStatus LinkFile(const std::string& /*src*/, const std::string& /*target*/,
  152. const IOOptions& /*options*/,
  153. IODebugContext* /*dbg*/) override;
  154. IOStatus NumFileLinks(const std::string& /*fname*/,
  155. const IOOptions& /*options*/, uint64_t* /*count*/,
  156. IODebugContext* /*dbg*/) override;
  157. IOStatus AreFilesSame(const std::string& /*first*/,
  158. const std::string& /*second*/,
  159. const IOOptions& /*options*/, bool* /*res*/,
  160. IODebugContext* /*dbg*/) override;
  161. IOStatus LockFile(const std::string& fname, const IOOptions& options,
  162. FileLock** lock, IODebugContext* dbg) override;
  163. IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
  164. IODebugContext* dbg) override;
  165. IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
  166. IODebugContext* dbg) override;
  167. // Create and returns a default logger (an instance of EnvLogger) for storing
  168. // informational messages. Derived classes can override to provide custom
  169. // logger.
  170. IOStatus NewLogger(const std::string& fname, const IOOptions& io_opts,
  171. std::shared_ptr<Logger>* result,
  172. IODebugContext* dbg) override;
  173. // Get full directory name for this db.
  174. IOStatus GetAbsolutePath(const std::string& db_path, const IOOptions& options,
  175. std::string* output_path,
  176. IODebugContext* dbg) override;
  177. IOStatus IsDirectory(const std::string& /*path*/, const IOOptions& options,
  178. bool* is_dir, IODebugContext* /*dgb*/) override;
  179. // This seems to clash with a macro on Windows, so #undef it here
  180. #undef GetFreeSpace
  181. IOStatus GetFreeSpace(const std::string& /*path*/,
  182. const IOOptions& /*options*/, uint64_t* /*diskfree*/,
  183. IODebugContext* /*dbg*/) override;
  184. FileOptions OptimizeForLogWrite(const FileOptions& file_options,
  185. const DBOptions& db_options) const override;
  186. FileOptions OptimizeForManifestRead(
  187. const FileOptions& file_options) const override;
  188. FileOptions OptimizeForManifestWrite(
  189. const FileOptions& file_options) const override;
  190. void SupportedOps(int64_t& supported_ops) override { supported_ops = 0; }
  191. protected:
  192. static uint64_t FileTimeToUnixTime(const FILETIME& ftTime);
  193. // Returns true iff the named directory exists and is a directory.
  194. virtual bool DirExists(const std::string& dname);
  195. // Helper for NewWritable and ReopenWritableFile
  196. virtual IOStatus OpenWritableFile(const std::string& fname,
  197. const FileOptions& options,
  198. std::unique_ptr<FSWritableFile>* result,
  199. bool reopen);
  200. private:
  201. std::shared_ptr<SystemClock> clock_;
  202. size_t page_size_;
  203. size_t allocation_granularity_;
  204. };
  205. // Designed for inheritance so can be re-used
  206. // but certain parts replaced
  207. class WinEnvIO {
  208. public:
  209. explicit WinEnvIO(Env* hosted_env);
  210. virtual ~WinEnvIO();
  211. virtual Status GetHostName(char* name, uint64_t len);
  212. private:
  213. Env* hosted_env_;
  214. };
  215. class WinEnv : public CompositeEnv {
  216. public:
  217. WinEnv();
  218. ~WinEnv();
  219. static const char* kClassName() { return "WinEnv"; }
  220. const char* Name() const override { return kClassName(); }
  221. const char* NickName() const override { return kDefaultName(); }
  222. Status GetHostName(char* name, uint64_t len) override;
  223. Status GetThreadList(std::vector<ThreadStatus>* thread_list) override;
  224. void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
  225. void* tag, void (*unschedFunction)(void* arg)) override;
  226. int UnSchedule(void* arg, Env::Priority pri) override;
  227. void StartThread(void (*function)(void* arg), void* arg) override;
  228. void WaitForJoin() override;
  229. unsigned int GetThreadPoolQueueLen(Env::Priority pri) const override;
  230. int ReserveThreads(int threads_to_be_reserved, Env::Priority pri) override;
  231. int ReleaseThreads(int threads_to_be_released, Env::Priority pri) override;
  232. uint64_t GetThreadID() const override;
  233. // Allow increasing the number of worker threads.
  234. void SetBackgroundThreads(int num, Env::Priority pri) override;
  235. int GetBackgroundThreads(Env::Priority pri) override;
  236. void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri) override;
  237. private:
  238. WinEnvIO winenv_io_;
  239. WinEnvThreads winenv_threads_;
  240. };
  241. } // namespace port
  242. } // namespace ROCKSDB_NAMESPACE