Panda3D
 All Classes Functions Variables Enumerations
memoryHook.I
00001 // Filename: memoryHook.I
00002 // Created by:  drose (28Jun07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: MemoryHook::inc_heap
00018 //       Access: Public
00019 //  Description: Called by our alternative malloc implementations
00020 //               (dlmalloc and ptmalloc2) to indicate they have
00021 //               requested size bytes from the system for the heap.
00022 ////////////////////////////////////////////////////////////////////
00023 INLINE void MemoryHook::
00024 inc_heap(size_t size) {
00025 #ifdef DO_MEMORY_USAGE
00026   AtomicAdjust::add(_requested_heap_size, (AtomicAdjust::Integer)size);
00027 #endif  // DO_MEMORY_USAGE
00028 }
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: MemoryHook::dec_heap
00032 //       Access: Public
00033 //  Description: Called by our alternative malloc implementations
00034 //               (dlmalloc and ptmalloc2) to indicate they have
00035 //               returned size bytes to the system from the heap.
00036 ////////////////////////////////////////////////////////////////////
00037 INLINE void MemoryHook::
00038 dec_heap(size_t size) {
00039 #ifdef DO_MEMORY_USAGE
00040   //assert((int)size <= _requested_heap_size);
00041   AtomicAdjust::add(_requested_heap_size, -(AtomicAdjust::Integer)size);
00042 #endif  // DO_MEMORY_USAGE
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: MemoryHook::get_memory_alignment
00047 //       Access: Public, Static
00048 //  Description: Returns the global memory alignment.  This is the
00049 //               number of bytes at which each allocated memory
00050 //               pointer will be aligned.
00051 ////////////////////////////////////////////////////////////////////
00052 INLINE size_t MemoryHook::
00053 get_memory_alignment() {
00054 #ifdef LINMATH_ALIGN
00055   // We require 16-byte alignment of certain structures, to support
00056   // SSE2.  We don't strictly have to align *everything*, but it's just
00057   // easier to do so.
00058   const size_t alignment_size = 16;
00059 #else
00060   // Otherwise, use word alignment.
00061   const size_t alignment_size = sizeof(void *);
00062 #endif
00063   return alignment_size;
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: MemoryHook::get_header_reserved_bytes
00068 //       Access: Public, Static
00069 //  Description: Returns the number of additional bytes that are
00070 //               reserved at the beginning of every allocated block to
00071 //               store a size_t.
00072 ////////////////////////////////////////////////////////////////////
00073 INLINE size_t MemoryHook::
00074 get_header_reserved_bytes() {
00075   // We need to figure out the minimum amount of additional space we
00076   // need in order to place a single word at the start of each
00077   // allocated block, to store the size of the block.
00078 
00079 #ifdef LINMATH_ALIGN
00080   // If we're doing SSE2 alignment, we must reserve a full 16-byte
00081   // block, since anything less than that will spoil the alignment.
00082   static const size_t header_reserved_bytes = 16;
00083 
00084 #elif defined(MEMORY_HOOK_DO_ALIGN)
00085   // If we're just aligning to words, we reserve a block as big as two
00086   // words, to allow us wiggle room to align the word precisely within
00087   // that block.
00088   static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
00089 
00090 #else
00091   // If we're not aligning, we just need space for the word itself.
00092   static const size_t header_reserved_bytes = sizeof(size_t);
00093 #endif
00094 
00095   return header_reserved_bytes;
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: MemoryHook::get_page_size
00100 //       Access: Public
00101 //  Description: Returns the operating system page size.  This is the
00102 //               minimum granularity required for calls to
00103 //               mmap_alloc().  Also see round_up_to_page_size().
00104 ////////////////////////////////////////////////////////////////////
00105 INLINE size_t MemoryHook::
00106 get_page_size() const {
00107   return _page_size;
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: MemoryHook::round_up_to_page_size
00112 //       Access: Public
00113 //  Description: Rounds the indicated size request up to the next
00114 //               larger multiple of page_size, to qualify it for a
00115 //               call to mmap_alloc().
00116 ////////////////////////////////////////////////////////////////////
00117 INLINE size_t MemoryHook::
00118 round_up_to_page_size(size_t size) const {
00119   return  ((size + _page_size - 1) / _page_size) * _page_size;
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: MemoryHook::inflate_size
00124 //       Access: Private, Static
00125 //  Description: Increments the amount of requested size as necessary
00126 //               to accommodate the extra data we might piggyback on
00127 //               each allocated block.
00128 ////////////////////////////////////////////////////////////////////
00129 INLINE size_t MemoryHook::
00130 inflate_size(size_t size) {
00131 #if defined(MEMORY_HOOK_DO_ALIGN)
00132   // If we're aligning, we need to request the header size, plus extra
00133   // bytes to give us wiggle room to adjust the pointer.
00134   return size + get_header_reserved_bytes() + get_memory_alignment() - 1;
00135 #elif defined(DO_MEMORY_USAGE)
00136   // If we're not aligning, but we're tracking memory allocations, we
00137   // just need the header size extra (this gives us a place to store
00138   // the size of the allocated block).
00139   return size + get_header_reserved_bytes();  
00140 #else
00141   // If we're not doing any of that, we can just allocate the precise
00142   // requested amount.
00143   return size;
00144 #endif  // DO_MEMORY_USAGE
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: MemoryHook::alloc_to_ptr
00149 //       Access: Private, Static
00150 //  Description: Converts an allocated pointer to a pointer returnable
00151 //               to the application.  Stuffs size in the first n bytes
00152 //               of the allocated space.
00153 ////////////////////////////////////////////////////////////////////
00154 INLINE void *MemoryHook::
00155 alloc_to_ptr(void *alloc, size_t size) {
00156 #if defined(MEMORY_HOOK_DO_ALIGN)
00157   size_t alignment = get_memory_alignment();
00158   // Move the allocated pointer up to the next even alignment.
00159   size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
00160   assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
00161   root[0] = size;
00162   root[1] = (size_t)alloc;  // Save the pointer we originally allocated.
00163   return (void *)((char *)root + get_header_reserved_bytes());
00164 #elif defined(DO_MEMORY_USAGE) 
00165   size_t *root = (size_t *)alloc;
00166   root[0] = size;
00167   return (void *)((char *)root + get_header_reserved_bytes());
00168 #else
00169   return alloc;
00170 #endif  // DO_MEMORY_USAGE
00171 }
00172 
00173 ////////////////////////////////////////////////////////////////////
00174 //     Function: MemoryHook::ptr_to_alloc
00175 //       Access: Private, Static
00176 //  Description: Converts an application pointer back to the original
00177 //               allocated pointer.  Extracts size from the first n
00178 //               bytes of the allocated space.
00179 ////////////////////////////////////////////////////////////////////
00180 INLINE void *MemoryHook::
00181 ptr_to_alloc(void *ptr, size_t &size) {
00182 #if defined(MEMORY_HOOK_DO_ALIGN)
00183   size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
00184   size = root[0];
00185   void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
00186   assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
00187   return alloc;
00188 #elif defined(DO_MEMORY_USAGE) 
00189   size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
00190   size = root[0];
00191   return (void *)root;
00192 #else
00193   return ptr;
00194 #endif  // DO_MEMORY_USAGE
00195 }
 All Classes Functions Variables Enumerations