// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_INCLUDE_LIB_KTRACE_H_
#define ZIRCON_KERNEL_INCLUDE_LIB_KTRACE_H_

#include <lib/ktrace/string_ref.h>
#include <lib/zircon-internal/ktrace.h>
#include <platform.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#include <ktl/atomic.h>

// Specifies whether the trace applies to the current thread or cpu.
enum class TraceContext {
  Thread,
  Cpu,
  // TODO(eieio): Support process?
};

// Argument type that specifies whether a trace function is enabled or disabled.
template <bool enabled>
struct TraceEnabled {};

// Type that specifies whether tracing is enabled or disabled for the local
// compilation unit.
template <bool enabled>
constexpr auto LocalTrace = TraceEnabled<enabled>{};

// Constants that specify unconditional enabled or disabled tracing.
constexpr auto TraceAlways = TraceEnabled<true>{};
constexpr auto TraceNever = TraceEnabled<false>{};

static inline uint64_t ktrace_timestamp() { return current_ticks(); }

// Indicate that the current time should be recorded when writing a trace record.
//
// Used for ktrace calls which accept a custom timestamp as a parameter.
inline constexpr uint64_t kRecordCurrentTimestamp = 0xffffffff'ffffffff;

// Utility macro to convert string literals passed to local tracing macros into
// StringRef literals.
//
// Example:
//
// #define LOCAL_KTRACE_ENABLE 0
//
// #define LOCAL_KTRACE(string, args...)
//     ktrace_probe(LocalTrace<LOCAL_KTRACE_ENABLE>, TraceContext::Cpu,
//                  KTRACE_STRING_REF(string), ##args)
//
#define KTRACE_STRING_REF_CAT(a, b) a##b
#define KTRACE_STRING_REF(string) KTRACE_STRING_REF_CAT(string, _stringref)

// Mask of trace groups that should be traced. If 0, then all tracing is disabled.
//
// This value is frequently read and rarely modified.
extern ktl::atomic<uint32_t> ktrace_grpmask;

// Determine if ktrace is enabled for the given tag.
inline bool ktrace_enabled(uint32_t tag) {
  return (ktrace_grpmask.load(std::memory_order_relaxed) & tag) != 0;
}

// Write a record to the tracelog.
//
// |payload| must consist of all uint32_t or all uint64_t types.
template <typename... Args>
void ktrace_write_record(uint32_t effective_tag, uint64_t explicit_ts, Args... args);

// Write a tiny ktrace record.
void ktrace_write_record_tiny(uint32_t tag, uint32_t arg);

// Emits a tiny trace record.
inline void ktrace_tiny(uint32_t tag, uint32_t arg) {
  if (unlikely(ktrace_enabled(tag))) {
    ktrace_write_record_tiny(tag, arg);
  }
}

// Emits a new trace record in the given context. Compiles to no-op if |enabled|
// is false.
template <bool enabled>
inline void ktrace(TraceEnabled<enabled>, TraceContext context, uint32_t tag, uint32_t a,
                   uint32_t b, uint32_t c, uint32_t d,
                   uint64_t explicit_ts = kRecordCurrentTimestamp) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, explicit_ts, a, b, c, d);
  }
}

// Backwards-compatible API for existing users of unconditional thread-context
// traces.
static inline void ktrace(uint32_t tag, uint32_t a, uint32_t b, uint32_t c, uint32_t d,
                          uint64_t explicit_ts = kRecordCurrentTimestamp) {
  ktrace(TraceAlways, TraceContext::Thread, tag, a, b, c, d, explicit_ts);
}

// Backwards-compatible API for existing users of unconditional thread-context
// pointer traces.
static inline void ktrace_ptr(uint32_t tag, const void* ptr, uint32_t c, uint32_t d) {
  const uintptr_t raw_value = reinterpret_cast<uintptr_t>(ptr);
  const uint32_t ptr_high = static_cast<uint32_t>(raw_value >> 32);
  const uint32_t ptr_low = static_cast<uint32_t>(raw_value);
  ktrace(tag, ptr_high, ptr_low, c, d);
}

template <bool enabled>
inline void ktrace_probe(TraceEnabled<enabled>, TraceContext context, StringRef* string_ref) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_PROBE_16(string_ref->GetId());
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp);
  }
}

template <bool enabled>
inline void ktrace_probe(TraceEnabled<enabled>, TraceContext context, StringRef* string_ref,
                         uint32_t a, uint32_t b) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_PROBE_24(string_ref->GetId());
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, a, b);
  }
}

template <bool enabled>
inline void ktrace_probe(TraceEnabled<enabled>, TraceContext context, StringRef* string_ref,
                         uint64_t a) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_PROBE_24(string_ref->GetId());
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, a);
  }
}

template <bool enabled>
inline void ktrace_probe(TraceEnabled<enabled>, TraceContext context, StringRef* string_ref,
                         uint64_t a, uint64_t b) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_PROBE_32(string_ref->GetId());
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, a, b);
  }
}

