Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison vmalloc.c @ 141:79bb48d7d93b
changed free back to request to master and bugfixes
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Wed, 21 Sep 2011 11:51:29 +0200 |
| parents | 2c8f3cf6c058 |
| children | 98fc8f3761a2 |
comparison
equal
deleted
inserted
replaced
| 26:ecb6ab08f516 | 27:173a01a650c3 |
|---|---|
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 #include <math.h> | 15 #include <math.h> |
| 16 | 16 |
| 17 #define NDEBUG | |
| 18 #include <assert.h> | |
| 19 | |
| 17 #include "VMS.h" | 20 #include "VMS.h" |
| 18 #include "vmalloc.h" | 21 #include "vmalloc.h" |
| 19 #include "Histogram/Histogram.h" | 22 #include "Histogram/Histogram.h" |
| 20 | 23 |
| 21 #define MAX_UINT64 0xFFFFFFFFFFFFFFFF | 24 #define MAX_UINT64 0xFFFFFFFFFFFFFFFF |
| 22 | 25 |
| 26 | |
| 27 | |
| 23 inline void | 28 inline void |
| 24 sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr); | 29 sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr); |
| 25 | 30 |
| 26 inline void | 31 inline void |
| 27 sendFreeReqst_master(int receiverID, void *ptrToFree); | 32 sendFreeReqst_master(int receiverID, void *ptrToFree); |
| 33 | |
| 34 void VMS__check_free_list(MallocArrays *freeLists); | |
| 28 | 35 |
| 29 //A MallocProlog is a head element if the HigherInMem variable is NULL | 36 //A MallocProlog is a head element if the HigherInMem variable is NULL |
| 30 //A Chunk is free if the prevChunkInFreeList variable is NULL | 37 //A Chunk is free if the prevChunkInFreeList variable is NULL |
| 31 | 38 |
| 32 /* | 39 /* |
| 52 | 59 |
| 53 if(removedChunk->nextChunkInFreeList) | 60 if(removedChunk->nextChunkInFreeList) |
| 54 removedChunk->nextChunkInFreeList->prevChunkInFreeList = | 61 removedChunk->nextChunkInFreeList->prevChunkInFreeList = |
| 55 (MallocProlog*)container; | 62 (MallocProlog*)container; |
| 56 | 63 |
| 64 assert((freeLists->bigChunksSearchVector[0] & ((uint64)1 << containerIdx)) != 0); | |
| 65 | |
| 57 if(*container == NULL) | 66 if(*container == NULL) |
| 58 { | 67 { |
| 59 if(containerIdx < 64) | 68 if(containerIdx < 64) |
| 69 { | |
| 70 assert((freeLists->bigChunksSearchVector[0] & ((uint64)1 << containerIdx)) != 0); | |
| 60 freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); | 71 freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); |
| 72 } | |
| 61 else | 73 else |
| 74 { | |
| 75 assert((freeLists->bigChunksSearchVector[1] & ((uint64)1 << (containerIdx-64))) != 0); | |
| 62 freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); | 76 freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); |
| 63 } | 77 } |
| 64 | 78 } |
| 65 return removedChunk; | 79 return removedChunk; |
| 66 } | 80 } |
| 67 | 81 |
| 68 /* | 82 /* |
| 69 * Removes the first chunk of a freeList | 83 * Removes the first chunk of a freeList |
| 101 if(chunk->nextChunkInFreeList) | 115 if(chunk->nextChunkInFreeList) |
| 102 chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList; | 116 chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList; |
| 103 | 117 |
| 104 //The last element in the list points to the container. If the container points | 118 //The last element in the list points to the container. If the container points |
| 105 //to NULL the container is empty | 119 //to NULL the container is empty |
| 106 if(*((void**)(chunk->prevChunkInFreeList)) == NULL && getChunkSize(chunk) >= BIG_LOWER_BOUND); | 120 if(((*((void**)(chunk->prevChunkInFreeList))) == NULL) && (getChunkSize(chunk) >= BIG_LOWER_BOUND)) |
| 107 { | 121 { |
| 122 assert((*((void**)(chunk->prevChunkInFreeList))) == NULL); | |
| 108 //Find the approppiate container because we do not know it | 123 //Find the approppiate container because we do not know it |
| 109 uint64 containerIdx = ((uintptr_t)chunk->prevChunkInFreeList - (uintptr_t)freeLists->bigChunks) >> 3; | 124 uint64 containerIdx = ((uintptr_t)chunk->prevChunkInFreeList - (uintptr_t)freeLists->bigChunks) >> 3; |
| 110 if(containerIdx < (uint64)64) | 125 if(containerIdx < (uint64)64) |
| 126 { | |
| 127 assert((freeLists->bigChunksSearchVector[0] & ((uint64)1 << containerIdx)) != 0); | |
| 111 freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); | 128 freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); |
| 129 } | |
| 112 if(containerIdx < 128 && containerIdx >=64) | 130 if(containerIdx < 128 && containerIdx >=64) |
| 131 { | |
| 132 assert((freeLists->bigChunksSearchVector[1] & ((uint64)1 << (containerIdx-64))) != 0); | |
| 113 freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); | 133 freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); |
| 134 } | |
| 114 | 135 |
| 115 } | 136 } |
| 116 } | 137 } |
| 117 | 138 |
| 118 /* | 139 /* |
| 181 printf("VMS malloc failed: low memory"); | 202 printf("VMS malloc failed: low memory"); |
| 182 exit(1); | 203 exit(1); |
| 183 } | 204 } |
| 184 containerIdx += 64; | 205 containerIdx += 64; |
| 185 } | 206 } |
| 186 containerIdx--; | 207 containerIdx--; // ffsl index starts at 1 |
| 187 | 208 |
| 188 | 209 |
| 189 foundChunk = removeChunk(freeLists, containerIdx); | 210 foundChunk = removeChunk(freeLists, containerIdx); |
| 190 size_t chunkSize = getChunkSize(foundChunk); | 211 size_t chunkSize = getChunkSize(foundChunk); |
| 191 | 212 |
| 197 insertChunk(foundChunk,&freeLists->bigChunks[containerIdx]); | 218 insertChunk(foundChunk,&freeLists->bigChunks[containerIdx]); |
| 198 if(containerIdx < 64) | 219 if(containerIdx < 64) |
| 199 freeLists->bigChunksSearchVector[0] |= ((uint64)1 << containerIdx); | 220 freeLists->bigChunksSearchVector[0] |= ((uint64)1 << containerIdx); |
| 200 else | 221 else |
| 201 freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (containerIdx-64)); | 222 freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (containerIdx-64)); |
| 223 assert(freeLists->bigChunks[containerIdx] == foundChunk); | |
| 224 assert((freeLists->bigChunksSearchVector[0] & ((uint64)1 << containerIdx)) != 0); | |
| 202 foundChunk = newChunk; | 225 foundChunk = newChunk; |
| 203 } | 226 } |
| 204 | 227 |
| 205 return foundChunk; | 228 return foundChunk; |
| 206 } | 229 } |
| 278 #ifdef MEAS__TIME_MALLOC | 301 #ifdef MEAS__TIME_MALLOC |
| 279 saveLowTimeStampCountInto( endStamp ); | 302 saveLowTimeStampCountInto( endStamp ); |
| 280 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->mallocTimeHist ); | 303 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->mallocTimeHist ); |
| 281 #endif | 304 #endif |
| 282 //======================================================================== | 305 //======================================================================== |
| 306 assert(getChunkSize((MallocProlog*)returnChunk)>=sizeRequested); | |
| 283 | 307 |
| 284 //skip over the prolog by adding its size to the pointer return | 308 //skip over the prolog by adding its size to the pointer return |
| 285 return returnChunk + 1; | 309 return returnChunk + 1; |
| 286 } | 310 } |
| 287 | 311 |
| 332 sendFreeReqst_master(int receiverID, void *ptrToFree) | 356 sendFreeReqst_master(int receiverID, void *ptrToFree) |
| 333 { | 357 { |
| 334 InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); | 358 InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); |
| 335 freeReqst->freePtr = ptrToFree; | 359 freeReqst->freePtr = ptrToFree; |
| 336 freeReqst->secondReqType = transfer_free_ptr; | 360 freeReqst->secondReqType = transfer_free_ptr; |
| 337 | 361 |
| 338 sendInterMasterReqst(receiverID, (InterMasterReqst*)freeReqst); | 362 VMS__sendInterMasterReqst(receiverID, (InterMasterReqst*)freeReqst); |
| 339 } | 363 } |
| 340 | 364 |
| 341 /* | 365 /* |
| 342 * This is called if the free is called from the plugin. This requests an inter | 366 * This is called if the free is called from the plugin. This requests an inter |
| 343 * master request from his master. | 367 * master request from his master. |
| 354 reqData.receiverID = receiverID; | 378 reqData.receiverID = receiverID; |
| 355 reqData.data = (void*)freeReqst; | 379 reqData.data = (void*)freeReqst; |
| 356 | 380 |
| 357 VMS__send_VMSSem_request( (void*)&reqData, animPr ); | 381 VMS__send_VMSSem_request( (void*)&reqData, animPr ); |
| 358 } | 382 } |
| 383 | |
| 384 void VMS__check_free_list(MallocArrays *freeLists) | |
| 385 { | |
| 386 int idx; | |
| 387 for(idx=0; idx< freeLists->containerCount; idx++) | |
| 388 { | |
| 389 if(freeLists->bigChunks[idx]) | |
| 390 assert((freeLists->bigChunksSearchVector[0] & ((uint64)1 << idx)) != 0); | |
| 391 if((freeLists->bigChunksSearchVector[0] & ((uint64)1 << idx))) | |
| 392 assert(freeLists->bigChunks[idx] != NULL); | |
| 393 } | |
| 394 } | |
| 359 | 395 |
| 360 /* | 396 /* |
| 361 * This is sequential code, meant to only be called from the Master, not from | 397 * This is sequential code, meant to only be called from the Master, not from |
| 362 * any slave VPs. | 398 * any slave VPs. |
| 363 */ | 399 */ |
| 409 insertChunk(chunkToFree, &freeLists->bigChunks[containerIdx]); | 445 insertChunk(chunkToFree, &freeLists->bigChunks[containerIdx]); |
| 410 if(containerIdx < 64) | 446 if(containerIdx < 64) |
| 411 freeLists->bigChunksSearchVector[0] |= (uint64)1 << containerIdx; | 447 freeLists->bigChunksSearchVector[0] |= (uint64)1 << containerIdx; |
| 412 else | 448 else |
| 413 freeLists->bigChunksSearchVector[1] |= (uint64)1 << (containerIdx-64); | 449 freeLists->bigChunksSearchVector[1] |= (uint64)1 << (containerIdx-64); |
| 414 } | 450 assert((freeLists->bigChunksSearchVector[0] & (uint64)1 << containerIdx) != 0); |
| 451 } | |
| 415 | 452 |
| 416 //============================= MEASUREMENT STUFF ======================== | 453 //============================= MEASUREMENT STUFF ======================== |
| 417 #ifdef MEAS__TIME_MALLOC | 454 #ifdef MEAS__TIME_MALLOC |
| 418 saveLowTimeStampCountInto( endStamp ); | 455 saveLowTimeStampCountInto( endStamp ); |
| 419 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->freeTimeHist ); | 456 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->freeTimeHist ); |
| 455 *(char*)ptr = 0; | 492 *(char*)ptr = 0; |
| 456 } | 493 } |
| 457 | 494 |
| 458 firstChunk->nextLowerInMem = NULL; | 495 firstChunk->nextLowerInMem = NULL; |
| 459 firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + | 496 firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + |
| 460 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog*)); | 497 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog)); |
| 461 firstChunk->nextChunkInFreeList = NULL; | 498 firstChunk->nextChunkInFreeList = NULL; |
| 462 //previous element in the queue is the container | 499 //previous element in the queue is the container |
| 463 firstChunk->prevChunkInFreeList = (MallocProlog*)&freeLists->bigChunks[container-2]; | 500 firstChunk->prevChunkInFreeList = (MallocProlog*)&freeLists->bigChunks[container-2]; |
| 464 | 501 |
| 465 freeLists->bigChunks[container-2] = firstChunk; | 502 freeLists->bigChunks[container-2] = firstChunk; |
| 466 //Insert into bit search list | 503 //Insert into bit search list |
| 467 if(container <= 65) | 504 if(container <= 65) |
| 505 { | |
| 468 freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2)); | 506 freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2)); |
| 507 freeLists->bigChunksSearchVector[1] = 0; | |
| 508 } | |
| 469 else | 509 else |
| 510 { | |
| 511 freeLists->bigChunksSearchVector[0] = 0; | |
| 470 freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66)); | 512 freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66)); |
| 513 } | |
| 471 | 514 |
| 472 //Create dummy chunk to mark the top of stack this is of course | 515 //Create dummy chunk to mark the top of stack this is of course |
| 473 //never freed | 516 //never freed |
| 474 MallocProlog *dummyChunk = firstChunk->nextHigherInMem; | 517 MallocProlog *dummyChunk = firstChunk->nextHigherInMem; |
| 475 dummyChunk->nextHigherInMem = dummyChunk+1; | 518 dummyChunk->nextHigherInMem = dummyChunk+1; |
