GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 66.1% 82 / 0 / 124
Functions: 81.8% 9 / 0 / 11
Branches: 29.8% 103 / 0 / 346

memory/shm_file.cc
Line Branch Exec Source
1 #include "shm_file.h"
2
3 #include <algorithm>
4 #include <iostream>
5 #ifdef __linux__
6 # include <sys/stat.h>
7 #endif
8
9 namespace base {
10 namespace {
11
12 constexpr const char* kFsDaxType = "FS_DAX";
13 constexpr const char* kAnonyDramType = "ANONY_DRAM";
14 constexpr const char* kDevDaxType = "DEV_DAX";
15
16 730 json BuildShmFileConfig(
17 const std::string& type, const std::string& filename, int64 size) {
18
15/30
✓ Branch 3 taken 730 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 730 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 730 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 730 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 730 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 730 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 730 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2190 times.
✓ Branch 25 taken 730 times.
✓ Branch 27 taken 1460 times.
✓ Branch 28 taken 730 times.
✓ Branch 30 taken 1460 times.
✓ Branch 31 taken 730 times.
✓ Branch 33 taken 1460 times.
✓ Branch 34 taken 730 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
7300 return json{{"type", type}, {"filename", filename}, {"size", size}};
19 }
20
21 } // namespace
22
23 736 std::unique_ptr<ShmFile> ShmFile::New(const json& config) {
24
3/16
✓ Branch 1 taken 736 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 736 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
736 CHECK(config.contains("type")) << "ShmFile config requires type";
25
2/4
✓ Branch 1 taken 736 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 736 times.
✗ Branch 5 not taken.
736 const std::string type = config.at("type").get<std::string>();
26 using SF = base::Factory<ShmFile, const json&>;
27
1/2
✓ Branch 1 taken 736 times.
✗ Branch 2 not taken.
736 std::unique_ptr<ShmFile> shm_file(SF::NewInstance(type, config));
28
3/4
✓ Branch 2 taken 736 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 734 times.
736 if (!shm_file->Initialize(config)) {
29 2 return nullptr;
30 }
31 734 return shm_file;
32 736 }
33
34 730 json ShmFile::ConfigForMedium(
35 const std::string& medium, const std::string& filename, int64 size) {
36
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 if (medium == "DRAM")
37
2/4
✓ Branch 2 taken 730 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 730 times.
✗ Branch 6 not taken.
730 return BuildShmFileConfig(kAnonyDramType, filename, size);
38 // return BuildShmFileConfig(kDevDaxType, filename, size);
39 if (medium == "SSD")
40 return BuildShmFileConfig(kFsDaxType, filename, size);
41 LOG(FATAL) << "Unsupported ShmFile medium: " << medium;
42 return json();
43 }
44
45 736 std::string ShmFile::ConfigFilename(const json& config) {
46
2/14
✗ Branch 1 not taken.
✓ Branch 2 taken 736 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 736 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
736 CHECK(config.contains("filename")) << "ShmFile config requires filename";
47 736 return config.at("filename").get<std::string>();
48 }
49
50 736 int64 ShmFile::ConfigSize(const json& config) {
51
2/14
✗ Branch 1 not taken.
✓ Branch 2 taken 736 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 736 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
736 CHECK(config.contains("size")) << "ShmFile config requires size";
52 736 return config.at("size").get<int64>();
53 }
54
55 6 bool FsDaxShmFile::Initialize(const json& config) {
56
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 Clear();
57
58
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 const std::string filename = ConfigFilename(config);
59
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 const int64 size = ConfigSize(config);
60
61 6 std::error_code ec;
62
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 bool file_exists = fs::exists(filename, ec);
63
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (ec) {
64 LOG(ERROR) << "fs::exists failed for " << filename << ": " << ec.message();
65 return false;
66 }
67
68
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (!file_exists) {
69
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
4 fs::create_directories(fs::path(filename).parent_path(), ec);
70
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (ec) {
71 LOG(ERROR) << "fs::create_directories failed: " << ec.message();
72 return false;
73 }
74
6/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
4 LOG(INFO) << "Create ShmFile: " << filename << ", size: " << size;
75 }
76
77
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 fd_ = open(filename.c_str(), O_RDWR | O_CREAT, 0666);
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (fd_ < 0) {
79 LOG(ERROR) << "Failed to open file " << filename << ": " << strerror(errno);
80 return false;
81 }
82
83
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (!file_exists) {
84
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 int ret = posix_fallocate(fd_, 0, size);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ret != 0) {
86 LOG(ERROR) << "posix_fallocate failed: " << strerror(ret);
87 close(fd_);
88 fd_ = -1;
89 return false;
90 }
91 }
92
93 struct stat st;
94
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (fstat(fd_, &st) != 0) {
95 LOG(ERROR) << "fstat failed: " << strerror(errno);
96 close(fd_);
97 fd_ = -1;
98 return false;
99 }
100 6 size_ = st.st_size;
101
102
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (size_ != size) {
103
6/12
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
2 LOG(ERROR) << "Size Error: " << size_ << " vs " << size;
104
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 close(fd_);
105 2 fd_ = -1;
106 2 size_ = 0;
107 2 return false;
108 }
109
110 4 data_ = reinterpret_cast<char*>(
111 4 mmap(nullptr, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
112
2/10
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
4 CHECK_NE(data_, MAP_FAILED) << "map failed";
113
114
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 filename_ = filename;
115
6/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
8 LOG(INFO) << "mmap shm file: " << filename << ", size: " << size_
116
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 << ", fd: " << fd_;
117 4 return true;
118 6 }
119
120 12 void FsDaxShmFile::Clear() {
121
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (fd_ >= 0) {
122
5/10
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
8 LOG(INFO) << "ummap shm file: " << filename_ << ", size: " << size_
123
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 << ", fd: " << fd_;
124 4 munmap(data_, size_);
125 4 close(fd_);
126 }
127 12 filename_.clear();
128 12 data_ = NULL;
129 12 size_ = 0;
130 12 fd_ = -1;
131 12 }
132
133 730 bool AnonyDramShmFile::Initialize(const json& config) {
134
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 Clear();
135
136
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 const std::string filename = ConfigFilename(config);
137
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 const int64 size = ConfigSize(config);
138
139 730 data_ = reinterpret_cast<char*>(mmap(
140 nullptr,
141 size,
142 PROT_READ | PROT_WRITE,
143 MAP_PRIVATE | MAP_ANONYMOUS,
144 -1,
145 0));
146
2/10
✓ Branch 3 taken 730 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 730 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
730 CHECK_NE(data_, MAP_FAILED) << "anonymous DRAM mmap failed";
147
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 filename_ = filename;
148 730 size_ = size;
149
2/4
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 730 times.
✗ Branch 5 not taken.
1460 LOG(INFO) << "ShmFile, anonymous DRAM mmap, filename:" << filename
150
4/8
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 730 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 730 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 730 times.
✗ Branch 11 not taken.
730 << ", size:" << size;
151 730 return true;
152 730 }
153
154 1460 void AnonyDramShmFile::Clear() {
155
2/2
✓ Branch 0 taken 730 times.
✓ Branch 1 taken 730 times.
1460 if (data_ != NULL) {
156
5/10
✓ Branch 2 taken 730 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 730 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 730 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 730 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 730 times.
✗ Branch 15 not taken.
730 LOG(INFO) << "ummap anonymous DRAM: " << filename_ << ", size: " << size_;
157 730 munmap(data_, size_);
158 }
159 1460 filename_.clear();
160 1460 data_ = NULL;
161 1460 size_ = 0;
162 1460 }
163
164 bool DevDaxShmFile::Initialize(const json& config) {
165 Clear();
166
167 const std::string filename = ConfigFilename(config);
168 const int64 size = ConfigSize(config);
169
170 {
171 static std::mutex m;
172 std::lock_guard<std::mutex> _(m);
173 data_ =
174 (char*)PMMmapRegisterCenter::GetInstance()->Register(filename, size);
175 filename_ = filename;
176 }
177
178 std::error_code ec;
179 if (!fs::exists(filename, ec)) {
180 fs::create_directories(fs::path(filename).parent_path(), ec);
181 LOG(INFO) << "Create ShmFile: " << filename << ", size: " << size;
182 std::ofstream output(filename);
183 output.write("a", 1);
184 output.close();
185 }
186 size_ = size;
187 return true;
188 }
189
190 void DevDaxShmFile::Clear() {
191 filename_.clear();
192 data_ = NULL;
193 size_ = 0;
194 }
195
196 FACTORY_REGISTER(ShmFile, FS_DAX, FsDaxShmFile, const json&);
197 FACTORY_REGISTER(ShmFile, ANONY_DRAM, AnonyDramShmFile, const json&);
198 FACTORY_REGISTER(ShmFile, DEV_DAX, DevDaxShmFile, const json&);
199
200 } // namespace base
201