| 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 |