00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "simpleAllocator.h"
00016
00017
00018
00019
00020
00021
00022 SimpleAllocator::
00023 ~SimpleAllocator() {
00024
00025 if (_next != (LinkedListNode *)this) {
00026 MutexHolder holder(_lock);
00027 while (_next != (LinkedListNode *)this) {
00028 nassertv(_next != (LinkedListNode *)NULL);
00029 ((SimpleAllocatorBlock *)_next)->do_free();
00030 }
00031 }
00032 }
00033
00034
00035
00036
00037
00038
00039 void SimpleAllocator::
00040 output(ostream &out) const {
00041 MutexHolder holder(_lock);
00042 out << "SimpleAllocator, " << _total_size << " of " << _max_size
00043 << " allocated";
00044 }
00045
00046
00047
00048
00049
00050
00051 void SimpleAllocator::
00052 write(ostream &out) const {
00053 MutexHolder holder(_lock);
00054 out << "SimpleAllocator, " << _total_size << " of " << _max_size
00055 << " allocated";
00056
00057 SimpleAllocatorBlock *block = (SimpleAllocatorBlock *)_next;
00058 while (block->_next != this) {
00059 SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
00060
00061 out << " " << *block << "\n";
00062 block = next;
00063 }
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 SimpleAllocatorBlock *SimpleAllocator::
00078 do_alloc(size_t size) {
00079 if (size > _contiguous) {
00080
00081 return NULL;
00082 }
00083
00084
00085
00086
00087 SimpleAllocatorBlock *block = NULL;
00088 size_t end = 0;
00089 size_t best = 0;
00090 if (_next != this) {
00091
00092 block = (SimpleAllocatorBlock *)_next;
00093 end = block->_start + block->_size;
00094
00095
00096 while (block->_next != this) {
00097 SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
00098 size_t free_size = next->_start - end;
00099 if (size <= free_size) {
00100 SimpleAllocatorBlock *new_block = make_block(end, size);
00101 nassertr(new_block->get_allocator() == this, NULL);
00102
00103 new_block->insert_before(next);
00104 _total_size += size;
00105
00106 if (_max_size - _total_size < _contiguous) {
00107
00108
00109
00110 _contiguous = _max_size - _total_size;
00111 changed_contiguous();
00112 }
00113 return new_block;
00114 }
00115 if (free_size > best) {
00116 best = free_size;
00117 }
00118
00119 block = next;
00120 end = block->_start + block->_size;
00121 }
00122 }
00123
00124
00125 size_t free_size = _max_size - end;
00126 if (size <= free_size) {
00127 SimpleAllocatorBlock *new_block = make_block(end, size);
00128 nassertr(new_block->get_allocator() == this, NULL);
00129
00130 new_block->insert_before(this);
00131 _total_size += size;
00132
00133 if (_max_size - _total_size < _contiguous) {
00134
00135
00136
00137 _contiguous = _max_size - _total_size;
00138 changed_contiguous();
00139 }
00140 return new_block;
00141 }
00142
00143 if (free_size > best) {
00144 best = free_size;
00145 }
00146
00147
00148
00149 if (_contiguous != best) {
00150 _contiguous = best;
00151 changed_contiguous();
00152 }
00153
00154
00155 return NULL;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 SimpleAllocatorBlock *SimpleAllocator::
00165 make_block(size_t start, size_t size) {
00166 return new SimpleAllocatorBlock(this, start, size);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176 void SimpleAllocator::
00177 changed_contiguous() {
00178 }
00179
00180
00181
00182
00183
00184
00185 void SimpleAllocatorBlock::
00186 output(ostream &out) const {
00187 if (_allocator == (SimpleAllocator *)NULL) {
00188 out << "free block\n";
00189 } else {
00190 MutexHolder holder(_allocator->_lock);
00191 out << "block of size " << _size << " at " << _start;
00192 }
00193 }