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 |