00001
00002
00003
00004
00005
00006
00007
00008 #ifndef OPENDDS_DCPS_BASICQUEUELINKALLOCATOR_T_H
00009 #define OPENDDS_DCPS_BASICQUEUELINKALLOCATOR_T_H
00010
00011 #include "BasicQueueLink_T.h"
00012 #include "BasicQueueLinkChunk_T.h"
00013 #include "ace/Malloc_T.h"
00014 #include "ace/Null_Mutex.h"
00015 #include "dds/DCPS/PoolAllocationBase.h"
00016
00017 namespace OpenDDS {
00018 namespace DCPS {
00019
00020 template <typename T>
00021 class BasicQueueLinkAllocator : public ACE_New_Allocator, public PoolAllocationBase {
00022 private:
00023
00024 typedef BasicQueueLink<T> LinkType;
00025 typedef BasicQueueLinkChunk<T> ChunkType;
00026 typedef ACE_Cached_Mem_Pool_Node<LinkType > NodeType;
00027 typedef ACE_Locked_Free_List<NodeType, ACE_Null_Mutex> FreeListType;
00028
00029 public:
00030
00031
00032 BasicQueueLinkAllocator(size_t chunk_size, size_t initial_chunks)
00033 : chunk_size_(chunk_size),
00034 head_chunk_(0),
00035 tail_chunk_(0),
00036 free_list_(ACE_PURE_FREE_LIST) {
00037 for (size_t i = 0; i < initial_chunks; i++) {
00038 this->grow();
00039 }
00040 }
00041
00042
00043 virtual ~BasicQueueLinkAllocator() {
00044 ChunkType* chunk = this->head_chunk_;
00045
00046 while (chunk != 0) {
00047 ChunkType* next_chunk = chunk->next_;
00048 delete chunk;
00049 chunk = next_chunk;
00050 }
00051 }
00052
00053
00054 void* malloc(size_t nbytes = sizeof(LinkType)) {
00055
00056 if (nbytes != sizeof(LinkType)) {
00057 return 0;
00058 }
00059
00060
00061
00062
00063 void* ptr = this->free_list_.remove()->addr();
00064
00065 if (ptr == 0) {
00066 this->grow();
00067 ptr = this->free_list_.remove()->addr();
00068 }
00069
00070 return ptr;
00071 }
00072
00073
00074 virtual void* calloc(size_t nbytes = sizeof(LinkType),
00075 char initial_value = '\0') {
00076
00077 if (nbytes != sizeof(LinkType)) {
00078 return 0;
00079 }
00080
00081
00082
00083
00084 void* ptr = this->free_list_.remove()->addr();
00085
00086 if (ptr == 0) {
00087 this->grow();
00088 ptr = this->free_list_.remove()->addr();
00089 }
00090
00091 ACE_OS::memset(ptr, initial_value, sizeof(LinkType));
00092
00093 return ptr;
00094 }
00095
00096
00097 virtual void* calloc(size_t n_elem,
00098 size_t elem_size,
00099 char initial_value = '\0') {
00100 ACE_UNUSED_ARG(n_elem);
00101 ACE_UNUSED_ARG(elem_size);
00102 ACE_UNUSED_ARG(initial_value);
00103 ACE_NOTSUP_RETURN(0);
00104 }
00105
00106
00107 void free(void* ptr) {
00108 this->free_list_.add((NodeType*)ptr);
00109 }
00110
00111 private:
00112
00113
00114 void grow() {
00115 ChunkType* chunk;
00116 ACE_NEW(chunk, ChunkType(this->chunk_size_));
00117
00118 for (size_t i = 0; i < this->chunk_size_; ++i) {
00119 void* placement = &(chunk->links_[i]);
00120 this->free_list_.add(new(placement) NodeType);
00121 }
00122
00123
00124 if (head_chunk_ == 0) {
00125 this->head_chunk_ = this->tail_chunk_ = chunk;
00126
00127 } else {
00128 this->tail_chunk_->next_ = chunk;
00129 this->tail_chunk_ = chunk;
00130 }
00131 }
00132
00133
00134 size_t chunk_size_;
00135
00136
00137 ChunkType* head_chunk_;
00138
00139
00140 ChunkType* tail_chunk_;
00141
00142
00143 FreeListType free_list_;
00144 };
00145
00146 }
00147 }
00148
00149 #endif