OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK > Class Template Reference

A fixed-size allocator that caches items for quicker access but if the pool is exhausted it will use the heap. More...

#include <Cached_Allocator_With_Overflow_T.h>

Inheritance diagram for OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >:

Inheritance graph
[legend]
Collaboration diagram for OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 Cached_Allocator_With_Overflow (size_t n_chunks)
 ~Cached_Allocator_With_Overflow ()
 Clear things up.
void * malloc (size_t nbytes=sizeof(T))
virtual void * calloc (size_t, char= '\0')
virtual void * calloc (size_t, size_t, char= '\0')
void free (void *ptr)
 Return a chunk of memory back to free list cache.
size_t available ()

Public Attributes

ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
allocs_from_heap_
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
allocs_from_pool_
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
frees_to_heap_
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
frees_to_pool_

Private Attributes

unsigned char * begin_
unsigned char * end_
 The end of the pool.
ACE_Locked_Free_List< ACE_Cached_Mem_Pool_Node<
T >, ACE_LOCK > 
free_list_
 Maintain a cached memory free list.

Detailed Description

template<class T, class ACE_LOCK>
class OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >

A fixed-size allocator that caches items for quicker access but if the pool is exhausted it will use the heap.

This class enables caching of dynamically allocated, fixed-sized classes. Notice that the sizeof (TYPE) must be greater than or equal to sizeof (void*) for this to work properly. If the free list is empty then memory is allocated from the heap. This way the allocations will not fail but may be slower.

Definition at line 43 of file Cached_Allocator_With_Overflow_T.h.


Constructor & Destructor Documentation

template<class T, class ACE_LOCK>
OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::Cached_Allocator_With_Overflow ( size_t  n_chunks  )  [inline]

Create a cached memory pool with n_chunks chunks each with sizeof (TYPE) size.

Definition at line 47 of file Cached_Allocator_With_Overflow_T.h.

00048     : allocs_from_heap_(0),
00049       allocs_from_pool_(0),
00050       frees_to_heap_(0),
00051       frees_to_pool_(0),
00052       free_list_(ACE_PURE_FREE_LIST) {
00053     // To maintain alignment requirements, make sure that each element
00054     // inserted into the free list is aligned properly for the platform.
00055     // Since the memory is allocated as a char[], the compiler won't help.
00056     // To make sure enough room is allocated, round up the size so that
00057     // each element starts aligned.
00058     //
00059     // NOTE - this would probably be easier by defining begin_ as a pointer
00060     // to T and allocating an array of them (the compiler would probably
00061     // take care of the alignment for us), but then the ACE_NEW below would
00062     // require a default constructor on T - a requirement that is not in
00063     // previous versions of ACE
00064     size_t chunk_size = sizeof(T);
00065     chunk_size = ACE_MALLOC_ROUNDUP(chunk_size, ACE_MALLOC_ALIGN);
00066     begin_ = static_cast<unsigned char*> (ACE_Allocator::instance()->malloc(n_chunks * chunk_size));
00067 
00068     // Remember end of the pool.
00069     end_ = begin_ + n_chunks * chunk_size;
00070 
00071     // Put into free list using placement contructor, no real memory
00072     // allocation in the <new> below.
00073     for (size_t c = 0; c < n_chunks; c++) {
00074       void* placement = begin_ + c * chunk_size;
00075       this->free_list_.add(new(placement) ACE_Cached_Mem_Pool_Node<T>);
00076     }
00077   }

template<class T, class ACE_LOCK>
OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::~Cached_Allocator_With_Overflow (  )  [inline]

Clear things up.

Definition at line 80 of file Cached_Allocator_With_Overflow_T.h.

00080                                     {
00081     ACE_Allocator::instance()->free(begin_);
00082   }


Member Function Documentation

template<class T, class ACE_LOCK>
size_t OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::available (  )  [inline]

How many chunks are available at this time.

Definition at line 209 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().

00209                      {
00210     return free_list_.size();
00211   };

