00001
00002
00003
00004
00005
00006
00007
00008 #ifndef OPENDDS_MEMORY_POOL_H
00009 #define OPENDDS_MEMORY_POOL_H
00010
00011 #include "dcps_export.h"
00012
00013 class MemoryPoolTest;
00014 class FreeIndexTest;
00015
00016 namespace OpenDDS {
00017 namespace DCPS {
00018
00019
00020
00021 class OpenDDS_Dcps_Export AllocHeader {
00022 public:
00023
00024 AllocHeader();
00025
00026
00027 unsigned int size() const { return is_free() ? -alloc_size_ : alloc_size_; }
00028
00029 unsigned int prev_size() const { return prev_size_; }
00030
00031 bool is_free() const { return alloc_size_ < 0; }
00032
00033
00034 unsigned char* ptr() const;
00035
00036
00037 AllocHeader* next_adjacent();
00038
00039
00040 AllocHeader* prev_adjacent();
00041
00042
00043 void allocate(size_t size);
00044
00045
00046 void set_size(size_t size);
00047
00048 void set_prev_size(int size) { prev_size_ = size; }
00049
00050 void set_allocated() { if (alloc_size_ < 0) alloc_size_ = - alloc_size_; }
00051
00052
00053 void join_next();
00054
00055 protected:
00056
00057 int alloc_size_;
00058 int prev_size_;
00059 };
00060
00061
00062
00063
00064 class OpenDDS_Dcps_Export FreeHeader : public AllocHeader {
00065 public:
00066
00067 void init_free_block(unsigned int pool_size);
00068
00069
00070 void set_free();
00071
00072
00073 FreeHeader* smaller_free(unsigned char* pool_base) const;
00074
00075 FreeHeader* larger_free(unsigned char* pool_base) const;
00076
00077
00078 void set_smaller_free(FreeHeader* next, unsigned char* pool_base);
00079
00080 void set_larger_free(FreeHeader* prev, unsigned char* pool_base);
00081
00082 private:
00083 size_t offset_smaller_free_;
00084 size_t offset_larger_free_;
00085 };
00086
00087
00088
00089
00090
00091 class FreeIndexNode {
00092 public:
00093 FreeIndexNode();
00094
00095 void set_ptr(FreeHeader* ptr) { ptr_ = ptr; }
00096
00097 void set_sizes(size_t size, size_t limit);
00098
00099
00100 bool contains(size_t size) { return ((size >= size_) && (size < limit_)); }
00101
00102
00103 FreeHeader* ptr() { return ptr_; }
00104
00105 unsigned int size() const { return static_cast<unsigned int>(size_); }
00106
00107 private:
00108 size_t size_;
00109 size_t limit_;
00110 FreeHeader* ptr_;
00111 };
00112
00113
00114
00115 class OpenDDS_Dcps_Export FreeIndex {
00116 friend class ::MemoryPoolTest;
00117 friend class ::FreeIndexTest;
00118 public:
00119 explicit FreeIndex(FreeHeader*& largest_free);
00120
00121 void init(FreeHeader* init_free_block);
00122
00123
00124 void add(FreeHeader* free_block);
00125
00126 void remove(FreeHeader* free_block, FreeHeader* next_largest);
00127
00128
00129 FreeHeader* find(size_t size, unsigned char* base);
00130
00131
00132 static unsigned int node_index(size_t size);
00133
00134 #ifdef VALIDATE_MEMORY_POOL
00135 static void validate_index(FreeIndex& index,
00136 unsigned char* base,
00137 bool log = false);
00138 #endif
00139 private:
00140 enum {
00141 min_index_pow = 3,
00142 max_index_pow = 12
00143 };
00144 enum {
00145 min_index = 8,
00146 max_index = 4096
00147 };
00148
00149 size_t size_;
00150 FreeHeader*& largest_free_;
00151 FreeIndexNode nodes_[max_index_pow - min_index_pow + 1];
00152 };
00153
00154
00155
00156
00157
00158
00159 class OpenDDS_Dcps_Export MemoryPool {
00160 friend class ::MemoryPoolTest;
00161 public:
00162 explicit MemoryPool(unsigned int pool_size, size_t granularity = 8);
00163 ~MemoryPool();
00164
00165
00166 bool includes(void* ptr) const {
00167 return (pool_ptr_ <= ptr) && (ptr < pool_ptr_ + pool_size_); }
00168
00169
00170 void* pool_alloc(size_t size);
00171
00172
00173
00174
00175 bool pool_free(void* ptr);
00176
00177
00178 size_t lwm_free_bytes() const;
00179
00180
00181 static size_t align(size_t size, size_t granularity) {
00182 return (size + granularity - 1) / granularity * granularity; }
00183
00184 size_t size () const { return pool_size_; }
00185
00186 private:
00187 const size_t granularity_;
00188 const size_t min_alloc_size_;
00189 const size_t pool_size_;
00190 size_t lwm_free_bytes_;
00191 unsigned char* pool_ptr_;
00192
00193 FreeHeader* largest_free_;
00194 FreeIndex free_index_;
00195
00196 enum {
00197 min_free_size = sizeof(FreeHeader)
00198 };
00199
00200
00201 void remove_free_alloc(FreeHeader* block_to_alloc);
00202 void insert_free_alloc(FreeHeader* block_freed);
00203 void join_free_allocs(FreeHeader* block_freed);
00204 unsigned char* allocate(FreeHeader* free_block, size_t alloc_size);
00205
00206 bool joinable_next(FreeHeader* freed);
00207 bool joinable_prev(FreeHeader* freed);
00208
00209 #ifdef VALIDATE_MEMORY_POOL
00210 static void validate_pool(MemoryPool& pool, bool log = false);
00211 #endif
00212 };
00213
00214 }}
00215
00216 #endif // OPENDDS_MEMORY_POOL_H