diff options
author | costan <costan@google.com> | 2019-03-11 13:04:53 -0700 |
---|---|---|
committer | Chris Mumford <cmumford@google.com> | 2019-03-11 13:41:25 -0700 |
commit | 7d8e41e49b8fddda66a2c5f0a6a47f1a916e8d26 (patch) | |
tree | 0a5556aaf20ba27bd6ea0ab3792d1366e60b2f81 /util/env_windows.cc | |
parent | dd906262fd364c08a652dfa914f9995f6b7608a9 (diff) | |
download | leveldb-7d8e41e49b8fddda66a2c5f0a6a47f1a916e8d26.tar.gz |
leveldb: Replace AtomicPointer with std::atomic.
This CL removes AtomicPointer from leveldb's port interface. Its usage is replaced with std::atomic<> from the C++11 standard library.
AtomicPointer was used to wrap flags, numbers, and pointers, so its instances are replaced with std::atomic<bool>, std::atomic<int>, std::atomic<size_t> and std::atomic<Node*>.
This CL does not revise the memory ordering. AtomicPointer's methods are replaced mechanically with their std::atomic equivalents, even when the underlying usage is incorrect. (Example: DBImpl::has_imm_ is written using release stores, even though it is always read using relaxed ordering.) Revising the memory ordering is left for future CLs.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=237865146
Diffstat (limited to 'util/env_windows.cc')
-rw-r--r-- | util/env_windows.cc | 56 |
1 files changed, 24 insertions, 32 deletions
diff --git a/util/env_windows.cc b/util/env_windows.cc index 57932bb..3b4496b 100644 --- a/util/env_windows.cc +++ b/util/env_windows.cc @@ -8,6 +8,7 @@ #include <windows.h> #include <algorithm> +#include <atomic> #include <chrono> #include <condition_variable> #include <deque> @@ -105,51 +106,42 @@ class ScopedHandle { }; // Helper class to limit resource usage to avoid exhaustion. -// Currently used to limit mmap file usage so that we do not end -// up running out virtual memory, or running into kernel performance -// problems for very large databases. +// Currently used to limit read-only file descriptors and mmap file usage +// so that we do not run out of file descriptors or virtual memory, or run into +// kernel performance problems for very large databases. class Limiter { public: - // Limit maximum number of resources to |n|. - Limiter(intptr_t n) { SetAllowed(n); } + // Limit maximum number of resources to |max_acquires|. + Limiter(int max_acquires) : acquires_allowed_(max_acquires) {} + + Limiter(const Limiter&) = delete; + Limiter operator=(const Limiter&) = delete; // If another resource is available, acquire it and return true. // Else return false. - bool Acquire() LOCKS_EXCLUDED(mu_) { - if (GetAllowed() <= 0) { - return false; - } - MutexLock l(&mu_); - intptr_t x = GetAllowed(); - if (x <= 0) { - return false; - } else { - SetAllowed(x - 1); + bool Acquire() { + int old_acquires_allowed = + acquires_allowed_.fetch_sub(1, std::memory_order_relaxed); + + if (old_acquires_allowed > 0) return true; - } + + acquires_allowed_.fetch_add(1, std::memory_order_relaxed); + return false; } // Release a resource acquired by a previous call to Acquire() that returned // true. - void Release() LOCKS_EXCLUDED(mu_) { - MutexLock l(&mu_); - SetAllowed(GetAllowed() + 1); + void Release() { + acquires_allowed_.fetch_add(1, std::memory_order_relaxed); } private: - port::Mutex mu_; - port::AtomicPointer allowed_; - - intptr_t GetAllowed() const { - return reinterpret_cast<intptr_t>(allowed_.Acquire_Load()); - } - - void SetAllowed(intptr_t v) EXCLUSIVE_LOCKS_REQUIRED(mu_) { - allowed_.Release_Store(reinterpret_cast<void*>(v)); - } - - Limiter(const Limiter&); - void operator=(const Limiter&); + // The number of available resources. + // + // This is a counter and is not tied to the invariants of any other class, so + // it can be operated on safely using std::memory_order_relaxed. + std::atomic<int> acquires_allowed_; }; class WindowsSequentialFile : public SequentialFile { |