template <bool enabled>
inline void ktrace_begin_duration(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                                  StringRef* string_ref) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_BEGIN_DURATION_16(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp);
  }
}

template <bool enabled>
inline void ktrace_end_duration(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                                StringRef* string_ref) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_END_DURATION_16(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);

  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp);
  }
}

template <bool enabled>
inline void ktrace_begin_duration(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                                  StringRef* string_ref, uint64_t a, uint64_t b) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_BEGIN_DURATION_32(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, a, b);
  }
}

template <bool enabled>
inline void ktrace_end_duration(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                                StringRef* string_ref, uint64_t a, uint64_t b) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_END_DURATION_32(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, a, b);
  }
}

template <bool enabled>
inline void ktrace_flow_begin(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                              StringRef* string_ref, uint64_t flow_id, uint64_t a = 0) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_FLOW_BEGIN(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, flow_id, a);
  }
}

template <bool enabled>
inline void ktrace_flow_end(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                            StringRef* string_ref, uint64_t flow_id, uint64_t a = 0) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_FLOW_END(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, flow_id, a);
  }
}

template <bool enabled>
inline void ktrace_flow_step(TraceEnabled<enabled>, TraceContext context, uint32_t group,
                             StringRef* string_ref, uint64_t flow_id, uint64_t a = 0) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = TAG_FLOW_STEP(string_ref->GetId(), group);
  const uint32_t effective_tag =
      KTRACE_TAG_FLAGS(tag, context == TraceContext::Thread ? 0 : KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(effective_tag))) {
    ktrace_write_record(effective_tag, kRecordCurrentTimestamp, flow_id, a);
  }
}

template <bool enabled>
inline void ktrace_counter(TraceEnabled<enabled>, uint32_t group, StringRef* string_ref,
                           int64_t value, uint64_t counter_id = 0) {
  if constexpr (!enabled) {
    return;
  }
  const uint32_t tag = KTRACE_TAG_FLAGS(TAG_COUNTER(string_ref->GetId(), group), KTRACE_FLAGS_CPU);
  if (unlikely(ktrace_enabled(tag))) {
    ktrace_write_record(tag, kRecordCurrentTimestamp, counter_id, static_cast<uint64_t>(value));
  }
}

void ktrace_name_etc(uint32_t tag, uint32_t id, uint32_t arg, const char* name, bool always);

inline void ktrace_name(uint32_t tag, uint32_t id, uint32_t arg, const char* name,
                        bool always = false) {
  ktrace_name_etc(tag, id, arg, name, always);
}

ssize_t ktrace_read_user(void* ptr, uint32_t off, size_t len);
zx_status_t ktrace_control(uint32_t action, uint32_t options, void* ptr);

void ktrace_report_live_threads();
void ktrace_report_live_processes();

// RAII type that emits begin/end duration events covering the lifetime of the
// instance for use in tracing scopes.
// TODO(eieio): Add option to combine begin/end traces as a single complete
// event for better trace buffer efficiency.
template <typename Enabled, uint16_t group, TraceContext = TraceContext::Thread>
class TraceDuration;

template <bool enabled, uint16_t group, TraceContext context>
class TraceDuration<TraceEnabled<enabled>, group, context> {
 public:
  explicit TraceDuration(StringRef* string_ref) : string_ref_{string_ref} {
    ktrace_begin_duration(TraceEnabled<enabled>{}, context, group, string_ref_);
  }
  TraceDuration(StringRef* string_ref, uint64_t a, uint64_t b) : string_ref_{string_ref} {
    ktrace_begin_duration(TraceEnabled<enabled>{}, context, group, string_ref_, a, b);
  }

  ~TraceDuration() { End(); }

  TraceDuration(const TraceDuration&) = delete;
  TraceDuration& operator=(const TraceDuration&) = delete;
  TraceDuration(TraceDuration&&) = delete;
  TraceDuration& operator=(TraceDuration&&) = delete;

  // Emits the end trace early, before this instance destructs.
  void End() {
    if (string_ref_) {
      ktrace_end_duration(TraceEnabled<enabled>{}, context, group, string_ref_);
      string_ref_ = nullptr;
    }
  }
  // Similar to the overload above, taking the given arguments for the end
  // event.
  void End(uint64_t a, uint64_t b) {
    if (string_ref_) {
      ktrace_end_duration(TraceEnabled<enabled>{}, context, group, string_ref_, a, b);
      string_ref_ = nullptr;
    }
  }

  // Returns a callable to complete this duration trace. This is useful to
  // delegate closing the duration to a callee. The lifetime of the
  // TraceDuration instance must not end before the completer is invoked.
  auto Completer() {
    return [this]() { End(); };
  }

 private:
  StringRef* string_ref_;
};

#endif  // ZIRCON_KERNEL_INCLUDE_LIB_KTRACE_H_
