Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: components/metrics/persistent_system_profile.cc

Issue 2938013002: Persist core system profile during startup. (Closed)
Patch Set: added test Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "components/metrics/persistent_system_profile.h" 5 #include "components/metrics/persistent_system_profile.h"
6 6
7 #include "base/atomicops.h" 7 #include "base/atomicops.h"
8 #include "base/memory/singleton.h" 8 #include "base/memory/singleton.h"
9 #include "base/metrics/persistent_memory_allocator.h" 9 #include "base/metrics/persistent_memory_allocator.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 28 matching lines...) Expand all
39 return (data_amount + sizeof(RecordHeader) + sizeof(RecordHeader) - 1) & 39 return (data_amount + sizeof(RecordHeader) + sizeof(RecordHeader) - 1) &
40 ~(sizeof(RecordHeader) - 1); 40 ~(sizeof(RecordHeader) - 1);
41 } 41 }
42 42
43 } // namespace 43 } // namespace
44 44
45 PersistentSystemProfile::RecordAllocator::RecordAllocator( 45 PersistentSystemProfile::RecordAllocator::RecordAllocator(
46 base::PersistentMemoryAllocator* memory_allocator, 46 base::PersistentMemoryAllocator* memory_allocator,
47 size_t min_size) 47 size_t min_size)
48 : allocator_(memory_allocator), 48 : allocator_(memory_allocator),
49 has_complete_profile_(false),
49 alloc_reference_(0), 50 alloc_reference_(0),
50 alloc_size_(0), 51 alloc_size_(0),
51 end_offset_(0) { 52 end_offset_(0) {
52 AddSegment(min_size); 53 AddSegment(min_size);
53 } 54 }
54 55
55 PersistentSystemProfile::RecordAllocator::RecordAllocator( 56 PersistentSystemProfile::RecordAllocator::RecordAllocator(
56 const base::PersistentMemoryAllocator* memory_allocator) 57 const base::PersistentMemoryAllocator* memory_allocator)
57 : allocator_( 58 : allocator_(
58 const_cast<base::PersistentMemoryAllocator*>(memory_allocator)), 59 const_cast<base::PersistentMemoryAllocator*>(memory_allocator)),
59 alloc_reference_(0), 60 alloc_reference_(0),
60 alloc_size_(0), 61 alloc_size_(0),
61 end_offset_(0) {} 62 end_offset_(0) {}
62 63
63 void PersistentSystemProfile::RecordAllocator::Reset() { 64 void PersistentSystemProfile::RecordAllocator::Reset() {
64 // Clear the first word of all blocks so they're known to be "empty". 65 // Clear the first word of all blocks so they're known to be "empty".
65 alloc_reference_ = 0; 66 alloc_reference_ = 0;
66 while (NextSegment()) { 67 while (NextSegment()) {
67 // Get the block as a char* and cast it. It can't be fetched directly as 68 // Get the block as a char* and cast it. It can't be fetched directly as
68 // an array of RecordHeader because that's not a fundamental type and only 69 // an array of RecordHeader because that's not a fundamental type and only
69 // arrays of fundamental types are allowed. 70 // arrays of fundamental types are allowed.
70 RecordHeader* header = 71 RecordHeader* header =
71 reinterpret_cast<RecordHeader*>(allocator_->GetAsArray<char>( 72 reinterpret_cast<RecordHeader*>(allocator_->GetAsArray<char>(
72 alloc_reference_, kTypeIdSystemProfile, sizeof(RecordHeader))); 73 alloc_reference_, kTypeIdSystemProfile, sizeof(RecordHeader)));
73 DCHECK(header); 74 DCHECK(header);
74 base::subtle::NoBarrier_Store(&header->as_atomic, 0); 75 base::subtle::NoBarrier_Store(&header->as_atomic, 0);
75 } 76 }
76 77
77 // Reset member variables. 78 // Reset member variables.
79 has_complete_profile_ = false;
78 alloc_reference_ = 0; 80 alloc_reference_ = 0;
79 alloc_size_ = 0; 81 alloc_size_ = 0;
80 end_offset_ = 0; 82 end_offset_ = 0;
81 } 83 }
82 84
83 bool PersistentSystemProfile::RecordAllocator::Write( 85 bool PersistentSystemProfile::RecordAllocator::Write(
84 RecordType type, 86 RecordType type,
85 const std::string& record) { 87 const std::string& record) {
86 const char* data = record.data(); 88 const char* data = record.data();
87 size_t remaining_size = record.size(); 89 size_t remaining_size = record.size();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 PersistentSystemProfile::~PersistentSystemProfile() {} 259 PersistentSystemProfile::~PersistentSystemProfile() {}
258 260
259 void PersistentSystemProfile::RegisterPersistentAllocator( 261 void PersistentSystemProfile::RegisterPersistentAllocator(
260 base::PersistentMemoryAllocator* memory_allocator) { 262 base::PersistentMemoryAllocator* memory_allocator) {
261 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 263 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
262 264
263 // Create and store the allocator. A |min_size| of "1" ensures that a memory 265 // Create and store the allocator. A |min_size| of "1" ensures that a memory
264 // block is reserved now. 266 // block is reserved now.
265 RecordAllocator allocator(memory_allocator, 1); 267 RecordAllocator allocator(memory_allocator, 1);
266 allocators_.push_back(std::move(allocator)); 268 allocators_.push_back(std::move(allocator));
269 all_have_complete_profile_ = false;
267 } 270 }
268 271
269 void PersistentSystemProfile::DeregisterPersistentAllocator( 272 void PersistentSystemProfile::DeregisterPersistentAllocator(
270 base::PersistentMemoryAllocator* memory_allocator) { 273 base::PersistentMemoryAllocator* memory_allocator) {
271 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 274 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
272 275
273 // This would be more efficient with a std::map but it's not expected that 276 // This would be more efficient with a std::map but it's not expected that
274 // allocators will get deregistered with any frequency, if at all. 277 // allocators will get deregistered with any frequency, if at all.
275 base::EraseIf(allocators_, [=](RecordAllocator& records) { 278 base::EraseIf(allocators_, [=](RecordAllocator& records) {
276 return records.allocator() == memory_allocator; 279 return records.allocator() == memory_allocator;
277 }); 280 });
278 } 281 }
279 282
280 void PersistentSystemProfile::SetSystemProfile( 283 void PersistentSystemProfile::SetSystemProfile(
281 const std::string& serialized_profile) { 284 const std::string& serialized_profile,
285 bool complete) {
282 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 286 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
283 287
284 if (allocators_.empty() || serialized_profile.empty()) 288 if (allocators_.empty() || serialized_profile.empty())
285 return; 289 return;
286 290
287 for (auto& allocator : allocators_) { 291 for (auto& allocator : allocators_) {
292 // Don't overwrite a complete profile with an incomplete one.
293 if (!complete && allocator.has_complete_profile())
294 continue;
288 // A full system profile always starts fresh. 295 // A full system profile always starts fresh.
289 allocator.Reset(); 296 allocator.Reset();
290 // Write out the serialized profile. 297 // Write out the serialized profile.
291 allocator.Write(kSystemProfileProto, serialized_profile); 298 allocator.Write(kSystemProfileProto, serialized_profile);
299 // Indicate if this is a complete profile.
300 if (complete)
301 allocator.set_complete_profile();
292 } 302 }
303
304 if (complete)
305 all_have_complete_profile_ = true;
293 } 306 }
294 307
295 void PersistentSystemProfile::SetSystemProfile( 308 void PersistentSystemProfile::SetSystemProfile(
296 const SystemProfileProto& profile) { 309 const SystemProfileProto& profile,
310 bool complete) {
311 // Avoid serialization if passed profile is not complete and all allocators
312 // already have complete ones.
313 if (!complete && all_have_complete_profile_)
314 return;
315
297 std::string serialized_profile; 316 std::string serialized_profile;
298 if (!profile.SerializeToString(&serialized_profile)) 317 if (!profile.SerializeToString(&serialized_profile))
299 return; 318 return;
300 SetSystemProfile(serialized_profile); 319 SetSystemProfile(serialized_profile, complete);
301 } 320 }
302 321
303 // static 322 // static
304 bool PersistentSystemProfile::HasSystemProfile( 323 bool PersistentSystemProfile::HasSystemProfile(
305 const base::PersistentMemoryAllocator& memory_allocator) { 324 const base::PersistentMemoryAllocator& memory_allocator) {
306 const RecordAllocator records(&memory_allocator); 325 const RecordAllocator records(&memory_allocator);
307 return records.HasMoreData(); 326 return records.HasMoreData();
308 } 327 }
309 328
310 // static 329 // static
(...skipping 12 matching lines...) Expand all
323 return system_profile->ParseFromString(record); 342 return system_profile->ParseFromString(record);
324 } 343 }
325 344
326 GlobalPersistentSystemProfile* GlobalPersistentSystemProfile::GetInstance() { 345 GlobalPersistentSystemProfile* GlobalPersistentSystemProfile::GetInstance() {
327 return base::Singleton< 346 return base::Singleton<
328 GlobalPersistentSystemProfile, 347 GlobalPersistentSystemProfile,
329 base::LeakySingletonTraits<GlobalPersistentSystemProfile>>::get(); 348 base::LeakySingletonTraits<GlobalPersistentSystemProfile>>::get();
330 } 349 }
331 350
332 } // namespace metrics 351 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/persistent_system_profile.h ('k') | components/metrics/persistent_system_profile_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698