template<class T, class ACE_LOCK>
virtual void* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::calloc ( size_t  ,
size_t  ,
char  = '\0' 
) [inline, virtual]

This method is a no-op and just returns 0 since the free list only works with fixed sized entities.

Definition at line 147 of file Cached_Allocator_With_Overflow_T.h.

00149                                                         {
00150     ACE_NOTSUP_RETURN(0);
00151   }

template<class T, class ACE_LOCK>
virtual void* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::calloc ( size_t  ,
char  = '\0' 
) [inline, virtual]

Get a chunk of memory from free list cache, giving them initial_value. Note that nbytes is only checked to make sure that it's less or equal to sizeof T, and is otherwise ignored since calloc() always returns a pointer to an item of sizeof (T).

Definition at line 140 of file Cached_Allocator_With_Overflow_T.h.

00141                                                         {
00142     ACE_NOTSUP_RETURN(0);
00143   }

template<class T, class ACE_LOCK>
void OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::free ( void *  ptr  )  [inline]

Return a chunk of memory back to free list cache.

Definition at line 154 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::WriteDataContainer::release_buffer(), OpenDDS::DCPS::TransportSendControlElement::release_element(), OpenDDS::DCPS::TransportRetainedElement::release_element(), and OpenDDS::DCPS::TransportReplacedElement::release_element().

00154                         {
00155     unsigned char* tmp = static_cast<unsigned char*>(ptr);
00156     if (tmp < begin_ ||
00157         tmp >= end_) {
00158       ACE_Allocator::instance()->free(tmp);
00159       frees_to_heap_++;
00160 
00161       if (frees_to_heap_ > allocs_from_heap_.value()) {
00162         ACE_ERROR((LM_ERROR,
00163                    "(%P|%t) ERROR:Cached_Allocator_With_Overflow::free %@"
00164                    " more deletes %Lu than allocs %Lu to the heap\n",
00165                    this,
00166                    this->frees_to_heap_.value(),
00167                    this->allocs_from_heap_.value()));
00168       }
00169 
00170       if (DCPS_debug_level >= 6) {
00171         if (frees_to_heap_.value() % 500 == 0) {
00172           ACE_DEBUG((LM_DEBUG,
00173                      "(%P|%t) Cached_Allocator_With_Overflow::free %@"
00174                      " %Lu heap allocs with %Lu outstanding\n",
00175                      this, this->allocs_from_heap_.value(),
00176                      this->allocs_from_heap_.value() - this->frees_to_heap_.value()));
00177         }
00178       }
00179 
00180     } else if (ptr != 0) {
00181       frees_to_pool_ ++;
00182 
00183       if (frees_to_pool_ > allocs_from_pool_.value()) {
00184         ACE_ERROR((LM_ERROR,
00185                    "(%P|%t) ERROR: Cached_Allocator_With_Overflow::free %@"
00186                    " more deletes %Lu than allocs %Lu from the pool ptr=%@ begin_=%@ end_=%@\n",
00187                    this,
00188                    this->frees_to_pool_.value(),
00189                    this->allocs_from_pool_.value(), ptr, begin_, end_));
00190       }
00191 
00192       this->free_list_.add((ACE_Cached_Mem_Pool_Node<T> *) ptr) ;
00193 
00194       if (DCPS_debug_level >= 6)
00195         if (this->available() % 500 == 0)
00196           ACE_DEBUG((LM_DEBUG,
00197                      "(%P|%t) Cached_Allocator_With_Overflow::malloc %@"
00198                      " %Lu pool allocs %Lu pool free with %Lu available\n",
00199                      this, this->allocs_from_pool_.value(),
00200                      this->frees_to_pool_.value(),
00201                      this->available()));
00202     }
00203   }

template<class T, class ACE_LOCK>
void* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::malloc ( size_t  nbytes = sizeof(T)  )  [inline]

Get a chunk of memory from free list cache. Note that nbytes is only checked to make sure that it's less or equal to sizeof T, and is otherwise ignored since malloc() always returns a pointer to an item of sizeof (T).

