// Copyright 2022 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_KERNEL_SPIN_TRACING_STORAGE_H_
#define ZIRCON_KERNEL_INCLUDE_KERNEL_SPIN_TRACING_STORAGE_H_

#include <lib/fxt/interned_string.h>

#include <kernel/lockdep.h>
#include <kernel/spin_tracing_config.h>
#include <ktl/atomic.h>

namespace spin_tracing {

class LockIdGenerator {
 protected:
  LockIdGenerator() = default;
  ~LockIdGenerator() = default;
  static uint64_t CreateId() { return generator_.fetch_add(1, ktl::memory_order_relaxed); }

 private:
  static inline ktl::atomic<uint64_t> generator_{1};
};

template <LockType kLockType, bool Enabled = false>
class LockNameStorage {
 public:
  constexpr void SetLockClassId(lockdep::LockClassId lcid) {}

 protected:
  constexpr LockNameStorage() = default;
  explicit constexpr LockNameStorage(uint16_t) {}
  constexpr EncodedLockId encoded_lock_id() const { return EncodedLockId::Invalid(); }
};

template <LockType kLockType>
class LockNameStorage<kLockType, true> : public LockIdGenerator {
 public:
  void SetLockClassId(lockdep::LockClassId lcid) {
    if ((lcid != lockdep::kInvalidLockClassId) &&
        (encoded_lock_id_.class_name() == fxt::InternedString::kInvalidId)) {
      lockdep::MetadataLockClassState* state = lockdep::MetadataLockClassState::Get(lcid);
      const fxt::InternedString* name = &state->interned_name();

      // Note: in a perfect world it should be absolutely impossible for the
      // reference returned by `interned_name()` to be invalid.  Unfortunately,
      // because of _technically_ possible global ctor races, it is possible to
      // be accessing a LockStateClass which has not fully been constructed yet,
      // meaning that its reference to its name might be null (something which
      // _should_ be impossible). Until we get to C++20 and can use
      // consteval/constinit, there is always a small chance that this could
      // happen in an instrumented build.
      //
      // If/when it does happen, it can be a pretty unpleasant experience as the
      // kernel will panic before there is even serial enabled, making things
      // extremely difficult to debug.  Adding this check (and hoping that the
      // compiler does not elide it) makes for a better experience in the worst
      // case scenario.  It is possible for a lock to go unnamed, but at least
      // we won't crash during early boot.
      if (name != nullptr) {
        encoded_lock_id_.SetLockClassId(name->GetId());
      }
    }
  }

 protected:
  constexpr LockNameStorage()
      : encoded_lock_id_{kLockType, CreateId(), fxt::InternedString::kInvalidId} {}

  explicit LockNameStorage(uint16_t class_name_id)
      : encoded_lock_id_{kLockType, CreateId(), class_name_id} {}

  EncodedLockId encoded_lock_id() const { return encoded_lock_id_; }

 private:
  EncodedLockId encoded_lock_id_;
};

}  // namespace spin_tracing

#endif  // ZIRCON_KERNEL_INCLUDE_KERNEL_SPIN_TRACING_STORAGE_H_
