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