Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

custmem.hpp

Go to the documentation of this file.
00001 // +-------------------------------------------------------------------------+
00002 // |               I__n__t__e__L__i__b           0.6.10 development          |
00003 // | Copyright (c) Andrey Vikt. Stolyarov <crocodil_AT_croco.net> 2000-2007. |
00004 // |                                                                         |
00005 // | This is free software. The library part is available under              |
00006 // |                               GNU LESSER GENERAL PUBLIC LICENSE v.2.1.  |
00007 // | GNU LGPL v2.1 is found in docs/gnu_gpl2.txt,  or at  http://www.gnu.org |
00008 // |     Please see also docs/readme.txt and visit http://www.intelib.org    |
00009 // |                                                                         |
00010 // | !!! THERE IS NO WARRANTY OF ANY KIND, NEITHER EXPRESSED NOR IMPLIED !!! |
00011 // +-------------------------------------------------------------------------+
00012 
00013 
00014 
00015 
00024 #ifndef INTELIB_CUSTMEM_HPP_SENTRY
00025 #define INTELIB_CUSTMEM_HPP_SENTRY
00026 
00027 
00028 #ifndef INTELIB_CUSTOM_MEMORY_MANAGEMENT
00029 
00030 #define INTELIB_CUSTOM_MEMORY_MANAGEMENT 1
00031 #endif
00032 
00033 #if INTELIB_CUSTOM_MEMORY_MANAGEMENT == 1
00034 
00035 #ifndef INTELIB_CMM_MAX_MEM_BLOCK
00036 #define INTELIB_CMM_MAX_MEM_BLOCK (256*1024)
00037 #endif
00038 
00039 
00040 
00041 #ifndef _SIZE_T
00042 #define _SIZE_T
00043 typedef unsigned int size_t;
00044 #endif 
00045 
00046 #ifndef INTELIB_CUSTOM_MEMORY_MANAGEMENT
00047 #error smemory.hpp must not be included when there is no memory management
00048 #endif 
00049 
00051 template <int unit_size, int block_size>
00052 class CustomMemoryManager {
00053     union memoryunit {
00054         char raw[unit_size];
00055         memoryunit *next;    // Used in free unit chains
00056     };
00057     struct blockhandler {
00058         int firstfreeunit;
00059         blockhandler *next;
00060         memoryunit block[block_size];
00061         blockhandler(blockhandler *nx = 0)
00062         { firstfreeunit = 0; next = nx; }
00063         void *getunit()
00064         { return (void*) ((firstfreeunit < block_size) ?
00065                               block + firstfreeunit++ : 0 ) ;
00066         }
00067     };
00068     blockhandler *firstblock;
00069     memoryunit *freechain;
00070 public:
00072     CustomMemoryManager() {
00073         firstblock = new blockhandler;
00074         freechain = 0;
00075     }
00077     ~CustomMemoryManager() {
00078         while(firstblock) {
00079             blockhandler *tmp = firstblock;
00080             firstblock = firstblock->next;
00081             delete tmp;
00082         }
00083     }
00085     void *GetUnit(size_t s) {
00086         void *r;
00087         if(freechain) {   // If there's a freed unit, reuse it
00088             r = freechain;
00089             freechain = freechain->next;
00090         } else {          // otherwise, hope there's still some free space
00091             // in the block last allocated
00092             r = firstblock->getunit();
00093             if(!r) {        // alas, we need to allocate another one
00094                 firstblock = new blockhandler(firstblock);
00095                 r = firstblock->getunit();
00096                 // this MUST succeed 'cause block is empty
00097             }
00098         }
00099         return r;
00100     }
00102     void ReleaseUnit(void *unit, size_t s) {
00103         // Just add it to the free units chain
00104         ((memoryunit*)unit) -> next = freechain;
00105         freechain = (memoryunit*)unit;
00106     }
00107 };
00108 
00109 
00111 
00118 #define INTELIB_DECLARE_CUSTOM_MEMORY_MANAGEMENT(classname)         \
00119   private:                                                          \
00120   static class classname##MemoryManager TheMemoryManager;           \
00121   public:                                                           \
00122   void* operator new(size_t s);                                     \
00123   void operator delete(void *p, size_t s);
00124 
00126 
00131 #define INTELIB_IMPLEMENT_CUSTOM_MEMORY_MANAGEMENT(classname)       \
00132   class classname##MemoryManager :                                  \
00133      public CustomMemoryManager<sizeof (classname),                 \
00134            INTELIB_CMM_MAX_MEM_BLOCK / sizeof(classname)> {}        \
00135        classname::TheMemoryManager;                                 \
00136   void* classname::operator new(size_t s)                           \
00137      { return TheMemoryManager.GetUnit(s); }                        \
00138   void classname::operator delete(void *p, size_t s)                \
00139      { return TheMemoryManager.ReleaseUnit(p, s); }                 
00140 
00141 
00142 
00143 #endif       // intelib_custom_memory_management
00144 #endif       // sentry

Generated on Tue Dec 18 00:39:43 2007 for InteLib by  doxygen 1.4.1