Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
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; |
