mirror of
https://github.com/google/leveldb.git
synced 2024-11-30 18:28:59 +08:00
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
This commit is contained in:
parent
9b44da73d9
commit
03064cbbb2
@ -16,9 +16,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "leveldb/slice.h"
|
#include "leveldb/slice.h"
|
||||||
#include "port/port.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.
|
// Helper class to limit resource usage to avoid exhaustion.
|
||||||
// Currently used to limit read-only file descriptors and mmap file usage
|
// 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,
|
// so that we do not run out of file descriptors or virtual memory, or run into
|
||||||
// or running into kernel performance problems for very large databases.
|
// kernel performance problems for very large databases.
|
||||||
class Limiter {
|
class Limiter {
|
||||||
public:
|
public:
|
||||||
// Limit maximum number of resources to |n|.
|
// Limit maximum number of resources to |max_acquires|.
|
||||||
Limiter(intptr_t n) {
|
Limiter(int max_acquires) : acquires_allowed_(max_acquires) {}
|
||||||
SetAllowed(n);
|
|
||||||
}
|
Limiter(const Limiter&) = delete;
|
||||||
|
Limiter operator=(const Limiter&) = delete;
|
||||||
|
|
||||||
// If another resource is available, acquire it and return true.
|
// If another resource is available, acquire it and return true.
|
||||||
// Else return false.
|
// Else return false.
|
||||||
bool Acquire() LOCKS_EXCLUDED(mu_) {
|
bool Acquire() {
|
||||||
if (GetAllowed() <= 0) {
|
int old_acquires_allowed =
|
||||||
return false;
|
acquires_allowed_.fetch_sub(1, std::memory_order_relaxed);
|
||||||
}
|
|
||||||
MutexLock l(&mu_);
|
if (old_acquires_allowed > 0)
|
||||||
intptr_t x = GetAllowed();
|
|
||||||
if (x <= 0) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
SetAllowed(x - 1);
|
|
||||||
return true;
|
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
|
// Release a resource acquired by a previous call to Acquire() that returned
|
||||||
// true.
|
// true.
|
||||||
void Release() LOCKS_EXCLUDED(mu_) {
|
void Release() {
|
||||||
MutexLock l(&mu_);
|
acquires_allowed_.fetch_add(1, std::memory_order_relaxed);
|
||||||
SetAllowed(GetAllowed() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
port::Mutex mu_;
|
// The number of available resources.
|
||||||
port::AtomicPointer allowed_;
|
//
|
||||||
|
// This is a counter and is not tied to the invariants of any other class, so
|
||||||
intptr_t GetAllowed() const {
|
// it can be operated on safely using std::memory_order_relaxed.
|
||||||
return reinterpret_cast<intptr_t>(allowed_.Acquire_Load());
|
std::atomic<int> acquires_allowed_;
|
||||||
}
|
|
||||||
|
|
||||||
void SetAllowed(intptr_t v) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
|
||||||
allowed_.Release_Store(reinterpret_cast<void*>(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
Limiter(const Limiter&);
|
|
||||||
void operator=(const Limiter&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PosixSequentialFile: public SequentialFile {
|
class PosixSequentialFile: public SequentialFile {
|
||||||
|
Loading…
Reference in New Issue
Block a user