summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcostan <costan@google.com>2018-09-04 09:31:27 -0700
committerVictor Costan <pwnall@chromium.org>2018-09-04 10:36:40 -0700
commit03064cbbb2c00c3e6e41a78e8111d14a020f7d6f (patch)
tree9e2abcfe5bcaed39e70b7d2d896a9772339f4cd1
parent9b44da73d9b1d839c437e3fdaaa14ea08260dce4 (diff)
downloadleveldb-03064cbbb2c00c3e6e41a78e8111d14a020f7d6f.tar.gz
Simplify Limiter in env_posix.cc.
Now that we require C++11, we can use std::atomic<int>, which has primitives for most of the logic we need. As a bonus, the happy path for Limiter::Acquire() and Limiter::Release() only performs one atomic operation. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=211469518
-rw-r--r--util/env_posix.cc58
1 files changed, 25 insertions, 33 deletions
diff --git a/util/env_posix.cc b/util/env_posix.cc
index 51844ad..18e7664 100644
--- a/util/env_posix.cc
+++ b/util/env_posix.cc
@@ -16,9 +16,12 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
+
+#include <atomic>
#include <deque>
#include <limits>
#include <set>
+
#include "leveldb/env.h"
#include "leveldb/slice.h"
#include "port/port.h"
@@ -53,52 +56,41 @@ static Status PosixError(const std::string& context, int err_number) {
// Helper class to limit resource usage to avoid exhaustion.
// Currently used to limit read-only file descriptors and mmap file usage
-// so that we do not end up running out of file descriptors, virtual memory,
-// or running into kernel performance problems for very large databases.
+// 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 PosixSequentialFile: public SequentialFile {