persistent_system_profile.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_METRICS_PERSISTENT_SYSTEM_PROFILE_H_
  5. #define COMPONENTS_METRICS_PERSISTENT_SYSTEM_PROFILE_H_
  6. #include <vector>
  7. #include "base/strings/string_piece.h"
  8. #include "base/threading/thread_checker.h"
  9. #include "third_party/metrics_proto/system_profile.pb.h"
  10. namespace base {
  11. template <typename T>
  12. struct DefaultSingletonTraits;
  13. class PersistentMemoryAllocator;
  14. } // namespace base
  15. namespace metrics {
  16. // Manages a copy of the system profile inside persistent memory segments.
  17. class PersistentSystemProfile {
  18. public:
  19. PersistentSystemProfile();
  20. PersistentSystemProfile(const PersistentSystemProfile&) = delete;
  21. PersistentSystemProfile& operator=(const PersistentSystemProfile&) = delete;
  22. ~PersistentSystemProfile();
  23. // This object can store records in multiple memory allocators.
  24. void RegisterPersistentAllocator(
  25. base::PersistentMemoryAllocator* memory_allocator);
  26. void DeregisterPersistentAllocator(
  27. base::PersistentMemoryAllocator* memory_allocator);
  28. // Stores a complete system profile. Use the version taking the serialized
  29. // version if available to avoid multiple serialization actions. The
  30. // |complete| flag indicates that this profile contains all known information
  31. // and can replace whatever exists. If the flag is false, the existing profile
  32. // will only be replaced if it is also incomplete. This method should not be
  33. // called too many times with incomplete profiles before setting a complete
  34. // profile to prevent impact on startup.
  35. void SetSystemProfile(const std::string& serialized_profile, bool complete);
  36. void SetSystemProfile(const SystemProfileProto& profile, bool complete);
  37. // Records the existence of a field trial.
  38. void AddFieldTrial(base::StringPiece trial, base::StringPiece group);
  39. // Tests if a persistent memory allocator contains an system profile.
  40. static bool HasSystemProfile(
  41. const base::PersistentMemoryAllocator& memory_allocator);
  42. // Retrieves the system profile from a persistent memory allocator. Returns
  43. // true if a profile was successfully retrieved. If null is passed for the
  44. // |system_profile|, only a basic check for the existence of one will be
  45. // done.
  46. static bool GetSystemProfile(
  47. const base::PersistentMemoryAllocator& memory_allocator,
  48. SystemProfileProto* system_profile);
  49. private:
  50. friend class PersistentSystemProfileTest;
  51. // Defines record types that can be stored inside our local Allocators.
  52. enum RecordType : uint8_t {
  53. kUnusedSpace = 0, // The default value for empty memory.
  54. kSystemProfileProto,
  55. kFieldTrialInfo,
  56. };
  57. // A class for managing record allocations inside a persistent memory segment.
  58. class RecordAllocator {
  59. public:
  60. // Construct an allocator for writing.
  61. RecordAllocator(base::PersistentMemoryAllocator* memory_allocator,
  62. size_t min_size);
  63. // Construct an allocator for reading.
  64. RecordAllocator(const base::PersistentMemoryAllocator* memory_allocator);
  65. // These methods manage writing records to the allocator. Do not mix these
  66. // with "read" calls; it's one or the other.
  67. void Reset();
  68. bool Write(RecordType type, base::StringPiece record);
  69. // Read a record from the allocator. Do not mix this with "write" calls;
  70. // it's one or the other.
  71. bool HasMoreData() const;
  72. bool Read(RecordType* type, std::string* record) const;
  73. base::PersistentMemoryAllocator* allocator() { return allocator_; }
  74. bool has_complete_profile() { return has_complete_profile_; }
  75. void set_complete_profile() { has_complete_profile_ = true; }
  76. private:
  77. // Advance to the next record segment in the memory allocator.
  78. bool NextSegment() const;
  79. // Advance to the next record segment, creating a new one if necessary with
  80. // sufficent |min_size| space.
  81. bool AddSegment(size_t min_size);
  82. // Writes data to the current position, updating the passed values past
  83. // the amount written. Returns false in case of an error.
  84. bool WriteData(RecordType type, const char** data, size_t* data_size);
  85. // Reads data from the current position, updating the passed string
  86. // in-place. |type| must be initialized to kUnusedSpace and |record| must
  87. // be an empty string before the first call but unchanged thereafter.
  88. // Returns true when record is complete.
  89. bool ReadData(RecordType* type, std::string* record) const;
  90. // This never changes but can't be "const" because vector calls operator=().
  91. base::PersistentMemoryAllocator* allocator_; // Storage location.
  92. // Indicates if a complete profile has been stored.
  93. bool has_complete_profile_;
  94. // These change even though the underlying data may be "const".
  95. mutable uint32_t alloc_reference_; // Last storage block.
  96. mutable size_t alloc_size_; // Size of the block.
  97. mutable size_t end_offset_; // End of data in block.
  98. // Copy and assign are allowed for easy use with STL containers.
  99. };
  100. // Write a record to all registered allocators.
  101. void WriteToAll(RecordType type, base::StringPiece record);
  102. // Merges all "update" records into a system profile.
  103. static void MergeUpdateRecords(
  104. const base::PersistentMemoryAllocator& memory_allocator,
  105. SystemProfileProto* system_profile);
  106. // The list of registered persistent allocators, described by RecordAllocator
  107. // instances.
  108. std::vector<RecordAllocator> allocators_;
  109. // Indicates if a complete profile has been stored to all allocators.
  110. bool all_have_complete_profile_ = false;
  111. THREAD_CHECKER(thread_checker_);
  112. };
  113. // A singleton instance of the above.
  114. class GlobalPersistentSystemProfile : public PersistentSystemProfile {
  115. public:
  116. static GlobalPersistentSystemProfile* GetInstance();
  117. GlobalPersistentSystemProfile(const GlobalPersistentSystemProfile&) = delete;
  118. GlobalPersistentSystemProfile& operator=(
  119. const GlobalPersistentSystemProfile&) = delete;
  120. private:
  121. friend struct base::DefaultSingletonTraits<GlobalPersistentSystemProfile>;
  122. GlobalPersistentSystemProfile() {}
  123. ~GlobalPersistentSystemProfile() {}
  124. };
  125. } // namespace metrics
  126. #endif // COMPONENTS_METRICS_PERSISTENT_SYSTEM_PROFILE_H_