• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Allocator.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   Fast-Allocators
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022 
00023   Provides three classes
00024     - Allocator for allocating memory blocks of fixed size
00025     - ClassAllocator for allocating objects
00026     - SpaceClassAllocator for allocating sparce objects (most members uninitialized)
00027 
00028   These class provides a efficient way for handling dynamic allocation.
00029   The fast allocator maintains its own freepool of objects from
00030   which it doles out object. Allocated objects when freed go back
00031   to the free pool.
00032 
00033   @note Fast allocators could accumulate a lot of objects in the
00034   free pool as a result of bursty demand. Memory used by the objects
00035   in the free pool never gets freed even if the freelist grows very
00036   large.
00037 
00038  */
00039 
00040 #ifndef _Allocator_h_
00041 #define _Allocator_h_
00042 
00043 #include <stdlib.h>
00044 #include "ink_queue.h"
00045 #include "ink_defs.h"
00046 #include "ink_resource.h"
00047 
00048 #define RND16(_x)               (((_x)+15)&~15)
00049 
00050 /** Allocator for fixed size memory blocks. */
00051 class Allocator
00052 {
00053 public:
00054   /**
00055     Allocate a block of memory (size specified during construction
00056     of Allocator.
00057   */
00058   void *
00059   alloc_void()
00060   {
00061     return ink_freelist_new(this->fl);
00062   }
00063 
00064   /** Deallocate a block of memory allocated by the Allocator. */
00065   void
00066   free_void(void *ptr)
00067   {
00068     ink_freelist_free(this->fl, ptr);
00069   }
00070 
00071   Allocator()
00072   {
00073     fl = NULL;
00074   }
00075 
00076   /**
00077     Creates a new allocator.
00078 
00079     @param name identification tag used for mem tracking .
00080     @param element_size size of memory blocks to be allocated.
00081     @param chunk_size number of units to be allocated if free pool is empty.
00082     @param alignment of objects must be a power of 2.
00083   */
00084   Allocator(const char *name, unsigned int element_size,
00085             unsigned int chunk_size = 128, unsigned int alignment = 8)
00086   {
00087     ink_freelist_init(&fl, name, element_size, chunk_size, alignment);
00088   }
00089 
00090   /** Re-initialize the parameters of the allocator. */
00091   void
00092   re_init(const char *name, unsigned int element_size,
00093           unsigned int chunk_size, unsigned int alignment)
00094   {
00095     ink_freelist_init(&this->fl, name, element_size, chunk_size, alignment);
00096   }
00097 
00098 protected:
00099   InkFreeList *fl;
00100 };
00101 
00102 /**
00103   Allocator for Class objects. It uses a prototype object to do
00104   fast initialization. Prototype of the template class is created
00105   when the fast allocator is created. This is instantiated with
00106   default (no argument) constructor. Constructor is not called for
00107   the allocated objects. Instead, the prototype is just memory
00108   copied onto the new objects. This is done for performance reasons.
00109 
00110 */
00111 template<class C> class ClassAllocator: public Allocator {
00112 public:
00113   /** Allocates objects of the templated type. */
00114   C*
00115   alloc()
00116   {
00117     void *ptr = ink_freelist_new(this->fl);
00118 
00119     memcpy(ptr, (void *)&this->proto.typeObject, sizeof(C));
00120     return (C *) ptr;
00121   }
00122 
00123   /**
00124     Deallocates objects of the templated type.
00125 
00126     @param ptr pointer to be freed.
00127   */
00128   void
00129   free(C * ptr)
00130   {
00131     ink_freelist_free(this->fl, ptr);
00132   }
00133 
00134   /**
00135     Allocate objects of the templated type via the inherited interface
00136     using void pointers.
00137   */
00138   void*
00139   alloc_void()
00140   {
00141     return (void *) alloc();
00142   }
00143 
00144   /**
00145     Deallocate objects of the templated type via the inherited
00146     interface using void pointers.
00147 
00148     @param ptr pointer to be freed.
00149   */
00150   void
00151   free_void(void *ptr)
00152   {
00153     free((C *) ptr);
00154   }
00155 
00156   /**
00157     Create a new class specific ClassAllocator.
00158 
00159     @param name some identifying name, used for mem tracking purposes.
00160     @param chunk_size number of units to be allocated if free pool is empty.
00161     @param alignment of objects must be a power of 2.
00162   */
00163   ClassAllocator(const char *name, unsigned int chunk_size = 128,
00164                  unsigned int alignment = 16)
00165   {
00166     ink_freelist_init(&this->fl, name, RND16(sizeof(C)), chunk_size, RND16(alignment));
00167   }
00168 
00169   struct
00170   {
00171     C typeObject;
00172     int64_t space_holder;
00173   } proto;
00174 };
00175 
00176 /**
00177   Allocator for space class, a class with a lot of uninitialized
00178   space/members. It uses an instantiate fucntion do initialization
00179   of objects. This is particulary useful if most of the space in
00180   the objects does not need to be intialized. The inifunction passed
00181   can be used to intialize a few fields selectively. Using
00182   ClassAllocator for space objects would unnecessarily initialized
00183   all of the members.
00184 
00185 */
00186 template<class C> class SparseClassAllocator:public ClassAllocator<C> {
00187 public:
00188 
00189   /** Allocates objects of the templated type. */
00190   C*
00191   alloc()
00192   {
00193     void *ptr = ink_freelist_new(this->fl);
00194 
00195     if (!_instantiate) {
00196       memcpy(ptr, (void *)&this->proto.typeObject, sizeof(C));
00197     } else
00198       (*_instantiate) ((C *) &this->proto.typeObject, (C *) ptr);
00199     return (C *) ptr;
00200   }
00201 
00202 
00203   /**
00204     Create a new class specific SparseClassAllocator.
00205 
00206     @param name some identifying name, used for mem tracking purposes.
00207     @param chunk_size number of units to be allocated if free pool is empty.
00208     @param alignment of objects must be a power of 2.
00209     @param instantiate_func
00210 
00211   */
00212   SparseClassAllocator(const char *name, unsigned int chunk_size = 128,
00213                        unsigned int alignment = 16,
00214                        void (*instantiate_func) (C * proto, C * instance) = NULL)
00215     : ClassAllocator<C>(name, chunk_size, alignment)
00216   {
00217     _instantiate = instantiate_func;       // NULL by default
00218   }
00219 
00220 private:
00221   void (*_instantiate) (C* proto, C* instance);
00222 };
00223 
00224 #endif  // _Allocator_h_

Generated by  doxygen 1.7.1