• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_
18 #define SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_
19 
20 #include <stdlib.h>
21 
22 #include <atomic>
23 #include <exception>
24 
25 namespace perfetto {
26 namespace profiling {
27 
28 // An allocator that uses the given |malloc| & |free| function pointers to
29 // allocate/deallocate memory. Used in the heapprofd_client library, which hooks
30 // the malloc functions in a target process, and therefore needs to use this
31 // allocator to not have its own heap usage enter the hooks.
32 //
33 // See https://en.cppreference.com/w/cpp/named_req/Allocator.
34 template <typename T>
35 class UnhookedAllocator {
36  public:
37   template <typename U>
38   friend class UnhookedAllocator;
39 
40   // to satisfy the Allocator interface
41   using value_type = T;
42 
43   // for implementation convenience
44   using unhooked_malloc_t = void* (*)(size_t);
45   using unhooked_free_t = void (*)(void*);
46 
UnhookedAllocator(unhooked_malloc_t unhooked_malloc,unhooked_free_t unhooked_free)47   UnhookedAllocator(unhooked_malloc_t unhooked_malloc,
48                     unhooked_free_t unhooked_free)
49       : unhooked_malloc_(unhooked_malloc), unhooked_free_(unhooked_free) {}
50 
51   template <typename U>
UnhookedAllocator(const UnhookedAllocator<U> & other)52   constexpr UnhookedAllocator(const UnhookedAllocator<U>& other) noexcept
53       : unhooked_malloc_(other.unhooked_malloc_),
54         unhooked_free_(other.unhooked_free_) {}
55 
allocate(size_t n)56   T* allocate(size_t n) {
57     if (n > size_t(-1) / sizeof(T))
58       std::terminate();
59     if (T* p = static_cast<T*>(unhooked_malloc_(n * sizeof(T))))
60       return p;
61     std::terminate();
62   }
63 
deallocate(T * p,size_t)64   void deallocate(T* p, size_t) noexcept { unhooked_free_(p); }
65 
66  private:
67   unhooked_malloc_t unhooked_malloc_ = nullptr;
68   unhooked_free_t unhooked_free_ = nullptr;
69 };
70 
71 template <typename T, typename U>
72 bool operator==(const UnhookedAllocator<T>& first,
73                 const UnhookedAllocator<U>& second) {
74   return first.unhooked_malloc_ == second.unhooked_malloc_ &&
75          first.unhooked_free_ == second.unhooked_free_;
76 }
77 
78 template <typename T, typename U>
79 bool operator!=(const UnhookedAllocator<T>& first,
80                 const UnhookedAllocator<U>& second) {
81   return !(first == second);
82 }
83 
84 }  // namespace profiling
85 }  // namespace perfetto
86 
87 #endif  // SRC_PROFILING_MEMORY_UNHOOKED_ALLOCATOR_H_
88