OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/discardable_shared_memory.h" | 5 #include "base/memory/discardable_shared_memory.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #include <unistd.h> | 8 #include <unistd.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize(); | 151 locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize(); |
152 #if DCHECK_IS_ON() | 152 #if DCHECK_IS_ON() |
153 for (size_t page = 0; page < locked_page_count_; ++page) | 153 for (size_t page = 0; page < locked_page_count_; ++page) |
154 locked_pages_.insert(page); | 154 locked_pages_.insert(page); |
155 #endif | 155 #endif |
156 | 156 |
157 return true; | 157 return true; |
158 } | 158 } |
159 | 159 |
| 160 bool DiscardableSharedMemory::Unmap() { |
| 161 if (!shared_memory_.Unmap()) |
| 162 return false; |
| 163 |
| 164 mapped_size_ = 0; |
| 165 return true; |
| 166 } |
| 167 |
160 DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( | 168 DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( |
161 size_t offset, size_t length) { | 169 size_t offset, size_t length) { |
162 DCHECK_EQ(AlignToPageSize(offset), offset); | 170 DCHECK_EQ(AlignToPageSize(offset), offset); |
163 DCHECK_EQ(AlignToPageSize(length), length); | 171 DCHECK_EQ(AlignToPageSize(length), length); |
164 | 172 |
165 // Calls to this function must be synchronized properly. | 173 // Calls to this function must be synchronized properly. |
166 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 174 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
167 | 175 |
168 DCHECK(shared_memory_.memory()); | 176 DCHECK(shared_memory_.memory()); |
169 | 177 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 // Detect incorrect usage by keeping track of exactly what pages are locked. | 213 // Detect incorrect usage by keeping track of exactly what pages are locked. |
206 for (auto page = start; page < end; ++page) { | 214 for (auto page = start; page < end; ++page) { |
207 auto result = locked_pages_.insert(page); | 215 auto result = locked_pages_.insert(page); |
208 DCHECK(result.second); | 216 DCHECK(result.second); |
209 } | 217 } |
210 DCHECK_EQ(locked_pages_.size(), locked_page_count_); | 218 DCHECK_EQ(locked_pages_.size(), locked_page_count_); |
211 #endif | 219 #endif |
212 | 220 |
213 #if defined(OS_ANDROID) | 221 #if defined(OS_ANDROID) |
214 SharedMemoryHandle handle = shared_memory_.handle(); | 222 SharedMemoryHandle handle = shared_memory_.handle(); |
215 DCHECK(SharedMemory::IsHandleValid(handle)); | 223 if (SharedMemory::IsHandleValid(handle)) { |
216 if (ashmem_pin_region( | 224 if (ashmem_pin_region( |
217 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { | 225 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { |
218 return PURGED; | 226 return PURGED; |
| 227 } |
219 } | 228 } |
220 #endif | 229 #endif |
221 | 230 |
222 return SUCCESS; | 231 return SUCCESS; |
223 } | 232 } |
224 | 233 |
225 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { | 234 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { |
226 DCHECK_EQ(AlignToPageSize(offset), offset); | 235 DCHECK_EQ(AlignToPageSize(offset), offset); |
227 DCHECK_EQ(AlignToPageSize(length), length); | 236 DCHECK_EQ(AlignToPageSize(length), length); |
228 | 237 |
229 // Calls to this function must be synchronized properly. | 238 // Calls to this function must be synchronized properly. |
230 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 239 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
231 | 240 |
232 // Zero for length means "everything onward". | 241 // Zero for length means "everything onward". |
233 if (!length) | 242 if (!length) |
234 length = AlignToPageSize(mapped_size_) - offset; | 243 length = AlignToPageSize(mapped_size_) - offset; |
235 | 244 |
236 DCHECK(shared_memory_.memory()); | 245 DCHECK(shared_memory_.memory()); |
237 | 246 |
238 #if defined(OS_ANDROID) | 247 #if defined(OS_ANDROID) |
239 SharedMemoryHandle handle = shared_memory_.handle(); | 248 SharedMemoryHandle handle = shared_memory_.handle(); |
240 DCHECK(SharedMemory::IsHandleValid(handle)); | 249 if (SharedMemory::IsHandleValid(handle)) { |
241 if (ashmem_unpin_region( | 250 if (ashmem_unpin_region( |
242 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { | 251 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { |
243 DPLOG(ERROR) << "ashmem_unpin_region() failed"; | 252 DPLOG(ERROR) << "ashmem_unpin_region() failed"; |
| 253 } |
244 } | 254 } |
245 #endif | 255 #endif |
246 | 256 |
247 size_t start = offset / base::GetPageSize(); | 257 size_t start = offset / base::GetPageSize(); |
248 size_t end = start + length / base::GetPageSize(); | 258 size_t end = start + length / base::GetPageSize(); |
249 DCHECK_LT(start, end); | 259 DCHECK_LT(start, end); |
250 DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); | 260 DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); |
251 | 261 |
252 // Remove pages from |locked_page_count_|. | 262 // Remove pages from |locked_page_count_|. |
253 // Note: Unlocking a page that is not locked is an error. | 263 // Note: Unlocking a page that is not locked is an error. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 DCHECK(shared_memory_.memory()); | 339 DCHECK(shared_memory_.memory()); |
330 | 340 |
331 SharedState result(subtle::NoBarrier_Load( | 341 SharedState result(subtle::NoBarrier_Load( |
332 &SharedStateFromSharedMemory(shared_memory_)->value.i)); | 342 &SharedStateFromSharedMemory(shared_memory_)->value.i)); |
333 | 343 |
334 return result.GetLockState() == SharedState::LOCKED || | 344 return result.GetLockState() == SharedState::LOCKED || |
335 !result.GetTimestamp().is_null(); | 345 !result.GetTimestamp().is_null(); |
336 } | 346 } |
337 | 347 |
338 void DiscardableSharedMemory::Close() { | 348 void DiscardableSharedMemory::Close() { |
339 shared_memory_.Unmap(); | |
340 shared_memory_.Close(); | 349 shared_memory_.Close(); |
341 mapped_size_ = 0; | |
342 } | 350 } |
343 | 351 |
344 #if defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) | 352 #if defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) |
345 void DiscardableSharedMemory::Shrink() { | 353 void DiscardableSharedMemory::Shrink() { |
346 #if defined(OS_POSIX) | 354 #if defined(OS_POSIX) |
347 SharedMemoryHandle handle = shared_memory_.handle(); | 355 SharedMemoryHandle handle = shared_memory_.handle(); |
348 if (!SharedMemory::IsHandleValid(handle)) | 356 if (!SharedMemory::IsHandleValid(handle)) |
349 return; | 357 return; |
350 | 358 |
351 // Truncate shared memory to size of SharedState. | 359 // Truncate shared memory to size of SharedState. |
352 if (HANDLE_EINTR( | 360 if (HANDLE_EINTR( |
353 ftruncate(handle.fd, AlignToPageSize(sizeof(SharedState)))) != 0) { | 361 ftruncate(handle.fd, AlignToPageSize(sizeof(SharedState)))) != 0) { |
354 DPLOG(ERROR) << "ftruncate() failed"; | 362 DPLOG(ERROR) << "ftruncate() failed"; |
355 return; | 363 return; |
356 } | 364 } |
357 mapped_size_ = 0; | 365 mapped_size_ = 0; |
358 #else | 366 #else |
359 NOTIMPLEMENTED(); | 367 NOTIMPLEMENTED(); |
360 #endif | 368 #endif |
361 } | 369 } |
362 #endif | 370 #endif |
363 | 371 |
364 Time DiscardableSharedMemory::Now() const { | 372 Time DiscardableSharedMemory::Now() const { |
365 return Time::Now(); | 373 return Time::Now(); |
366 } | 374 } |
367 | 375 |
368 } // namespace base | 376 } // namespace base |
OLD | NEW |