comparison vmalloc.c @ 115:62c59f2ac9f1

first changes malloc
author Merten Sach <msach@mailbox.tu-berlin.de>
date Thu, 25 Aug 2011 16:32:13 +0200
parents def70e32cf2c
children 35547e66b971
comparison
equal deleted inserted replaced
14:533fe4146879 15:5f703d658f90
15 #include <math.h> 15 #include <math.h>
16 16
17 #include "VMS.h" 17 #include "VMS.h"
18 #include "Histogram/Histogram.h" 18 #include "Histogram/Histogram.h"
19 19
20 #define MAX_UINT64 0xFFFFFFFFFFFFFFFF
21
20 //A MallocProlog is a head element if the HigherInMem variable is NULL 22 //A MallocProlog is a head element if the HigherInMem variable is NULL
21 //A Chunk is free if the prevChunkInFreeList variable is NULL 23 //A Chunk is free if the prevChunkInFreeList variable is NULL
22 24
23 /* 25 /*
24 * This calculates the container which fits the given size. 26 * This calculates the container which fits the given size.
64 66
65 /* 67 /*
66 * Removes a chunk from a free list. 68 * Removes a chunk from a free list.
67 */ 69 */
68 inline 70 inline
69 void extractChunk(MallocProlog* chunk) 71 void extractChunk(MallocProlog* chunk, MallocArrays *freeLists)
70 { 72 {
71 chunk->prevChunkInFreeList->nextChunkInFreeList = chunk->nextChunkInFreeList; 73 chunk->prevChunkInFreeList->nextChunkInFreeList = chunk->nextChunkInFreeList;
72 if(chunk->nextChunkInFreeList) 74 if(chunk->nextChunkInFreeList)
73 chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList; 75 chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList;
76 if(*(chunk->prevChunkInFreeList) == NULL)
77 {
78 uint32 containerIdx = (uintptr_t)(chunk->prevChunkInFreeList - freeLists->bigChunks) / sizeof(MallocProlog*);
79 freeLists->bigChunksSearchVector &= ~(1 << containerIdx);
80 }
74 } 81 }
75 82
76 /* 83 /*
77 * Merges two chunks. 84 * Merges two chunks.
78 * Chunk A has to be before chunk B in memory. Both have to be removed from 85 * Chunk A has to be before chunk B in memory. Both have to be removed from
160 saveLowTimeStampCountInto( startStamp ); 167 saveLowTimeStampCountInto( startStamp );
161 #endif 168 #endif
162 //======================================================================== 169 //========================================================================
163 170
164 171
165 MallocArrays* freeList = _VMSMasterEnv->freeLists; 172 MallocArrays* freeLists = _VMSMasterEnv->freeLists;
166 173
167 //Return a small chunk if the requested size is smaller than 128B 174 //Return a small chunk if the requested size is smaller than 128B
168 if(sizeRequested <= LOWER_BOUND) 175 if(sizeRequested <= LOWER_BOUND)
169 { 176 {
170 uint32 freeListIdx = (sizeRequested-1)/32; 177 uint32 freeListIdx = (sizeRequested-1)/32;
171 if(freeList->smallChunkCount[freeListIdx] == 0) 178 if(freeLists->smallChunkCount[freeListIdx] == 0)
172 { 179 {
173 makeChunks((freeListIdx+1)*32, &freeList->smallChunks[freeListIdx]); 180 makeChunks((freeListIdx+1)*32, &freeLists->smallChunks[freeListIdx]);
174 freeList->smallChunkCount[freeListIdx] += 5; 181 freeLists->smallChunkCount[freeListIdx] += 5;
175 } 182 }
176 183
177 freeList->smallChunkCount[freeListIdx]--; 184 freeLists->smallChunkCount[freeListIdx]--;
178 return removeChunk(&freeList->smallChunks[freeListIdx]) + 1; 185 return removeChunk(&freeLists->smallChunks[freeListIdx]) + 1;
179 } 186 }
180 187
181 //Calculate the expected container. Start one higher to have a Chunk that's 188 //Calculate the expected container. Start one higher to have a Chunk that's
182 //always big enough. 189 //always big enough.
183 uint32 targetContainerIdx = getContainer(sizeRequested); 190 uint32 targetContainerIdx = getContainer(sizeRequested);
184 uint32 containerIdx = targetContainerIdx + 1; 191 uint32 containerIdx = targetContainerIdx + 1;
185 192
186 MallocProlog* foundChunk; 193 MallocProlog* foundChunk;
187 if(freeList->bigChunks[containerIdx] == NULL) 194 if(freeLists->bigChunks[containerIdx] == NULL)
188 { 195 {
196 uint64 searchVector = freeLists->bigChunksSearchVector;
197 //set small chunk bits to zero
198 searchVector &= MAX_UINT64 << containerIdx;
199 containerIdx = __builtin_ffsl(searchVector);
200
201 if(containerIdx == 0)
202 {
203 printf("VMS malloc failed: low memory");
204 exit(1);
205 }
206 /*
189 while(freeList->bigChunks[containerIdx] == NULL) 207 while(freeList->bigChunks[containerIdx] == NULL)
190 { 208 {
191 containerIdx++; 209 containerIdx++;
192 if(containerIdx >= freeList->containerCount) 210 if(containerIdx >= freeList->containerCount)
193 { 211 {
194 printf("VMS malloc failed: low memory"); 212 printf("VMS malloc failed: low memory");
195 exit(1); 213 exit(1);
196 } 214 }
197 } 215 }*/
198 216
199 foundChunk = removeChunk(&freeList->bigChunks[containerIdx]); 217 foundChunk = removeChunk(&freeLists->bigChunks[containerIdx]);
200 size_t chunkSize = getChunkSize(foundChunk); 218 size_t chunkSize = getChunkSize(foundChunk);
201 219
202 if(chunkSize > sizeRequested + sizeof(MallocProlog)) 220 //If the new chunk is larger than the requested size: split
221 if(chunkSize > sizeRequested + 2 * sizeof(MallocProlog) + LOWER_BOUND)
203 { 222 {
204 MallocProlog *newChunk = divideChunk(foundChunk,sizeRequested); 223 MallocProlog *newChunk = divideChunk(foundChunk,sizeRequested);
205 containerIdx = getContainer(chunkSize - sizeRequested - sizeof(MallocProlog)); 224 containerIdx = getContainer(getChunkSize(newChunk));
206 insertChunk(foundChunk,&freeList->bigChunks[containerIdx]); 225 insertChunk(foundChunk,&freeLists->bigChunks[containerIdx]);
226 freeLists->bigChunksSearchVector |= 1 << containerIdx;
207 foundChunk = newChunk; 227 foundChunk = newChunk;
208 } 228 }
209 } 229 }
210 else 230 else
211 { 231 {
212 foundChunk = removeChunk(&freeList->bigChunks[containerIdx]); 232 foundChunk = removeChunk(&freeLists->bigChunks[containerIdx]);
213 } 233 }
214 234
215 //Mark as allocated 235 //Mark as allocated
216 foundChunk->prevChunkInFreeList = NULL; 236 foundChunk->prevChunkInFreeList = NULL;
217 237
391 firstChunk->nextChunkInFreeList = NULL; 411 firstChunk->nextChunkInFreeList = NULL;
392 //previous element in the queue is the container 412 //previous element in the queue is the container
393 firstChunk->prevChunkInFreeList = freeLists->bigChunks[container-1]; 413 firstChunk->prevChunkInFreeList = freeLists->bigChunks[container-1];
394 414
395 freeLists->bigChunks[container-1] = firstChunk; 415 freeLists->bigChunks[container-1] = firstChunk;
416 //Insert into bit search list
417 freeLists->bigChunksSearchVector |= (1 << (container-1));
396 418
397 //Create dummy chunk to mark the top of stack this is of course 419 //Create dummy chunk to mark the top of stack this is of course
398 //never freed 420 //never freed
399 MallocProlog *dummyChunk = firstChunk->nextHigherInMem; 421 MallocProlog *dummyChunk = firstChunk->nextHigherInMem;
400 dummyChunk->nextHigherInMem = dummyChunk+1; 422 dummyChunk->nextHigherInMem = dummyChunk+1;