// Copyright 2020 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.

#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_PIN_EXECUTABLE_MEMORY_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_PIN_EXECUTABLE_MEMORY_H_

#include <lib/async-loop/cpp/loop.h>
#include <lib/fzl/vmo-mapper.h>
#include <zircon/syscalls/object.h>

#include <mutex>
#include <vector>

#include "src/lib/fxl/synchronization/thread_annotations.h"

namespace media::audio {

// Spins up a background thread to periodically touch all pages of executable
// memory, which keeps our executable pages on the "recently used" list and prevents
// them from being paged out. This is a hacky implementation of memory pinning.
// We are using this temporarily until Zircon provides a better solution.
// See fxbug.dev/62830.
class PinExecutableMemory {
 public:
  // Return the singleton object. Executable memory is pinned the first time this
  // function is called and periodically thereafter. If on-demand pinning is desired,
  // use Singleton().Pin().
  static PinExecutableMemory& Singleton();

  // Pins all executable memory. Thread-safe.
  void Pin();

  // Our Pin() implementation assumes that mappings are not concurrently discarded.
  // To prevent races, dynamic mappings must be made through the following object, which
  // synchronizes with Pin() when the mapping is destructed.
  class VmoMapper {
   public:
    VmoMapper() = default;
    VmoMapper(VmoMapper&&) = default;
    VmoMapper(VmoMapper&) = delete;

    ~VmoMapper() {
      if (!mapper_.start()) {
        return;
      }
      auto& pinner = PinExecutableMemory::Singleton();
      std::lock_guard<std::mutex> lock(pinner.mutex_);
      pinner.discarded_mappings_.push_back({
          .start = reinterpret_cast<size_t>(start()),
          .end = reinterpret_cast<size_t>(start()) + size(),
      });
      mapper_.Unmap();
    }

    zx_status_t CreateAndMap(uint64_t size, zx_vm_option_t map_flags,
                             fbl::RefPtr<fzl::VmarManager> vmar_manager = nullptr,
                             zx::vmo* vmo_out = nullptr,
                             zx_rights_t vmo_rights = ZX_RIGHT_SAME_RIGHTS,
                             uint32_t cache_policy = 0, uint32_t vmo_options = 0) {
      return mapper_.CreateAndMap(size, map_flags, vmar_manager, vmo_out, vmo_rights, cache_policy,
                                  vmo_options);
    }

    zx_status_t Map(const zx::vmo& vmo, uint64_t offset, uint64_t size, zx_vm_option_t map_flags,
                    fbl::RefPtr<fzl::VmarManager> vmar_manager = nullptr) {
      return mapper_.Map(vmo, offset, size, map_flags, vmar_manager);
    }

    void* start() const { return mapper_.start(); }
    uint64_t size() const { return mapper_.size(); }

   private:
    fzl::VmoMapper mapper_;
  };

 private:
  friend class VmoMapper;

  PinExecutableMemory();
  PinExecutableMemory(PinExecutableMemory&) = delete;
  PinExecutableMemory(PinExecutableMemory&&) = delete;

  void PeriodicPin();
  std::vector<zx_info_maps_t> ListVMaps();
  bool ShouldSkip(size_t addr) const FXL_REQUIRE(mutex_);

  // Thread annotation workaround for non-scoped lock acquisitions.
  void AssertMutexHeld() __attribute__((assert_capability(mutex_))) {}

  struct Range {
    size_t start;
    size_t end;
  };

  async::Loop loop_;

  std::mutex mutex_;
  std::vector<Range> discarded_mappings_ FXL_GUARDED_BY(mutex_);
  size_t last_pinned_bytes_ FXL_GUARDED_BY(mutex_) = 0;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_PIN_EXECUTABLE_MEMORY_H_
