/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_
#define SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_

#include <stdlib.h>

#include <atomic>
#include <exception>

namespace perfetto {
namespace profiling {

// An allocator that uses the given |malloc| & |free| function pointers to
// allocate/deallocate memory. Used in the heapprofd_client library, which hooks
// the malloc functions in a target process, and therefore needs to use this
// allocator to not have its own heap usage enter the hooks.
//
// See https://en.cppreference.com/w/cpp/named_req/Allocator.
template <typename T>
class UnhookedAllocator {
 public:
  template <typename U>
  friend class UnhookedAllocator;

  // to satisfy the Allocator interface
  using value_type = T;

  // for implementation convenience
  using unhooked_malloc_t = void* (*)(size_t);
  using unhooked_free_t = void (*)(void*);

  UnhookedAllocator(unhooked_malloc_t unhooked_malloc,
                    unhooked_free_t unhooked_free)
      : unhooked_malloc_(unhooked_malloc), unhooked_free_(unhooked_free) {}

  template <typename U>
  constexpr explicit UnhookedAllocator(
      const UnhookedAllocator<U>& other) noexcept
      : unhooked_malloc_(other.unhooked_malloc_),
        unhooked_free_(other.unhooked_free_) {}

  T* allocate(size_t n) {
    if (n > size_t(-1) / sizeof(T))
      std::terminate();
    if (T* p = static_cast<T*>(unhooked_malloc_(n * sizeof(T))))
      return p;
    std::terminate();
  }

  void deallocate(T* p, size_t) noexcept { unhooked_free_(p); }

 private:
  unhooked_malloc_t unhooked_malloc_ = nullptr;
  unhooked_free_t unhooked_free_ = nullptr;
};

template <typename T, typename U>
bool operator==(const UnhookedAllocator<T>& first,
                const UnhookedAllocator<U>& second) {
  return first.unhooked_malloc_ == second.unhooked_malloc_ &&
         first.unhooked_free_ == second.unhooked_free_;
}

template <typename T, typename U>
bool operator!=(const UnhookedAllocator<T>& first,
                const UnhookedAllocator<U>& second) {
  return !(first == second);
}

}  // namespace profiling
}  // namespace perfetto

#endif  // SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_
