Chromium Code Reviews| 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 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 if (result.value.u != old_state.value.u) { | 195 if (result.value.u != old_state.value.u) { |
| 196 // Update |last_known_usage_| in case the above CAS failed because of | 196 // Update |last_known_usage_| in case the above CAS failed because of |
| 197 // an incorrect timestamp. | 197 // an incorrect timestamp. |
| 198 last_known_usage_ = result.GetTimestamp(); | 198 last_known_usage_ = result.GetTimestamp(); |
| 199 return FAILED; | 199 return FAILED; |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 | 202 |
| 203 // Zero for length means "everything onward". | 203 // Zero for length means "everything onward". |
| 204 if (!length) | 204 if (!length) |
| 205 length = AlignToPageSize(mapped_size_) - offset; | 205 length = AlignToPageSize(mapped_size_) - offset; |
|
penny
2016/02/28 18:44:00
The only time length can be 0 is if the caller pas
reveman
2016/02/28 20:36:16
We've had DCHECKs for this at a higher level but t
| |
| 206 | 206 |
| 207 size_t start = offset / base::GetPageSize(); | 207 size_t start = offset / base::GetPageSize(); |
| 208 size_t end = start + length / base::GetPageSize(); | 208 size_t end = start + length / base::GetPageSize(); |
| 209 DCHECK_LE(start, end); | 209 DCHECK_LE(start, end); |
| 210 DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); | 210 DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize()); |
| 211 | 211 |
| 212 // Add pages to |locked_page_count_|. | 212 // Add pages to |locked_page_count_|. |
| 213 // Note: Locking a page that is already locked is an error. | 213 // Note: Locking a page that is already locked is an error. |
| 214 locked_page_count_ += end - start; | 214 locked_page_count_ += end - start; |
| 215 #if DCHECK_IS_ON() | 215 #if DCHECK_IS_ON() |
| 216 // Detect incorrect usage by keeping track of exactly what pages are locked. | 216 // Detect incorrect usage by keeping track of exactly what pages are locked. |
| 217 for (auto page = start; page < end; ++page) { | 217 for (auto page = start; page < end; ++page) { |
| 218 auto result = locked_pages_.insert(page); | 218 auto result = locked_pages_.insert(page); |
| 219 DCHECK(result.second); | 219 DCHECK(result.second); |
| 220 } | 220 } |
| 221 DCHECK_EQ(locked_pages_.size(), locked_page_count_); | 221 DCHECK_EQ(locked_pages_.size(), locked_page_count_); |
| 222 #endif | 222 #endif |
| 223 | 223 |
| 224 // Pin pages if supported. | 224 // Pin pages if supported. |
| 225 #if defined(OS_ANDROID) | 225 #if defined(OS_ANDROID) |
| 226 SharedMemoryHandle handle = shared_memory_.handle(); | 226 SharedMemoryHandle handle = shared_memory_.handle(); |
| 227 if (SharedMemory::IsHandleValid(handle)) { | 227 if (SharedMemory::IsHandleValid(handle)) { |
| 228 if (ashmem_pin_region( | 228 if (ashmem_pin_region( |
| 229 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { | 229 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { |
| 230 return PURGED; | 230 return PURGED; |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 #elif defined(OS_WIN) | 233 #elif defined(OS_WIN) |
| 234 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 234 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| 235 if (!VirtualAlloc(reinterpret_cast<char*>(shared_memory_.memory()) + | 235 if (length && |
|
penny
2016/02/28 21:49:10
if (!length)
return PURGED;
Unlock is fine as i
reveman
2016/02/29 16:36:59
Done.
Note: memory segments are initially locked
| |
| 236 !VirtualAlloc(reinterpret_cast<char*>(shared_memory_.memory()) + | |
| 236 AlignToPageSize(sizeof(SharedState)) + offset, | 237 AlignToPageSize(sizeof(SharedState)) + offset, |
| 237 length, MEM_RESET_UNDO, PAGE_READWRITE)) { | 238 length, MEM_RESET_UNDO, PAGE_READWRITE)) { |
| 238 return PURGED; | 239 return PURGED; |
| 239 } | 240 } |
| 240 } | 241 } |
| 241 #endif | 242 #endif |
| 242 | 243 |
| 243 return SUCCESS; | 244 return SUCCESS; |
| 244 } | 245 } |
| 245 | 246 |
| 246 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { | 247 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { |
| 247 DCHECK_EQ(AlignToPageSize(offset), offset); | 248 DCHECK_EQ(AlignToPageSize(offset), offset); |
| 248 DCHECK_EQ(AlignToPageSize(length), length); | 249 DCHECK_EQ(AlignToPageSize(length), length); |
| 249 | 250 |
| 250 // Calls to this function must be synchronized properly. | 251 // Calls to this function must be synchronized properly. |
| 251 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 252 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
| 252 | 253 |
| 253 // Zero for length means "everything onward". | 254 // Zero for length means "everything onward". |
| 254 if (!length) | 255 if (!length) |
| 255 length = AlignToPageSize(mapped_size_) - offset; | 256 length = AlignToPageSize(mapped_size_) - offset; |
|
penny
2016/02/28 18:44:00
Here too.
| |
| 256 | 257 |
| 257 DCHECK(shared_memory_.memory()); | 258 DCHECK(shared_memory_.memory()); |
| 258 | 259 |
| 259 // Unpin pages if supported. | 260 // Unpin pages if supported. |
| 260 #if defined(OS_ANDROID) | 261 #if defined(OS_ANDROID) |
| 261 SharedMemoryHandle handle = shared_memory_.handle(); | 262 SharedMemoryHandle handle = shared_memory_.handle(); |
| 262 if (SharedMemory::IsHandleValid(handle)) { | 263 if (SharedMemory::IsHandleValid(handle)) { |
| 263 if (ashmem_unpin_region( | 264 if (ashmem_unpin_region( |
| 264 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { | 265 handle.fd, AlignToPageSize(sizeof(SharedState)) + offset, length)) { |
| 265 DPLOG(ERROR) << "ashmem_unpin_region() failed"; | 266 DPLOG(ERROR) << "ashmem_unpin_region() failed"; |
| 266 } | 267 } |
| 267 } | 268 } |
| 268 #elif defined(OS_WIN) | 269 #elif defined(OS_WIN) |
| 269 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 270 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| 270 // Note: MEM_RESET is not technically gated on Win8. However, this Unlock | 271 // Note: MEM_RESET is not technically gated on Win8. However, this Unlock |
| 271 // function needs to match the Lock behaviour (MEM_RESET_UNDO) to properly | 272 // function needs to match the Lock behaviour (MEM_RESET_UNDO) to properly |
| 272 // implement memory pinning. It needs to bias towards preserving the | 273 // implement memory pinning. It needs to bias towards preserving the |
| 273 // contents of memory between an Unlock and next Lock. | 274 // contents of memory between an Unlock and next Lock. |
| 274 if (!VirtualAlloc(reinterpret_cast<char*>(shared_memory_.memory()) + | 275 if (length && |
| 276 !VirtualAlloc(reinterpret_cast<char*>(shared_memory_.memory()) + | |
| 275 AlignToPageSize(sizeof(SharedState)) + offset, | 277 AlignToPageSize(sizeof(SharedState)) + offset, |
| 276 length, MEM_RESET, PAGE_READWRITE)) { | 278 length, MEM_RESET, PAGE_READWRITE)) { |
| 277 DPLOG(ERROR) << "VirtualAlloc() MEM_RESET failed in Unlock()"; | 279 DPLOG(ERROR) << "VirtualAlloc() MEM_RESET failed in Unlock()"; |
| 278 } | 280 } |
| 279 } | 281 } |
| 280 #endif | 282 #endif |
| 281 | 283 |
| 282 size_t start = offset / base::GetPageSize(); | 284 size_t start = offset / base::GetPageSize(); |
| 283 size_t end = start + length / base::GetPageSize(); | 285 size_t end = start + length / base::GetPageSize(); |
| 284 DCHECK_LE(start, end); | 286 DCHECK_LE(start, end); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 | 412 |
| 411 void DiscardableSharedMemory::Close() { | 413 void DiscardableSharedMemory::Close() { |
| 412 shared_memory_.Close(); | 414 shared_memory_.Close(); |
| 413 } | 415 } |
| 414 | 416 |
| 415 Time DiscardableSharedMemory::Now() const { | 417 Time DiscardableSharedMemory::Now() const { |
| 416 return Time::Now(); | 418 return Time::Now(); |
| 417 } | 419 } |
| 418 | 420 |
| 419 } // namespace base | 421 } // namespace base |
| OLD | NEW |