-
Notifications
You must be signed in to change notification settings - Fork 2
/
version_buffer.h
82 lines (67 loc) · 2.1 KB
/
version_buffer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// version_buffer.h
// Copyright (c) 2014 Jinglei Ren <jinglei@ren.systems>
#ifndef SEXAIN_VERSION_BUFFER_H_
#define SEXAIN_VERSION_BUFFER_H_
#include <vector>
#include <set>
#include <limits>
#include <cstdint>
#include <cassert>
#include "profiler.h"
#define INVAL_ADDR std::numeric_limits<uint64_t>::max()
class VersionBuffer {
public:
enum State {
BACKUP0 = 0,
BACKUP1,
IN_USE,
FREE, // max queue index
};
VersionBuffer(int length, int block_bits);
uint64_t SlotAlloc(Profiler& pf);
void FreeSlot(uint64_t mach_addr, State state, Profiler& pf);
void SlotBackup(uint64_t mach_addr, State state, Profiler& pf);
void ClearBackup(Profiler& pf);
uint64_t addr_base() const { return addr_base_; }
void set_addr_base(uint64_t base) { addr_base_ = base; }
int length() const { return length_; }
int block_size() const { return 1 << block_bits_; }
/// The total address space size that this buffer area covers in bytes
uint64_t Size() const;
bool Contains(uint64_t addr) const;
private:
uint64_t At(int index);
int Index(uint64_t mach_addr);
uint64_t addr_base_;
const int length_;
const int block_bits_;
const uint64_t block_mask_;
std::vector<std::set<int>> sets_;
};
inline VersionBuffer::VersionBuffer(int length, int block_bits) :
length_(length), block_bits_(block_bits),
block_mask_(block_size() - 1), sets_(FREE + 1) {
for (int i = 0; i < length_; ++i) {
sets_[FREE].insert(i);
}
addr_base_ = INVAL_ADDR;
}
inline uint64_t VersionBuffer::Size() const {
return length_ << block_bits_;
}
inline bool VersionBuffer::Contains(uint64_t addr) const {
return addr >= addr_base_ && (addr - addr_base_) < Size();
}
inline uint64_t VersionBuffer::At(int index) {
assert(addr_base_ != INVAL_ADDR && index >= 0 && index < length_);
return addr_base_ + (index << block_bits_);
}
inline int VersionBuffer::Index(uint64_t mach_addr) {
assert(mach_addr >= addr_base_);
uint64_t bytes = mach_addr - addr_base_;
assert((bytes & block_mask_) == 0);
int i = bytes >> block_bits_;
assert(i >= 0 && i < length_);
return i;
}
#endif // SEXAIN_VERSION_BUFFER_H_