basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/fast_new.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : Fast memory allocation
00004 * DESCRIPTION: Fast allocations is realized by using a linked list
00005 *              of allocations for each fixed size divisible by
00006 *              a word length up to MMX_MAX_FAST. Otherwise,
00007 *              usual memory allocation is used.
00008 * COPYRIGHT  : (C) 1999-2008  Joris van der Hoeven
00009 *******************************************************************************
00010 * This software falls under the GNU general public license and comes WITHOUT
00011 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00012 * If you don't have this file, write to the Free Software Foundation, Inc.,
00013 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00014 ******************************************************************************/
00015 
00016 #include <basix/port.hpp>
00017 #ifdef BASIX_HAVE_STDINT_H
00018 #include <stdint.h>
00019 using ::uintptr_t;
00020 #endif
00021 
00022 namespace mmx {
00023 
00024 #ifdef MMX_ENABLE_FAST_ALLOCATORS
00025 
00026 char   alloc_table[MMX_MAX_FAST]; // Static declaration initializes with NULL's
00027 char*  alloc_mem= NULL;
00028 size_t alloc_remains= 0;
00029 nat    allocated= 0;
00030 nat    fast_chunks= 0;
00031 nat    large_uses= 0;
00032 
00033 void*
00034 safe_malloc (register size_t sz) {
00035   // Always guarantees 16 byte alignment
00036   register char* ret;
00037   register char* ptr= (char*) malloc (sz + 16);
00038   if (ptr == NULL) {
00039     fprintf (stderr, "Fatal error: out of memory\n");
00040     assert (false);
00041     exit (1);
00042   }
00043   ret= ptr + (16 - (((nat) ((uintptr_t) ((void*) ptr))) & 15));
00044   //printf ("Alloc: %lx, %lx\n",
00045   //        (uintptr_t) (void*) ret, (uintptr_t) (void*) ptr);
00046   *((void**) ((void*) (ret - sizeof (void*))))= (void*) ptr;
00047   return (void*) ret;
00048 }
00049 
00050 void*
00051 enlarge_malloc (register size_t sz) {
00052   if (alloc_remains<sz) {
00053     alloc_mem    = (char *) safe_malloc (MMX_BLOCK_SIZE);
00054     alloc_remains= MMX_BLOCK_SIZE - 16;
00055     fast_chunks++;
00056   }
00057   register void* ptr= alloc_mem;
00058   if ((sz&15) == 0 && (((nat) ((uintptr_t) ptr)) & 15) != 0) {
00059     // NOTE: force 16 byte alignment for sizes which are multiples of 16
00060     nat sz2= 16 - (((nat) ((uintptr_t) ptr)) & 15);
00061     MMX_IND (ptr)       = MMX_ALLOC_PTR (sz2);
00062     MMX_ALLOC_PTR (sz2) = ptr;
00063     alloc_mem      += sz2;
00064     alloc_remains  -= sz2;
00065     ptr             = alloc_mem;
00066   }
00067   alloc_mem    += sz;
00068   alloc_remains-= sz;
00069   return ptr;
00070 }
00071 
00072 void*
00073 mmx_malloc_thread_unsafe (register size_t sz) {
00074   if (sz == 0) return NULL;
00075   sz= (sz+MMX_WORD_LENGTH_INC)&MMX_WORD_MASK;
00076   if (sz<MMX_MAX_FAST) {
00077     register void *ptr= MMX_ALLOC_PTR (sz);
00078     if (ptr==NULL) return enlarge_malloc (sz);
00079     //assert (((nat) ptr) != 2);
00080     //assert (((nat) (MMX_IND (ptr))) != 2);
00081     MMX_ALLOC_PTR (sz)= MMX_IND (ptr);
00082     return ptr;
00083   }
00084   else {
00085     //printf ("Big alloc of %d bytes", (int) sz);
00086     //printf ("Memory used: %d bytes", (int) mmx_used_bytes ());
00087     large_uses += sz;
00088     return safe_malloc (sz);
00089   }
00090 }
00091 
00092 void
00093 mmx_free_thread_unsafe (register void* ptr, register size_t sz) {
00094   if (sz == 0) return;
00095   sz=(sz+MMX_WORD_LENGTH_INC)&MMX_WORD_MASK;
00096   if (sz<MMX_MAX_FAST) {
00097     MMX_IND (ptr)     = MMX_ALLOC_PTR (sz);
00098     MMX_ALLOC_PTR (sz)= ptr;
00099   }
00100   else {
00101     large_uses -= sz;
00102     safe_free (ptr);
00103     //printf ("Big free of %d bytes", (int) sz);
00104     //printf ("Memory used: %d bytes", (int) mmx_used_bytes ());
00105   }
00106 }
00107 
00108 void*
00109 mmx_realloc_thread_unsafe (register void* old_ptr, register size_t old_sz,
00110                            register size_t new_sz) {
00111   void* new_ptr= mmx_malloc_thread_unsafe (new_sz);
00112   memcpy (new_ptr, old_ptr, new_sz < old_sz ? new_sz: old_sz);
00113   mmx_free_thread_unsafe (old_ptr, old_sz);
00114   return new_ptr;
00115 }
00116 
00117 size_t
00118 mmx_compute_free (void* ptr) {
00119   nat i= (nat) -1;
00120   while (ptr!=NULL) {
00121     i++;
00122     ptr= MMX_IND (ptr);
00123   }
00124   return i;
00125 }
00126 
00127 size_t
00128 mmx_used_bytes () {
00129   size_t free_bytes= alloc_remains;
00130   size_t chunks_use= MMX_BLOCK_SIZE*fast_chunks;
00131   for (nat i=MMX_WORD_LENGTH; i<MMX_MAX_FAST; i+=MMX_WORD_LENGTH)
00132     free_bytes += i*mmx_compute_free (alloc_table+i);
00133   size_t small_uses= chunks_use- free_bytes;
00134   return small_uses+ large_uses;
00135 }
00136 
00137 void
00138 mmx_mem_info () {
00139   mmout << "\n---------------- memory statistics ----------------\n";
00140   size_t free_bytes= alloc_remains;
00141   size_t chunks_use= MMX_BLOCK_SIZE*fast_chunks;
00142   for (nat i=MMX_WORD_LENGTH; i<MMX_MAX_FAST; i+=MMX_WORD_LENGTH)
00143     free_bytes += i*mmx_compute_free (alloc_table+i);
00144   size_t small_uses= chunks_use- free_bytes;
00145   size_t total_uses= small_uses+ large_uses;
00146   // mmout << "Fast chunks   : " << chunks_use << " bytes\n";
00147   // mmout << "Free on chunks: " << alloc_remains << " bytes\n";
00148   mmout << "User          : " << total_uses << " bytes\n";
00149   mmout << "Allocator     : " << chunks_use+ large_uses << " bytes\n";
00150   mmout << "Small mallocs : "
00151         << ((100*((float) small_uses))/((float) total_uses)) << "%\n";
00152 }
00153 
00154 #else // not MMX_ENABLE_FAST_ALLOCATORS
00155 
00156 extern size_t bytes_in_use= 0;
00157 
00158 size_t
00159 mmx_used_bytes () {
00160   return bytes_in_use;
00161 }
00162 
00163 #endif // MMX_ENABLE_FAST_ALLOCATORS
00164 
00165 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines