Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/memorypool.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 ///@cond DOXYGEN_HIDDEN
00020 
00021 #ifndef MEMORYPOOL_H
00022 #define MEMORYPOOL_H
00023 #include <vector>
00024 #include <iostream>
00025 #include <cstdlib>
00026 #include <cassert>
00027 #ifdef _OPENMP
00028 #include <omp.h>
00029 #endif
00030 
00031 #ifdef _OPENMP
00032 #define THREAD_NUMBER  omp_get_thread_num()
00033 static const size_t MAXNBTHREADS = 128;
00034 #else
00035 #define THREAD_NUMBER 0
00036 static const size_t MAXNBTHREADS = 1;
00037 #endif
00038 
00039 static const size_t BUFFOBJ      = 20;
00040 
00041 namespace tlp {
00042 /**
00043   * @class MemoryPool
00044   * \brief That class enables to easily create a memory pool for an a class
00045   *
00046   * It allocates chunk of BUFFOBJ size of continous memory to allocate
00047   * instance of the class. After a delete the memory is not free, and
00048   * will be reused at the next new of the class.
00049   *
00050   * @warning it is not recommended to inherit from an object that inherit of that class
00051   *
00052   * The following  code only calls malloc one time even if NBTRY object are created
00053   * in that example, the speedup is about 23, without MemoryPool malloc is called NBTRY times
00054   * @code
00055   * class A : public MemoryPool<A> {
00056   * public:
00057   *     A(){}
00058   *    ~A(){}
00059   *    int data[1000];
00060   * };
00061   *
00062   * size_t NBTRY = 1000 * 1000;
00063   * for (size_t j=0; j < NBTRY; ++j) {
00064   *    A *a = new A();
00065   *    a->data[100] = j;
00066   *    r1 += a->data[100];
00067   *    delete a;
00068   * }
00069   * @endcode
00070   *
00071   */
00072 template <typename  TYPE >
00073 class MemoryPool {
00074 public:
00075   MemoryPool() {
00076   }
00077 
00078 #ifndef NDEBUG
00079   inline void *operator new( size_t sizeofObj) {
00080 #else
00081   inline void *operator new( size_t ) {
00082 #endif
00083     assert(sizeof(TYPE) == sizeofObj); //to prevent inheritance with different size of object
00084     TYPE * t;
00085     t = getObject(THREAD_NUMBER);
00086     return t;
00087   }
00088 
00089   inline void operator delete( void *p ) {
00090     _freeObject[THREAD_NUMBER].push_back(p);
00091   }
00092 private:
00093   static std::vector<void * > _freeObject[MAXNBTHREADS];
00094 
00095   static TYPE* getObject(size_t threadId) {
00096     TYPE *result;
00097 
00098     if (_freeObject[threadId].empty()) {
00099       TYPE * p = (TYPE *)malloc(BUFFOBJ * sizeof(TYPE));
00100 
00101       for (size_t j=0; j< BUFFOBJ - 1; ++j) {
00102         _freeObject[threadId].push_back((void *)p);
00103         p += 1;
00104       }
00105 
00106       result = p;
00107     }
00108     else {
00109       result = (TYPE *)_freeObject[threadId].back();
00110       _freeObject[threadId].pop_back();
00111     }
00112 
00113     return result;
00114   }
00115 };
00116 
00117 template <typename  TYPE >
00118 std::vector<void * > MemoryPool<TYPE>::_freeObject[MAXNBTHREADS];
00119 
00120 }
00121 #endif // MEMORYPOOL_H
00122 ///@endcond
 All Classes Files Functions Variables Enumerations Enumerator Properties