Disk ARchive  2.5.2
Full featured and portable backup and archiving tool
on_pool.hpp
Go to the documentation of this file.
00001 /*********************************************************************/
00002 // dar - disk archive - a backup/restoration program
00003 // Copyright (C) 2002-2052 Denis Corbin
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // to contact the author : http://dar.linux.free.fr/email.html
00020 /*********************************************************************/
00021 
00025 
00026 
00027 
00028 #ifndef ON_POOL_HPP
00029 #define ON_POOL_HPP
00030 
00031 #include "../my_config.h"
00032 #include <vector>
00033 #include <new>
00034 #include "integers.hpp"
00035 #include "memory_pool.hpp"
00036 #include "mem_allocator.hpp"
00037 #include "cygwin_adapt.hpp"
00038 
00039 
00040 namespace libdar
00041 {
00042 
00043 
00046 
00051 
00052     class on_pool
00053     {
00054     public:
00055 #ifdef LIBDAR_SPECIAL_ALLOC
00056 
00063     on_pool() { dynamic_init(); };
00064 
00069     on_pool(const on_pool & ref) { dynamic_init(); };
00070 
00075     const on_pool & operator = (const on_pool & ref) { return *this; };
00076 
00078     virtual ~on_pool() throw(Ebug) {};
00079 #endif
00080 
00084     void *operator new(size_t n_byte) { void *ret = alloc(n_byte, nullptr); if(ret == nullptr) throw std::bad_alloc(); return ret; };
00085 
00086 
00090     void *operator new(size_t n_byte, const std::nothrow_t & nothrow_value) { return alloc(n_byte, nullptr); };
00091 
00092 
00096     void *operator new[](size_t n_byte) { void *ret = alloc(n_byte, nullptr); if(ret == nullptr) throw std::bad_alloc(); return ret; };
00097 
00098 
00102     void *operator new[](size_t n_byte, const std::nothrow_t & nothrow_value) { return alloc(n_byte, nullptr); };
00103 
00108     void *operator new(size_t n_byte, memory_pool *p) { return alloc(n_byte, p); };
00109 
00110 
00115     void *operator new[] (size_t n_byte, memory_pool *p) { return alloc(n_byte, p); };
00116 
00117 
00119     void operator delete(void *ptr, memory_pool *p) { dealloc(ptr); };
00120 
00121 
00123     void operator delete[](void *ptr, memory_pool *p) { dealloc(ptr); };
00124 
00125 
00127     void operator delete(void *ptr) { dealloc(ptr); };
00128 
00129 
00131     void operator delete[](void *ptr) { dealloc(ptr); };
00132 
00133     protected:
00141 #ifdef LIBDAR_SPECIAL_ALLOC
00142     memory_pool *get_pool() const { return dynamic ? (((pool_ptr *)this) - 1)->reserve : nullptr; };
00143 #else
00144     memory_pool *get_pool() const { return nullptr; };
00145 #endif
00146 
00147     template <class T> void meta_new(T * & ptr, size_t num)
00148     {
00149 #ifdef LIBDAR_SPECIAL_ALLOC
00150         size_t byte = num * sizeof(T);
00151 
00152         if(get_pool() != nullptr)
00153         ptr = (T *)get_pool()->alloc(byte);
00154         else
00155         ptr = (T *)new (std::nothrow) char [byte];
00156 #else
00157         ptr = new (std::nothrow) T[num];
00158 #endif
00159     }
00160 
00161 
00162 
00163     template <class T> void meta_delete(T * ptr)
00164     {
00165 #ifdef LIBDAR_SPECIAL_ALLOC
00166         if(get_pool() != nullptr)
00167         get_pool()->release(ptr);
00168         else
00169         delete [] (char *)(ptr);
00170 #else
00171         delete [] ptr;
00172 #endif
00173     }
00174 
00175     private:
00176 #ifdef LIBDAR_SPECIAL_ALLOC
00177 
00182     union pool_ptr
00183     {
00184         memory_pool *reserve; //< this is to be able to pass the pool object to the constructor if it requires dynamic memory allocation
00185         U_I  alignment__i; //< to properly align the allocated memory block that follows
00186         U_32 alignment_32; //< to properly align the allocated memory block that follows
00187         U_64 alignment_64; //< to properly align the allocated memory block that follows
00188     };
00189 
00190         // this field is necessary to make distinction between object on the heap that have a pool_ptr header from those
00191         // created as local or temporary variable (on the stack).
00192     bool dynamic;
00193 
00195     void dynamic_init() const { const_cast<on_pool *>(this)->dynamic = (alloc_not_constructed == this); alloc_not_constructed = nullptr; };
00196 #endif
00197 
00203     static void *alloc(size_t size, memory_pool *p);
00204 
00209     static void dealloc(void *ptr);
00210 
00211 #ifdef LIBDAR_SPECIAL_ALLOC
00212 #ifdef CYGWIN_BUILD
00213     static on_pool *alloc_not_constructed;
00214         // under cygwin the thread_local directive does not work but
00215         // as we build only command-line tools that are single threaded
00216         // program, it does not hurt using global static field here
00217         // well, as soon as another application than dar/dar_xform/...
00218         // relies on a cygwin build of libdar, this trick should be changed
00219 #else
00220     thread_local static on_pool * alloc_not_constructed;
00221 #endif
00222 #endif
00223     };
00224 
00226 
00227 } // end of namespace
00228 
00229 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines