Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison vmalloc.c @ 139:99798e4438a6
Merge of Malloc2 and inter master requests
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Mon, 19 Sep 2011 16:12:01 +0200 |
| parents | d0aa5a796fc5 99343ffe1918 |
| children | 2c8f3cf6c058 |
comparison
equal
deleted
inserted
replaced
| 20:535b0f2c7154 | 25:faee7dc89616 |
|---|---|
| 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 | 20 #define MAX_UINT64 0xFFFFFFFFFFFFFFFF |
| 21 | |
| 22 inline void | |
| 23 sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr); | |
| 24 | |
| 25 inline void | |
| 26 sendFreeReqst_master(int receiverID, void *ptrToFree); | |
| 21 | 27 |
| 22 //A MallocProlog is a head element if the HigherInMem variable is NULL | 28 //A MallocProlog is a head element if the HigherInMem variable is NULL |
| 23 //A Chunk is free if the prevChunkInFreeList variable is NULL | 29 //A Chunk is free if the prevChunkInFreeList variable is NULL |
| 24 | 30 |
| 25 /* | 31 /* |
| 196 } | 202 } |
| 197 | 203 |
| 198 return foundChunk; | 204 return foundChunk; |
| 199 } | 205 } |
| 200 | 206 |
| 207 /* | |
| 208 * This function is called by code which is part of the master loop. | |
| 209 * This reads the animating coreID from the MasterEnv and calls the normal malloc | |
| 210 * in VMS__malloc_on_core | |
| 211 */ | |
| 212 void * | |
| 213 VMS__malloc( size_t sizeRequested) | |
| 214 { | |
| 215 return VMS__malloc_on_core(sizeRequested, _VMSMasterEnv->currentMasterProcrID); | |
| 216 } | |
| 217 | |
| 218 /* | |
| 219 * This is called by the plugin. This call to VMS_malloc_on_core is run on the | |
| 220 * slave VPs stack so there is no switch to the VMS runtime. | |
| 221 */ | |
| 222 void * | |
| 223 VMS__malloc_in_lib(size_t sizeRequested, VirtProcr *VProcr) | |
| 224 { | |
| 225 return VMS__malloc_on_core(sizeRequested, VProcr->coreAnimatedBy); | |
| 226 } | |
| 201 | 227 |
| 202 /* | 228 /* |
| 203 * This is sequential code, meant to only be called from the Master, not from | 229 * This is sequential code, meant to only be called from the Master, not from |
| 204 * any slave VPs. | 230 * any slave VPs. |
| 205 */ | 231 */ |
| 206 void *VMS__malloc( size_t sizeRequested ) | 232 void *VMS__malloc_on_core( size_t sizeRequested, int procrID ) |
| 207 { | 233 { |
| 208 //============================= MEASUREMENT STUFF ======================== | 234 //============================= MEASUREMENT STUFF ======================== |
| 209 #ifdef MEAS__TIME_MALLOC | 235 #ifdef MEAS__TIME_MALLOC |
| 210 int32 startStamp, endStamp; | 236 int32 startStamp, endStamp; |
| 211 saveLowTimeStampCountInto( startStamp ); | 237 saveLowTimeStampCountInto( startStamp ); |
| 212 #endif | 238 #endif |
| 213 //======================================================================== | 239 //======================================================================== |
| 214 | 240 |
| 215 MallocArrays* freeLists = _VMSMasterEnv->freeLists; | 241 MallocArrays* freeLists = _VMSMasterEnv->freeLists[procrID]; |
| 216 MallocProlog* foundChunk; | 242 MallocProlog* foundChunk; |
| 243 MallocPrologAllocated* returnChunk; | |
| 217 | 244 |
| 218 //Return a small chunk if the requested size is smaller than 128B | 245 //Return a small chunk if the requested size is smaller than 128B |
| 219 if(sizeRequested <= LOWER_BOUND) | 246 if(sizeRequested <= LOWER_BOUND) |
| 220 { | 247 { |
| 221 uint32 freeListIdx = (sizeRequested-1)/SMALL_CHUNK_SIZE; | 248 uint32 freeListIdx = (sizeRequested-1)/SMALL_CHUNK_SIZE; |
| 222 if(freeLists->smallChunks[freeListIdx] == NULL) | 249 if(freeLists->smallChunks[freeListIdx] == NULL) |
| 223 foundChunk = searchChunk(freeLists, SMALL_CHUNK_SIZE*(freeListIdx+1), 0); | 250 foundChunk = searchChunk(freeLists, SMALL_CHUNK_SIZE*(freeListIdx+1), 0); |
| 224 else | 251 else |
| 225 foundChunk = removeSmallChunk(freeLists, freeListIdx); | 252 foundChunk = removeSmallChunk(freeLists, freeListIdx); |
| 226 | 253 |
| 227 //Mark as allocated | 254 returnChunk = (MallocPrologAllocated*)foundChunk; |
| 228 foundChunk->prevChunkInFreeList = NULL; | 255 returnChunk->prevChunkInFreeList = NULL;//indicates elem currently allocated |
| 229 return foundChunk + 1; | 256 returnChunk->procrID = procrID; |
| 257 return returnChunk + 1; | |
| 230 } | 258 } |
| 231 | 259 |
| 232 //Calculate the expected container. Start one higher to have a Chunk that's | 260 //Calculate the expected container. Start one higher to have a Chunk that's |
| 233 //always big enough. | 261 //always big enough. |
| 234 uint32 containerIdx = getContainer(sizeRequested); | 262 uint32 containerIdx = getContainer(sizeRequested); |
| 237 foundChunk = searchChunk(freeLists, sizeRequested, containerIdx); | 265 foundChunk = searchChunk(freeLists, sizeRequested, containerIdx); |
| 238 else | 266 else |
| 239 foundChunk = removeChunk(freeLists, containerIdx); | 267 foundChunk = removeChunk(freeLists, containerIdx); |
| 240 | 268 |
| 241 //Mark as allocated | 269 //Mark as allocated |
| 242 foundChunk->prevChunkInFreeList = NULL; | 270 returnChunk = (MallocPrologAllocated*)foundChunk; |
| 271 returnChunk->prevChunkInFreeList = NULL;//indicates elem currently allocated | |
| 272 returnChunk->procrID = procrID; | |
| 243 | 273 |
| 244 //============================= MEASUREMENT STUFF ======================== | 274 //============================= MEASUREMENT STUFF ======================== |
| 245 #ifdef MEAS__TIME_MALLOC | 275 #ifdef MEAS__TIME_MALLOC |
| 246 saveLowTimeStampCountInto( endStamp ); | 276 saveLowTimeStampCountInto( endStamp ); |
| 247 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->mallocTimeHist ); | 277 addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->mallocTimeHist ); |
| 248 #endif | 278 #endif |
| 249 //======================================================================== | 279 //======================================================================== |
| 250 | 280 |
| 251 //skip over the prolog by adding its size to the pointer return | 281 //skip over the prolog by adding its size to the pointer return |
| 252 return foundChunk + 1; | 282 return returnChunk + 1; |
| 283 } | |
| 284 | |
| 285 /* | |
| 286 * This free is called for a master loop. It decides whether the allocation of | |
| 287 * chunk was done on the same core. If it was it calls VMS__free_on_core | |
| 288 * otherwise it sends a message to the responsible core. | |
| 289 */ | |
| 290 void | |
| 291 VMS__free(void *ptrToFree) | |
| 292 { | |
| 293 MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1; | |
| 294 if(chunk->procrID == _VMSMasterEnv->currentMasterProcrID) | |
| 295 { | |
| 296 VMS__free_on_core(ptrToFree, _VMSMasterEnv->currentMasterProcrID); | |
| 297 } | |
| 298 else | |
| 299 { | |
| 300 sendFreeReqst_master(chunk->procrID, ptrToFree); | |
| 301 | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 /* | |
| 306 * This free is called for the plugins. It decides whether the allocation of | |
| 307 * chunk was done on the same core. If it was it calls VMS__free_on_core | |
| 308 * otherwise it sends a message to the responsible core. | |
| 309 */ | |
| 310 void | |
| 311 VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc) | |
| 312 { | |
| 313 MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1; | |
| 314 if(chunk->procrID == VProc->coreAnimatedBy) | |
| 315 { | |
| 316 VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy); | |
| 317 } | |
| 318 else | |
| 319 { | |
| 320 sendFreeReqst_lib(chunk->procrID, ptrToFree, VProc); | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 /* | |
| 325 * This is called form a masterVP and request an free from a different masterVP. | |
| 326 * The free of the request structure is done after the request is handled. | |
| 327 */ | |
| 328 inline void | |
| 329 sendFreeReqst_master(int receiverID, void *ptrToFree) | |
| 330 { | |
| 331 InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); | |
| 332 freeReqst->freePtr = ptrToFree; | |
| 333 freeReqst->secondReqType = transfer_free_ptr; | |
| 334 | |
| 335 sendInterMasterReqst(receiverID, (InterMasterReqst*)freeReqst); | |
| 336 } | |
| 337 | |
| 338 /* | |
| 339 * This is called if the free is called from the plugin. This requests an inter | |
| 340 * master request from his master. | |
| 341 */ | |
| 342 inline void | |
| 343 sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr ) | |
| 344 { | |
| 345 VMSSemReq reqData; | |
| 346 InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); | |
| 347 freeReqst->freePtr = ptrToFree; | |
| 348 freeReqst->secondReqType = transfer_free_ptr; | |
| 349 | |
| 350 reqData.reqType = interMasterReqst; | |
| 351 reqData.receiverID = receiverID; | |
| 352 reqData.data = (void*)freeReqst; | |
| 353 | |
| 354 VMS__send_VMSSem_request( (void*)&reqData, animPr ); | |
| 253 } | 355 } |
| 254 | 356 |
| 255 /* | 357 /* |
| 256 * This is sequential code, meant to only be called from the Master, not from | 358 * This is sequential code, meant to only be called from the Master, not from |
| 257 * any slave VPs. | 359 * any slave VPs. |
| 258 */ | 360 */ |
| 259 void | 361 void |
| 260 VMS__free( void *ptrToFree ) | 362 VMS__free_on_core( void *ptrToFree, int procrID ) |
| 261 { | 363 { |
| 262 | 364 |
| 263 //============================= MEASUREMENT STUFF ======================== | 365 //============================= MEASUREMENT STUFF ======================== |
| 264 #ifdef MEAS__TIME_MALLOC | 366 #ifdef MEAS__TIME_MALLOC |
| 265 int32 startStamp, endStamp; | 367 int32 startStamp, endStamp; |
| 266 saveLowTimeStampCountInto( startStamp ); | 368 saveLowTimeStampCountInto( startStamp ); |
| 267 #endif | 369 #endif |
| 268 //======================================================================== | 370 //======================================================================== |
| 269 | 371 |
| 270 MallocArrays* freeLists = _VMSMasterEnv->freeLists; | 372 MallocArrays* freeLists = _VMSMasterEnv->freeLists[procrID]; |
| 271 MallocProlog *chunkToFree = (MallocProlog*)ptrToFree - 1; | 373 MallocProlog *chunkToFree = (MallocProlog*)ptrToFree - 1; |
| 272 uint32 containerIdx; | 374 uint32 containerIdx; |
| 273 | 375 |
| 274 //Check for free neighbors | 376 //Check for free neighbors |
| 275 if(chunkToFree->nextLowerInMem) | 377 if(chunkToFree->nextLowerInMem) |
| 321 */ | 423 */ |
| 322 MallocArrays * | 424 MallocArrays * |
| 323 VMS_ext__create_free_list() | 425 VMS_ext__create_free_list() |
| 324 { | 426 { |
| 325 //Initialize containers for small chunks and fill with zeros | 427 //Initialize containers for small chunks and fill with zeros |
| 326 _VMSMasterEnv->freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) ); | 428 MallocArrays *freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) ); |
| 327 MallocArrays *freeLists = _VMSMasterEnv->freeLists; | |
| 328 | 429 |
| 329 freeLists->smallChunks = | 430 freeLists->smallChunks = |
| 330 (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); | 431 (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); |
| 331 memset((void*)freeLists->smallChunks, | 432 memset((void*)freeLists->smallChunks, |
| 332 0,SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); | 433 0,SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); |
| 353 firstChunk->nextLowerInMem = NULL; | 454 firstChunk->nextLowerInMem = NULL; |
| 354 firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + | 455 firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + |
| 355 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog*)); | 456 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog*)); |
| 356 firstChunk->nextChunkInFreeList = NULL; | 457 firstChunk->nextChunkInFreeList = NULL; |
| 357 //previous element in the queue is the container | 458 //previous element in the queue is the container |
| 358 firstChunk->prevChunkInFreeList = &freeLists->bigChunks[container-2]; | 459 firstChunk->prevChunkInFreeList = (MallocProlog*)&freeLists->bigChunks[container-2]; |
| 359 | 460 |
| 360 freeLists->bigChunks[container-2] = firstChunk; | 461 freeLists->bigChunks[container-2] = firstChunk; |
| 361 //Insert into bit search list | 462 //Insert into bit search list |
| 362 if(container <= 65) | 463 if(container <= 65) |
| 363 freeLists->bigChunksSearchVector[0] |= ((uint64)1 << (container-2)); | 464 freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2)); |
| 364 else | 465 else |
| 365 freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (container-66)); | 466 freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66)); |
| 366 | 467 |
| 367 //Create dummy chunk to mark the top of stack this is of course | 468 //Create dummy chunk to mark the top of stack this is of course |
| 368 //never freed | 469 //never freed |
| 369 MallocProlog *dummyChunk = firstChunk->nextHigherInMem; | 470 MallocProlog *dummyChunk = firstChunk->nextHigherInMem; |
| 370 dummyChunk->nextHigherInMem = dummyChunk+1; | 471 dummyChunk->nextHigherInMem = dummyChunk+1; |
| 382 VMS_ext__free_free_list( MallocArrays *freeLists ) | 483 VMS_ext__free_free_list( MallocArrays *freeLists ) |
| 383 { | 484 { |
| 384 free(freeLists->memSpace); | 485 free(freeLists->memSpace); |
| 385 free(freeLists->bigChunks); | 486 free(freeLists->bigChunks); |
| 386 free(freeLists->smallChunks); | 487 free(freeLists->smallChunks); |
| 387 | 488 free(freeLists); |
| 388 } | 489 } |
| 389 | 490 |
