Panda3D
memoryHook.I
1 // Filename: memoryHook.I
2 // Created by: drose (28Jun07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: MemoryHook::inc_heap
18 // Access: Public
19 // Description: Called by our alternative malloc implementations
20 // (dlmalloc and ptmalloc2) to indicate they have
21 // requested size bytes from the system for the heap.
22 ////////////////////////////////////////////////////////////////////
23 INLINE void MemoryHook::
24 inc_heap(size_t size) {
25 #ifdef DO_MEMORY_USAGE
26  AtomicAdjust::add(_requested_heap_size, (AtomicAdjust::Integer)size);
27 #endif // DO_MEMORY_USAGE
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: MemoryHook::dec_heap
32 // Access: Public
33 // Description: Called by our alternative malloc implementations
34 // (dlmalloc and ptmalloc2) to indicate they have
35 // returned size bytes to the system from the heap.
36 ////////////////////////////////////////////////////////////////////
37 INLINE void MemoryHook::
38 dec_heap(size_t size) {
39 #ifdef DO_MEMORY_USAGE
40  //assert((int)size <= _requested_heap_size);
41  AtomicAdjust::add(_requested_heap_size, -(AtomicAdjust::Integer)size);
42 #endif // DO_MEMORY_USAGE
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: MemoryHook::get_memory_alignment
47 // Access: Public, Static
48 // Description: Returns the global memory alignment. This is the
49 // number of bytes at which each allocated memory
50 // pointer will be aligned.
51 ////////////////////////////////////////////////////////////////////
52 INLINE size_t MemoryHook::
54 #ifdef LINMATH_ALIGN
55  // We require 16-byte alignment of certain structures, to support
56  // SSE2. We don't strictly have to align *everything*, but it's just
57  // easier to do so.
58 #ifdef __AVX__
59  // Eigen requires 32-byte alignment when using AVX instructions.
60  const size_t alignment_size = 32;
61 #else
62  const size_t alignment_size = 16;
63 #endif
64 #else
65  // Otherwise, use word alignment.
66  const size_t alignment_size = sizeof(void *);
67 #endif
68  return alignment_size;
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: MemoryHook::get_header_reserved_bytes
73 // Access: Public, Static
74 // Description: Returns the number of additional bytes that are
75 // reserved at the beginning of every allocated block to
76 // store a size_t.
77 ////////////////////////////////////////////////////////////////////
78 INLINE size_t MemoryHook::
80  // We need to figure out the minimum amount of additional space we
81  // need in order to place a single word at the start of each
82  // allocated block, to store the size of the block.
83 
84 #ifdef LINMATH_ALIGN
85  // If we're doing SSE2 alignment, we must reserve a full 16-byte
86  // block, since anything less than that will spoil the alignment.
87 #ifdef __AVX__
88  // Eigen requires 32-byte alignment when using AVX instructions.
89  const size_t header_reserved_bytes = 32;
90 #else
91  const size_t header_reserved_bytes = 16;
92 #endif
93 
94 #elif defined(MEMORY_HOOK_DO_ALIGN)
95  // If we're just aligning to words, we reserve a block as big as two
96  // words, to allow us wiggle room to align the word precisely within
97  // that block.
98  static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
99 
100 #else
101  // If we're not aligning, we just need space for the word itself.
102  static const size_t header_reserved_bytes = sizeof(size_t);
103 #endif
104 
105  return header_reserved_bytes;
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: MemoryHook::get_page_size
110 // Access: Public
111 // Description: Returns the operating system page size. This is the
112 // minimum granularity required for calls to
113 // mmap_alloc(). Also see round_up_to_page_size().
114 ////////////////////////////////////////////////////////////////////
115 INLINE size_t MemoryHook::
116 get_page_size() const {
117  return _page_size;
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: MemoryHook::round_up_to_page_size
122 // Access: Public
123 // Description: Rounds the indicated size request up to the next
124 // larger multiple of page_size, to qualify it for a
125 // call to mmap_alloc().
126 ////////////////////////////////////////////////////////////////////
127 INLINE size_t MemoryHook::
128 round_up_to_page_size(size_t size) const {
129  return ((size + _page_size - 1) / _page_size) * _page_size;
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: MemoryHook::inflate_size
134 // Access: Private, Static
135 // Description: Increments the amount of requested size as necessary
136 // to accommodate the extra data we might piggyback on
137 // each allocated block.
138 ////////////////////////////////////////////////////////////////////
139 INLINE size_t MemoryHook::
140 inflate_size(size_t size) {
141 #if defined(MEMORY_HOOK_DO_ALIGN)
142  // If we're aligning, we need to request the header size, plus extra
143  // bytes to give us wiggle room to adjust the pointer.
144  return size + get_header_reserved_bytes() + get_memory_alignment() - 1;
145 #elif defined(DO_MEMORY_USAGE)
146  // If we're not aligning, but we're tracking memory allocations, we
147  // just need the header size extra (this gives us a place to store
148  // the size of the allocated block).
149  return size + get_header_reserved_bytes();
150 #else
151  // If we're not doing any of that, we can just allocate the precise
152  // requested amount.
153  return size;
154 #endif // DO_MEMORY_USAGE
155 }
156 
157 ////////////////////////////////////////////////////////////////////
158 // Function: MemoryHook::alloc_to_ptr
159 // Access: Private, Static
160 // Description: Converts an allocated pointer to a pointer returnable
161 // to the application. Stuffs size in the first n bytes
162 // of the allocated space.
163 ////////////////////////////////////////////////////////////////////
164 INLINE void *MemoryHook::
165 alloc_to_ptr(void *alloc, size_t size) {
166 #if defined(MEMORY_HOOK_DO_ALIGN)
167  size_t alignment = get_memory_alignment();
168  // Move the allocated pointer up to the next even alignment.
169  size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
170  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
171  root[0] = size;
172  root[1] = (size_t)alloc; // Save the pointer we originally allocated.
173  return (void *)((char *)root + get_header_reserved_bytes());
174 #elif defined(DO_MEMORY_USAGE)
175  size_t *root = (size_t *)alloc;
176  root[0] = size;
177  return (void *)((char *)root + get_header_reserved_bytes());
178 #else
179  return alloc;
180 #endif // DO_MEMORY_USAGE
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: MemoryHook::ptr_to_alloc
185 // Access: Private, Static
186 // Description: Converts an application pointer back to the original
187 // allocated pointer. Extracts size from the first n
188 // bytes of the allocated space.
189 ////////////////////////////////////////////////////////////////////
190 INLINE void *MemoryHook::
191 ptr_to_alloc(void *ptr, size_t &size) {
192 #if defined(MEMORY_HOOK_DO_ALIGN)
193  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
194  size = root[0];
195  void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
196  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
197  return alloc;
198 #elif defined(DO_MEMORY_USAGE)
199  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
200  size = root[0];
201  return (void *)root;
202 #else
203  return ptr;
204 #endif // DO_MEMORY_USAGE
205 }
void inc_heap(size_t size)
Called by our alternative malloc implementations (dlmalloc and ptmalloc2) to indicate they have reque...
Definition: memoryHook.I:24
static void add(Integer &var, Integer delta)
Atomically computes var += delta.
size_t get_page_size() const
Returns the operating system page size.
Definition: memoryHook.I:116
static size_t get_header_reserved_bytes()
Returns the number of additional bytes that are reserved at the beginning of every allocated block to...
Definition: memoryHook.I:79
void dec_heap(size_t size)
Called by our alternative malloc implementations (dlmalloc and ptmalloc2) to indicate they have retur...
Definition: memoryHook.I:38
size_t round_up_to_page_size(size_t size) const
Rounds the indicated size request up to the next larger multiple of page_size, to qualify it for a ca...
Definition: memoryHook.I:128
static size_t get_memory_alignment()
Returns the global memory alignment.
Definition: memoryHook.I:53