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