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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 #endif | 155 #endif |
156 | 156 |
157 return true; | 157 return true; |
158 } | 158 } |
159 | 159 |
160 DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( | 160 DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock( |
161 size_t offset, size_t length) { | 161 size_t offset, size_t length) { |
162 DCHECK_EQ(AlignToPageSize(offset), offset); | 162 DCHECK_EQ(AlignToPageSize(offset), offset); |
163 DCHECK_EQ(AlignToPageSize(length), length); | 163 DCHECK_EQ(AlignToPageSize(length), length); |
164 | 164 |
165 // Calls to this function must synchronized properly. | 165 // Calls to this function must be synchronized properly. |
166 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 166 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
167 | 167 |
168 // Return false when instance has been purged or not initialized properly by | |
169 // checking if |last_known_usage_| is NULL. | |
170 if (last_known_usage_.is_null()) | |
171 return FAILED; | |
172 | |
173 DCHECK(shared_memory_.memory()); | 168 DCHECK(shared_memory_.memory()); |
174 | 169 |
175 // We need to successfully acquire the platform independent lock before | 170 // We need to successfully acquire the platform independent lock before |
176 // individual pages can be locked. | 171 // individual pages can be locked. |
177 if (!locked_page_count_) { | 172 if (!locked_page_count_) { |
| 173 // Return false when instance has been purged or not initialized properly |
| 174 // by checking if |last_known_usage_| is NULL. |
| 175 if (last_known_usage_.is_null()) |
| 176 return FAILED; |
| 177 |
178 SharedState old_state(SharedState::UNLOCKED, last_known_usage_); | 178 SharedState old_state(SharedState::UNLOCKED, last_known_usage_); |
179 SharedState new_state(SharedState::LOCKED, Time()); | 179 SharedState new_state(SharedState::LOCKED, Time()); |
180 SharedState result(subtle::Acquire_CompareAndSwap( | 180 SharedState result(subtle::Acquire_CompareAndSwap( |
181 &SharedStateFromSharedMemory(shared_memory_)->value.i, | 181 &SharedStateFromSharedMemory(shared_memory_)->value.i, |
182 old_state.value.i, | 182 old_state.value.i, |
183 new_state.value.i)); | 183 new_state.value.i)); |
184 if (result.value.u != old_state.value.u) { | 184 if (result.value.u != old_state.value.u) { |
185 // Update |last_known_usage_| in case the above CAS failed because of | 185 // Update |last_known_usage_| in case the above CAS failed because of |
186 // an incorrect timestamp. | 186 // an incorrect timestamp. |
187 last_known_usage_ = result.GetTimestamp(); | 187 last_known_usage_ = result.GetTimestamp(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 } | 219 } |
220 #endif | 220 #endif |
221 | 221 |
222 return SUCCESS; | 222 return SUCCESS; |
223 } | 223 } |
224 | 224 |
225 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { | 225 void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { |
226 DCHECK_EQ(AlignToPageSize(offset), offset); | 226 DCHECK_EQ(AlignToPageSize(offset), offset); |
227 DCHECK_EQ(AlignToPageSize(length), length); | 227 DCHECK_EQ(AlignToPageSize(length), length); |
228 | 228 |
229 // Calls to this function must synchronized properly. | 229 // Calls to this function must be synchronized properly. |
230 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 230 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
231 | 231 |
232 // Zero for length means "everything onward". | 232 // Zero for length means "everything onward". |
233 if (!length) | 233 if (!length) |
234 length = AlignToPageSize(mapped_size_) - offset; | 234 length = AlignToPageSize(mapped_size_) - offset; |
235 | 235 |
236 DCHECK(shared_memory_.memory()); | 236 DCHECK(shared_memory_.memory()); |
237 | 237 |
238 #if defined(OS_ANDROID) | 238 #if defined(OS_ANDROID) |
239 SharedMemoryHandle handle = shared_memory_.handle(); | 239 SharedMemoryHandle handle = shared_memory_.handle(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 287 |
288 last_known_usage_ = current_time; | 288 last_known_usage_ = current_time; |
289 } | 289 } |
290 | 290 |
291 void* DiscardableSharedMemory::memory() const { | 291 void* DiscardableSharedMemory::memory() const { |
292 return reinterpret_cast<uint8*>(shared_memory_.memory()) + | 292 return reinterpret_cast<uint8*>(shared_memory_.memory()) + |
293 AlignToPageSize(sizeof(SharedState)); | 293 AlignToPageSize(sizeof(SharedState)); |
294 } | 294 } |
295 | 295 |
296 bool DiscardableSharedMemory::Purge(Time current_time) { | 296 bool DiscardableSharedMemory::Purge(Time current_time) { |
297 // Calls to this function must synchronized properly. | 297 // Calls to this function must be synchronized properly. |
298 DFAKE_SCOPED_LOCK(thread_collision_warner_); | 298 DFAKE_SCOPED_LOCK(thread_collision_warner_); |
299 | 299 |
300 // Early out if not mapped. This can happen if the segment was previously | 300 // Early out if not mapped. This can happen if the segment was previously |
301 // unmapped using a call to Close(). | 301 // unmapped using a call to Close(). |
302 if (!shared_memory_.memory()) | 302 if (!shared_memory_.memory()) |
303 return true; | 303 return true; |
304 | 304 |
305 SharedState old_state(SharedState::UNLOCKED, last_known_usage_); | 305 SharedState old_state(SharedState::UNLOCKED, last_known_usage_); |
306 SharedState new_state(SharedState::UNLOCKED, Time()); | 306 SharedState new_state(SharedState::UNLOCKED, Time()); |
307 SharedState result(subtle::Acquire_CompareAndSwap( | 307 SharedState result(subtle::Acquire_CompareAndSwap( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 shared_memory_.Unmap(); | 355 shared_memory_.Unmap(); |
356 shared_memory_.Close(); | 356 shared_memory_.Close(); |
357 mapped_size_ = 0; | 357 mapped_size_ = 0; |
358 } | 358 } |
359 | 359 |
360 Time DiscardableSharedMemory::Now() const { | 360 Time DiscardableSharedMemory::Now() const { |
361 return Time::Now(); | 361 return Time::Now(); |
362 } | 362 } |
363 | 363 |
364 } // namespace base | 364 } // namespace base |
OLD | NEW |