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 45 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 49 of file Cached_Allocator_With_Overflow_T.h.

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

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 82 of file Cached_Allocator_With_Overflow_T.h.

00082                                     {
00083     ACE_Allocator::instance()->free(begin_);
00084   }


Member Function Documentation

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

How many chunks are available at this time.

Definition at line 211 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Cached_Allocator_With_Overflow< ACE_Message_Block, RECEIVE_SYNCH >::free(), and OpenDDS::DCPS::Cached_Allocator_With_Overflow< ACE_Message_Block, RECEIVE_SYNCH >::malloc().

00211                      {
00212     return free_list_.size();
00213   };

Here is the caller graph for this function:

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.

Reimplemented from ACE_New_Allocator.

Definition at line 149 of file Cached_Allocator_With_Overflow_T.h.

00151                                                         {
00152     ACE_NOTSUP_RETURN(0);
00153   }

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).

Reimplemented from ACE_New_Allocator.

Definition at line 142 of file Cached_Allocator_With_Overflow_T.h.

00143                                                         {
00144     ACE_NOTSUP_RETURN(0);
00145   }

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

Return a chunk of memory back to free list cache.

Reimplemented from ACE_New_Allocator.

Definition at line 156 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::TransportReceiveStrategy< TH, DSH >::handle_dds_input(), and OpenDDS::DCPS::WriteDataContainer::release_buffer().

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

Here is the caller graph for this function:

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

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).

Reimplemented from ACE_New_Allocator.

Definition at line 91 of file Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::TransportQueueElement::clone_mb(), OpenDDS::DCPS::WriteDataContainer::copy_and_prepend(), OpenDDS::DCPS::TransportReceiveStrategy< TH, DSH >::handle_dds_input(), OpenDDS::DCPS::WriteDataContainer::obtain_buffer(), and OpenDDS::DCPS::WriteDataContainer::obtain_buffer_for_control().

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

Here is the caller graph for this function:


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_
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_
template<class T, class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::begin_ [private]
template<class T, class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::end_ [private]
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]
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_
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_

The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1