OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK > Class Template Reference

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

#include <Dynamic_Cached_Allocator_With_Overflow_T.h>

Inheritance diagram for OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >:

Inheritance graph
[legend]
Collaboration diagram for OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 Dynamic_Cached_Allocator_With_Overflow (size_t n_chunks, size_t chunk_size)
 ~Dynamic_Cached_Allocator_With_Overflow ()
 Clear things up.
void * malloc (size_t nbytes=0)
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 pool_depth ()
 Return the number of chunks available in the cache.
size_t available ()

Public Attributes

ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
allocs_from_heap_
 number of allocations from the heap.
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
allocs_from_pool_
 number of allocations from the pool.
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
frees_to_heap_
 number of frees returned to the heap
ACE_Atomic_Op< ACE_Thread_Mutex,
unsigned long > 
frees_to_pool_
 number of frees returned to the pool

Private Attributes

unsigned char * begin_
unsigned char * end_
 The end of the pool.
ACE_Locked_Free_List< ACE_Cached_Mem_Pool_Node<
char >, ACE_LOCK > 
free_list_
size_t chunk_size_
 Remember the size of our chunks.

Detailed Description

template<class ACE_LOCK>
class OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >

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

This class enables caching of dynamically allocated, fixed-size chunks. Notice that the chunk_size must be greater than or equal to sizeof (void*) for this to work properly.

This class can be configured flexibly with different types of ACE_LOCK strategies that support the ACE_Thread_Mutex and ACE_Process_Mutex constructor API.

Definition at line 42 of file Dynamic_Cached_Allocator_With_Overflow_T.h.


Constructor & Destructor Documentation

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

Create a cached memory pool with n_chunks chunks each with chunk_size size.

Definition at line 46 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

00047   : allocs_from_heap_(0),
00048     allocs_from_pool_(0),
00049     frees_to_heap_(0),
00050     frees_to_pool_(0),
00051     free_list_(ACE_PURE_FREE_LIST)
00052   {
00053     chunk_size_ = ACE_MALLOC_ROUNDUP(chunk_size, ACE_MALLOC_ALIGN);
00054     begin_ = static_cast<unsigned char*> (ACE_Allocator::instance()->malloc(n_chunks * chunk_size_));
00055     // Remember end of the pool.
00056     end_ = begin_ + n_chunks * chunk_size_;
00057 
00058     // Put into free list using placement contructor, no real memory
00059     // allocation in the <new> below.
00060     for (size_t c = 0;
00061          c < n_chunks;
00062          c++) {
00063       void* placement = begin_ + c * chunk_size_;
00064 
00065       this->free_list_.add(new(placement) ACE_Cached_Mem_Pool_Node<char>);
00066     }
00067   }

template<class ACE_LOCK>
OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::~Dynamic_Cached_Allocator_With_Overflow (  )  [inline]

Clear things up.

Definition at line 70 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

00070                                             {
00071     ACE_Allocator::instance()->free(begin_);
00072     begin_ = 0;
00073     chunk_size_ = 0;
00074   }


Member Function Documentation

template<class ACE_LOCK>
size_t OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::available (  )  [inline]

How many chunks are available at this time.

Definition at line 209 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc().

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

template<class ACE_LOCK>
virtual void* OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< 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 141 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

00143                                                         {
00144     ACE_NOTSUP_RETURN(0);
00145   }

template<class ACE_LOCK>
virtual void* OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< 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 chunk_size, and is otherwise ignored since calloc() always returns a pointer to an item of chunk_size.

Definition at line 134 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

00135                                                         {
00136     ACE_NOTSUP_RETURN(0);
00137   }

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

Return a chunk of memory back to free list cache.

Definition at line 148 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::TransportSendElement::release_element().

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

template<class ACE_LOCK>
void* OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::malloc ( size_t  nbytes = 0  )  [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 chunk_size, and is otherwise ignored since malloc() always returns a pointer to an item of chunk_size size.

Definition at line 82 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::TransportSendElement::alloc().

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

template<class ACE_LOCK>
size_t OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::pool_depth (  )  [inline]

Return the number of chunks available in the cache.

Definition at line 201 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

00201                       {
00202     return this->free_list_.size() ;
00203   }


Member Data Documentation

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

number of allocations from the heap.

Definition at line 211 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc().

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

number of allocations from the pool.

Definition at line 216 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc().

template<class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::begin_ [private]

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

Definition at line 224 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::Dynamic_Cached_Allocator_With_Overflow(), OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::~Dynamic_Cached_Allocator_With_Overflow().

template<class ACE_LOCK>
size_t OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::chunk_size_ [private]

Remember the size of our chunks.

Definition at line 235 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::Dynamic_Cached_Allocator_With_Overflow(), OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::~Dynamic_Cached_Allocator_With_Overflow().

template<class ACE_LOCK>
unsigned char* OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::end_ [private]

The end of the pool.

Definition at line 226 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::Dynamic_Cached_Allocator_With_Overflow(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free().

template<class ACE_LOCK>
ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_LOCK >::free_list_ [private]

Maintain a cached memory free list. We use char as template parameter, although sizeof(char) is usually less than sizeof(void*). Really important is that chunk_size must be greater or equal to sizeof(void*).

Definition at line 232 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::available(), OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::Dynamic_Cached_Allocator_With_Overflow(), OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::pool_depth().

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

number of frees returned to the heap

Definition at line 218 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc().

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

number of frees returned to the pool

Definition at line 220 of file Dynamic_Cached_Allocator_With_Overflow_T.h.

Referenced by OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::free(), and OpenDDS::DCPS::Dynamic_Cached_Allocator_With_Overflow< ACE_Thread_Mutex >::malloc().


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