diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 2002-03-28 16:24:13 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 2002-03-28 16:24:13 +0000 |
commit | 78545a25e4922ffd8c7ddffd2bf48bf47ec3201c (patch) | |
tree | f74ffe2acc4478c9dcb1711949abdbbf4d2fd197 /ace | |
parent | 2424a14c9adb1a8033b167817cba02035f361d37 (diff) | |
download | ATCD-78545a25e4922ffd8c7ddffd2bf48bf47ec3201c.tar.gz |
ChangeLogTag:Thu Mar 28 10:12:13 2002 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu>
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Malloc_T.cpp | 29 | ||||
-rw-r--r-- | ace/Malloc_T.h | 65 | ||||
-rw-r--r-- | ace/Malloc_T.i | 39 |
3 files changed, 133 insertions, 0 deletions
diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp index 74b97b3d4b1..a5ce3677ea1 100644 --- a/ace/Malloc_T.cpp +++ b/ace/Malloc_T.cpp @@ -41,6 +41,35 @@ ACE_Cached_Allocator<T, ACE_LOCK>::~ACE_Cached_Allocator (void) delete [] this->pool_; } +template <class ACE_LOCK> +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::ACE_Dynamic_Cached_Allocator + (size_t n_chunks, size_t chunk_size) + : pool_ (0), + free_list_ (ACE_PURE_FREE_LIST), + chunk_size_(chunk_size) +{ + ACE_NEW (this->pool_, char[n_chunks * chunk_size_]); + + for (size_t c = 0; + c < n_chunks; + c++) + { + void* placement = this->pool_ + c * chunk_size_; + + this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<char>); + } + // Put into free list using placement contructor, no real memory + // allocation in the above <new>. +} + +template <class ACE_LOCK> +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::~ACE_Dynamic_Cached_Allocator (void) +{ + delete [] this->pool_; + this->pool_ = 0; + chunk_size_ = 0; +} + ACE_ALLOC_HOOK_DEFINE (ACE_Malloc_T) template <class MALLOC> int diff --git a/ace/Malloc_T.h b/ace/Malloc_T.h index bc8c42cd66f..baade61c235 100644 --- a/ace/Malloc_T.h +++ b/ace/Malloc_T.h @@ -122,6 +122,71 @@ private: }; /** + * @class ACE_Dynamic_Cached_Allocator + * + * @brief Create a cached memory poll with <n_chunks> chunks each with + * requested size <chunk_size>. + * + * This class enables caching of dynamically allocated, + * chunks with size <chunk_size>. Notice that the <code>chunk_size</code> + * must be greater than or equal to <code> sizeof (void*) </code> for + * this to work properly. + * + * @sa ACE_Cached_Mem_Pool_Node + */ +template <class ACE_LOCK> +class ACE_Dynamic_Cached_Allocator : public ACE_New_Allocator +{ +public: + /// Create a cached memory poll with <n_chunks> chunks + /// each with <chunk_size> size. + ACE_Dynamic_Cached_Allocator (size_t n_chunks, size_t chunk_size); + + /// clear things up. + ~ACE_Dynamic_Cached_Allocator (void); + + /** + * Get a chunk of memory from free list cache. Note that <nbytes> is + * only checked to make sure that it's <= to <chunk_size>, and is + * otherwise ignored since <malloc> always returns a pointer to an + * item of <chunk_size> size. + */ + void *malloc (size_t nbytes = 0); + + /** + * 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 <= to <chunk_size>, and is otherwise ignored since <malloc> + * always returns a pointer to an item of <chunk_size>. + */ + virtual void *calloc (size_t nbytes, + char initial_value = '\0'); + + /// This method is a no-op and just returns 0 since the free list + /// only works with fixed sized entities. + virtual void *calloc (size_t n_elem, + size_t elem_size, + char initial_value = '\0'); + + /// Return a chunk of memory back to free list cache. + void free (void *); + +private: + /// Remember how we allocate the memory in the first place so + /// we can clear things up later. + char *pool_; + + /// 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 >= sizeof(void*). + ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> free_list_; + + /// Remember the size of our chunks. + size_t chunk_size_; +}; + +/** * @class ACE_Allocator_Adapter * * @brief This class is an Adapter that allows the <ACE_Allocator> to diff --git a/ace/Malloc_T.i b/ace/Malloc_T.i index 27e5f7ae4f8..7aed626b567 100644 --- a/ace/Malloc_T.i +++ b/ace/Malloc_T.i @@ -65,6 +65,45 @@ ACE_Cached_Allocator<T, ACE_LOCK>::free (void * ptr) this->free_list_.add ((ACE_Cached_Mem_Pool_Node<T> *) ptr) ; } +template <class ACE_LOCK> ACE_INLINE void * +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::malloc (size_t nbytes) +{ + // Check if size requested fits within pre-determined size. + if (nbytes > chunk_size_) + return 0; + + // addr() call is really not absolutely necessary because of the way + // ACE_Cached_Mem_Pool_Node's internal structure arranged. + return this->free_list_.remove ()->addr (); +} + +template <class ACE_LOCK> ACE_INLINE void * +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t nbytes, + char initial_value) +{ + // Check if size requested fits within pre-determined size. + if (nbytes > chunk_size_) + return 0; + + // addr() call is really not absolutely necessary because of the way + // ACE_Cached_Mem_Pool_Node's internal structure arranged. + void *ptr = this->free_list_.remove ()->addr (); + ACE_OS::memset (ptr, initial_value, chunk_size_); + return ptr; +} + +template <class ACE_LOCK> ACE_INLINE void * +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t, size_t, char) +{ + ACE_NOTSUP_RETURN (0); +} + +template <class ACE_LOCK> ACE_INLINE void +ACE_Dynamic_Cached_Allocator<ACE_LOCK>::free (void * ptr) +{ + this->free_list_.add ((ACE_Cached_Mem_Pool_Node<char> *) ptr); +} + template <class MALLOC> ACE_INLINE void * ACE_Allocator_Adapter<MALLOC>::malloc (size_t nbytes) { |