Definition at line 89 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::TransportSendControlElement::alloc(), OpenDDS::DCPS::TransportQueueElement::clone_mb(), OpenDDS::DCPS::WriteDataContainer::copy_and_append(), OpenDDS::DCPS::DataWriterImpl::create_control_message(), OpenDDS::DCPS::DataWriterImpl::create_sample_data_message(), OpenDDS::DCPS::WriteDataContainer::obtain_buffer(), OpenDDS::DCPS::WriteDataContainer::obtain_buffer_for_control(), and OpenDDS::DCPS::CopyChainVisitor::visit_element().

00089                                           {
00090     // Check if size requested fits within pre-determined size.
00091     if (nbytes > sizeof(T))
00092       return 0;
00093 
00094     // addr() call is really not absolutely necessary because of the way
00095     // ACE_Cached_Mem_Pool_Node's internal structure arranged.
00096     void* rtn =  this->free_list_.remove()->addr();
00097 
00098     if (0 == rtn) {
00099       rtn = ACE_Allocator::instance()->malloc(sizeof(T));
00100       allocs_from_heap_++;
00101 
00102       if (DCPS_debug_level >= 2) {
00103         if (allocs_from_heap_ == 1 && DCPS_debug_level >= 2)
00104           ACE_DEBUG((LM_DEBUG,
00105                      "(%P|%t) Cached_Allocator_With_Overflow::malloc %@"
00106                      " %Lu heap allocs with %Lu outstanding\n",
00107                      this, this->allocs_from_heap_.value(),
00108                      this->allocs_from_heap_.value() - this->frees_to_heap_.value()));
00109 
00110         if (DCPS_debug_level >= 6)
00111           if (allocs_from_heap_.value() % 500 == 0)
00112             ACE_DEBUG((LM_DEBUG,
00113                        "(%P|%t) Cached_Allocator_With_Overflow::malloc %@"
00114                        " %Lu heap allocs with %Lu outstanding\n",
00115                        this, this->allocs_from_heap_.value(),
00116                        this->allocs_from_heap_.value() - this->frees_to_heap_.value()));
00117       }
00118 
00119     } else {
00120       allocs_from_pool_++;
00121 
00122       if (DCPS_debug_level >= 6)
00123         if (allocs_from_pool_.value() % 500 == 0)
00124           ACE_DEBUG((LM_DEBUG,
00125                      "(%P|%t) Cached_Allocator_With_Overflow::malloc %@"
00126                      " %Lu pool allocs %Lu pool frees with %Lu available\n",
00127                      this, this->allocs_from_pool_.value(), this->frees_to_pool_.value(),
00128                      this->available()));
00129     }
00130 
00131     return rtn;
00132   }


Member Data Documentation

template<class T, class ACE_LOCK>
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::allocs_from_heap_

Definition at line 211 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().

template<class T, class ACE_LOCK>
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::allocs_from_pool_

Definition at line 214 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().

template<class T, class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::begin_ [private]

Remember how we allocate the memory in the first place so we can clear things up later.

Definition at line 221 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::Cached_Allocator_With_Overflow(), OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::~Cached_Allocator_With_Overflow().

template<class T, class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::end_ [private]

The end of the pool.

Definition at line 223 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::Cached_Allocator_With_Overflow(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free().

template<class T, class ACE_LOCK>
ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<T>, ACE_LOCK> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::free_list_ [private]

Maintain a cached memory free list.

Definition at line 226 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::available(), OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::Cached_Allocator_With_Overflow(), OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().

template<class T, class ACE_LOCK>
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::frees_to_heap_

Definition at line 215 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().

template<class T, class ACE_LOCK>
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::frees_to_pool_

Definition at line 216 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex >::malloc().


The documentation for this class was generated from the following file:
Generated on Fri Feb 12 20:06:10 2016 for OpenDDS by  doxygen 1.4.7