21 void Chunk256::setFree(
bool free){
24 allocationTimeStamp = 0x0;
27 allocationTimeStamp = allocationTimeStamp & offMask;
30 bool Chunk256::getFree(){
32 return ((allocationTimeStamp | offMask) == offMask ?
true :
false);
35 void Chunk256::setAllocationTimeStamp(Uint32 cTime){
39 Uint32 onMask = 0x80000000;
40 allocationTimeStamp = 0x0;
41 allocationTimeStamp = onMask | cTime;
44 Uint32 Chunk256::getAllocationTimeStamp(){
45 Uint32 onMask = 0x80000000;
46 allocationTimeStamp = allocationTimeStamp ^ onMask;
47 printf(
"\nGet allocation time. Time is %d", allocationTimeStamp);
48 return allocationTimeStamp;
51 bool BuddyMemory::allocate(
int nChunksToAllocate) {
56 printf(
"\nAllocating %d chunks...", nChunksToAllocate);
58 startOfMemoryBlock = (Uint32*) malloc(256 * nChunksToAllocate);
60 if (startOfMemoryBlock == NULL)
64 chunk =
new Chunk256[nChunksToAllocate];
68 for (
int i=0;
i < nChunksToAllocate;
i++) {
69 chunk[
i].setFree(
true);
72 chunk[
i].prevSegmentOfSameSize =
i-32;
73 chunk[
i].nextSegmentOfSameSize =
i + 32;
74 chunk[0].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
75 chunk[totalNoOfChunks-32].nextSegmentOfSameSize = END_OF_CHUNK_LIST;
78 chunk[
i].prevSegmentOfSameSize = UNDEFINED_CHUNK;
79 chunk[
i].nextSegmentOfSameSize = UNDEFINED_CHUNK;
84 for (
int i=0;
i<sz_MAX;
i++)
85 freeSegment[
i] = UNDEFINED_CHUNK;
88 freeSegment[sz_8192] = 0;
90 for (
int i=0;
i<sz_MAX;
i++)
91 printf(
"\nPointers: %d", freeSegment[
i]);
97 bool BuddyMemory::getSegment(Uint32
size,
Segment * dst) {
100 Uint32 nChunksAskedFor = ceil((
double(size)/
double(256)));
103 printf(
"\n%d chunks asked for", nChunksAskedFor);
108 int nChunksToAllocate = nChunksAskedFor;
111 if ((nChunksToAllocate != 1) && (nChunksToAllocate % 2 != 0))
114 printf(
"\n%d chunks to allocate", nChunksToAllocate);
115 int segmSize = logTwoPlus(nChunksToAllocate) - 1;
116 if (size-pow(2,segmSize) > 256)
118 printf(
"\nSegment size: %f", pow(2,
int(8+segmSize)));
120 while ((segmSize <= sz_GET_MAX) && (freeSegment[segmSize] == UNDEFINED_CHUNK))
123 segm = freeSegment[segmSize];
124 if (segm != UNDEFINED_CHUNK){
128 removeFromFreeSegmentList(segmSize, segm);
132 for (
int i = segm;
i <= segm+nChunksToAllocate;
i++) {
133 chunk[
i].setFree(
false);
134 chunk[
i].setAllocationTimeStamp(currentTime);
138 if (nChunksAskedFor < nChunksToAllocate)
139 release(nChunksAskedFor, nChunksToAllocate - nChunksAskedFor - 1);
142 segment.segmentAddress = startOfMemoryBlock+(segm * 256);
143 segment.segmentSize = 256 * nChunksAskedFor;
144 segment.releaseId = segm;
146 printf(
"\nSegment: segment address = %d, segment size = %d, release Id = %d",
147 segment.segmentAddress, segment.segmentSize, segment.releaseId);
151 printf(
"\nNo segments of asked size or larger are found");
155 void BuddyMemory::removeFromFreeSegmentList(
int sz,
int index) {
158 printf(
"\nRemoving segment from list...");
159 if (index != UNDEFINED_CHUNK) {
162 int prevChunkIndex = chunk[
index].prevSegmentOfSameSize;
163 int nextChunkIndex = chunk[
index].nextSegmentOfSameSize;
165 if (prevChunkIndex == END_OF_CHUNK_LIST) {
166 if (nextChunkIndex == END_OF_CHUNK_LIST)
168 freeSegment[sz] = UNDEFINED_CHUNK;
171 nextChunk = chunk[nextChunkIndex];
172 nextChunk.prevSegmentOfSameSize = END_OF_CHUNK_LIST;
173 freeSegment[sz] = nextChunkIndex;
176 if (nextChunkIndex == END_OF_CHUNK_LIST) {
178 prevChunk = chunk[prevChunkIndex];
179 prevChunk.nextSegmentOfSameSize = END_OF_CHUNK_LIST;
182 prevChunk = chunk[prevChunkIndex];
183 nextChunk = chunk[nextChunkIndex];
184 prevChunk.nextSegmentOfSameSize = nextChunkIndex;
185 nextChunk.prevSegmentOfSameSize = prevChunkIndex;
189 for (
int i=0;
i<sz_MAX;
i++)
190 printf(
"\nPointers: %d", freeSegment[
i]);
193 void BuddyMemory::release(
int releaseId,
int size) {
195 int nChunksToRelease = (size == 0 ? 1 : ceil(
double(size)/
double(256)));
197 int startChunk = releaseId;
198 int endChunk = releaseId + nChunksToRelease - 1;
200 printf(
"\n%d chunks to release (initially)", nChunksToRelease);
203 for (
int i = startChunk;
i <= endChunk;
i++){
204 chunk[
i].setFree(
true);
208 for (
int i = releaseId-1;
i >= 0;
i--) {
209 if (!chunk[
i].getFree())
217 if (chunk[
i].nextSegmentOfSameSize != UNDEFINED_CHUNK)
218 removeFromFreeSegmentList(size,
i);
223 for (
int i = endChunk+1;
i <= totalNoOfChunks;
i++) {
224 if (!chunk[
i].getFree())
232 if (chunk[
i].nextSegmentOfSameSize != UNDEFINED_CHUNK)
233 removeFromFreeSegmentList(size,
i);
243 printf(
"\n%d chunks to release (finally)", nChunksToRelease);
245 segmSize = logTwoPlus(nChunksToRelease) - 1;
246 if (segmSize > sz_MAX) {
250 nChunksToRelease = pow(2,segmSize);
251 addToFreeSegmentList(nChunksToRelease*256, startChunk);
254 void BuddyMemory::addToFreeSegmentList(
int sz,
int index) {
257 printf(
"\nAsked to add segment of size %d", sz);
260 int segmSize = logTwoPlus(sz) - 1;
261 if (sz - pow(2,segmSize) >= 256)
265 int nextSegm = freeSegment[sz];
267 printf(
"\nAdding a segment of size %f", pow(2,(8 + sz)));
269 freeSegment[sz] =
index;
270 if (nextSegm == UNDEFINED_CHUNK) {
272 chunk[
index].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
273 chunk[
index].nextSegmentOfSameSize = END_OF_CHUNK_LIST;
277 chunk[
index].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
278 chunk[
index].nextSegmentOfSameSize = nextSegm;
279 chunk[nextSegm].prevSegmentOfSameSize =
index;
282 for (
int i=0;
i<sz_MAX;
i++)
283 printf(
"\nPointers: %d", freeSegment[
i]);
287 Uint32 BuddyMemory::logTwoPlus(Uint32 arg) {
292 arg = arg | (arg >> 8);
293 arg = arg | (arg >> 4);
294 arg = arg | (arg >> 2);
295 arg = arg | (arg >> 1);
296 resValue = (arg & 0x5555) + ((arg >> 1) & 0x5555);
297 resValue = (resValue & 0x3333) + ((resValue >> 2) & 0x3333);
298 resValue = resValue + (resValue >> 4);
299 resValue = (resValue & 0xf) + ((resValue >> 8) & 0xf);
304 bool BuddyMemory::memoryAvailable() {
306 for (
int i = sz_8192;
i < sz_MAX;
i++)
307 if (freeSegment[
i] != UNDEFINED_CHUNK)
313 void BuddyMemory::refreshTime(Uint32 time) {
314 if (time - currentTime > 1000) {
319 for (
int i=0;
i<totalNoOfChunks;
i++) {
320 if ((!chunk[
i].getFree()) &&
321 (currentTime-chunk[
i].getAllocationTimeStamp() > ALLOCATION_TIMEOUT)) {
323 printf(
"\nChunks hve been allocated for too long");