// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_METRICS_SHARED_METRICS_BUFFER_H_ #define CC_METRICS_SHARED_METRICS_BUFFER_H_ #include "device/base/synchronization/one_writer_seqlock.h" namespace cc { // The struct written in shared memory to transport metrics across // processes. |data| is protected by the sequence-lock |seq_lock|. // Note: This template copies data between processes. Any class that uses this // template would need security review. template struct SharedMetricsBuffer { device::OneWriterSeqLock seq_lock; T data; static_assert(std::is_trivially_copyable::value, "Metrics shared across processes need to be trivially " "copyable, otherwise it is dangerous to copy it."); bool Read(T& out) const { const uint32_t kMaxRetries = 5; uint32_t retries = 0; base::subtle::Atomic32 version; do { const uint32_t kMaxReadAttempts = 32; version = seq_lock.ReadBegin(kMaxReadAttempts); device::OneWriterSeqLock::AtomicReaderMemcpy(&out, &data, sizeof(T)); } while (seq_lock.ReadRetry(version) && ++retries < kMaxRetries); // Consider the number of retries less than kMaxRetries as success. return retries < kMaxRetries; } void Write(const T& in) { seq_lock.WriteBegin(); device::OneWriterSeqLock::AtomicWriterMemcpy(&data, &in, sizeof(T)); seq_lock.WriteEnd(); } }; } // namespace cc #endif // CC_METRICS_SHARED_METRICS_BUFFER_H_