summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>2002-03-28 16:24:13 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>2002-03-28 16:24:13 +0000
commit78545a25e4922ffd8c7ddffd2bf48bf47ec3201c (patch)
treef74ffe2acc4478c9dcb1711949abdbbf4d2fd197 /ace
parent2424a14c9adb1a8033b167817cba02035f361d37 (diff)
downloadATCD-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.cpp29
-rw-r--r--ace/Malloc_T.h65
-rw-r--r--ace/Malloc_T.i39
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)
{