blob: 8fde9654ee4482f78f9ee0cbcce0574c59197b58 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
#include <unistd.h>
#include <cobalt-client/cpp/types-internal.h>
#include <fbl/atomic.h>
#include <fbl/function.h>
#include <fbl/string.h>
#include <fbl/vector.h>
namespace cobalt_client {
namespace internal {
// Note: Everything on this namespace is internal, no external users should rely
// on the behaviour of any of these classes.
// BaseCounter and RemoteCounter differ in that the first is simply a thin wrapper over
// an atomic while the second provides Cobalt Fidl specific API and holds more metric related
// data for a full fledged metric.
//
// Thin wrapper on top of an atomic, which provides a fixed memory ordering for all calls.
// Calls are inlined to reduce overhead.
class BaseCounter {
public:
using Type = uint64_t;
// All atomic operations use this memory order.
static constexpr fbl::memory_order kMemoryOrder = fbl::memory_order::memory_order_relaxed;
BaseCounter() : counter_(0) {}
BaseCounter(const BaseCounter&) = delete;
BaseCounter(BaseCounter&&);
BaseCounter& operator=(const BaseCounter&) = delete;
BaseCounter& operator=(BaseCounter&&) = delete;
~BaseCounter() = default;
// Increments |counter_| by |val|.
void Increment(Type val = 1) { counter_.fetch_add(val, kMemoryOrder); }
// Returns the current value of|counter_| and resets it to |val|.
Type Exchange(Type val = 0) { return counter_.exchange(val, kMemoryOrder); }
// Returns the current value of |counter_|.
Type Load() const { return counter_.load(kMemoryOrder); }
protected:
fbl::atomic<Type> counter_;
};
// Counter which represents a standalone cobalt metric. Provides API for converting
// to cobalt FIDL types.
//
// This class is moveable and move-assignanle.
// This class is not copy or copy-assignable.
// This class is thread-safe.
class RemoteCounter : public BaseCounter {
public:
// Callback to notify that Flush has been completed, and that the observation buffer is
// writeable again(this is buffer where the counter and its metadata are flushed).
using FlushCompleteFn = fbl::Function<void()>;
// Alias for the specific buffer instantiation.
using EventBuffer = internal::EventBuffer<uint32_t>;
// Function in charge persisting or processing the ObservationValue buffer.
using FlushFn =
fbl::Function<void(uint64_t metric_id, const EventBuffer&, FlushCompleteFn complete)>;
RemoteCounter() = delete;
RemoteCounter(uint64_t metric_id, const fbl::Vector<Metadata>& metadata);
RemoteCounter(const RemoteCounter&) = delete;
RemoteCounter(RemoteCounter&&);
RemoteCounter& operator=(const RemoteCounter&) = delete;
RemoteCounter& operator=(RemoteCounter&&) = delete;
~RemoteCounter() = default;
// Returns true if the contests were flushed.
bool Flush(const FlushFn& flush_handler);
// Returns the metric Id associated with this counter.
uint64_t metric_id() const { return metric_id_; }
private:
// The buffer containing the data to be flushed.
EventBuffer buffer_;
// Unique-Id representing this metric in the backend.
uint64_t metric_id_;
};
} // namespace internal
} // namespace cobalt_client