#include <Cached_Allocator_With_Overflow_T.h>
Inheritance diagram for OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >:
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. |
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.
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 }
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 }
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 };
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.
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.
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 }
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 }
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::allocs_from_heap_ |
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::allocs_from_pool_ |
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().
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().
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().
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::frees_to_heap_ |
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> OpenDDS::DCPS::Cached_Allocator_With_Overflow< T, ACE_LOCK >::frees_to_pool_ |