comparison vmalloc.c @ 134:a9b72021f053

Distributed memory management w/o free requests working
author Merten Sach <msach@mailbox.tu-berlin.de>
date Fri, 16 Sep 2011 16:19:24 +0200
parents dbfc8382d546
children 0b49fd35afc1
comparison
equal deleted inserted replaced
21:2ea90c770565 22:0877c22b1191
10 #include <malloc.h> 10 #include <malloc.h>
11 #include <inttypes.h> 11 #include <inttypes.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <stdio.h> 13 #include <stdio.h>
14 14
15 #include "ProcrContext.h" 15 #include "VMS.h"
16 #include "Histogram/Histogram.h" 16 #include "Histogram/Histogram.h"
17 17
18 /*Helper function 18 /*Helper function
19 *Insert a newly generated free chunk into the first spot on the free list. 19 *Insert a newly generated free chunk into the first spot on the free list.
20 * The chunk is cast as a MallocProlog, so the various pointers in it are 20 * The chunk is cast as a MallocProlog, so the various pointers in it are
68 VMS__malloc_on_core( size_t sizeRequested, int procrID) 68 VMS__malloc_on_core( size_t sizeRequested, int procrID)
69 { MallocProlog *foundElem = NULL, *currElem, *newElem; 69 { MallocProlog *foundElem = NULL, *currElem, *newElem;
70 MallocPrologAllocated *returnElem; 70 MallocPrologAllocated *returnElem;
71 ssize_t amountExtra, sizeConsumed,sizeOfFound; 71 ssize_t amountExtra, sizeConsumed,sizeOfFound;
72 uint32 foundElemIsTopOfHeap; 72 uint32 foundElemIsTopOfHeap;
73
74 printf("Malloc on core %d\n", procrID);
73 75
74 //============================= MEASUREMENT STUFF ======================== 76 //============================= MEASUREMENT STUFF ========================
75 #ifdef MEAS__TIME_MALLOC 77 #ifdef MEAS__TIME_MALLOC
76 int32 startStamp, endStamp; 78 int32 startStamp, endStamp;
77 saveLowTimeStampCountInto( startStamp ); 79 saveLowTimeStampCountInto( startStamp );
78 #endif 80 #endif
79 //======================================================================== 81 //========================================================================
80 82
81 //step up the size to be aligned at 16-byte boundary, prob better ways 83 //step up the size to be aligned at 16-byte boundary, prob better ways
82 sizeRequested = (sizeRequested + 16) & ~15; 84 sizeRequested = (sizeRequested + 16) & ~15;
83 currElem = (_VMSMasterEnv->freeListHead[_VMSMasterEnv->currentMasterProcrID]) 85 currElem = (_VMSMasterEnv->freeListHead[procrID])
84 ->nextChunkInFreeList; 86 ->nextChunkInFreeList;
85 87
86 while( currElem != NULL ) 88 while( currElem != NULL )
87 { //check if size of currElem is big enough 89 { //check if size of currElem is big enough
88 sizeOfFound=(size_t)((uintptr_t)currElem->nextHigherInMem -(uintptr_t)currElem); 90 sizeOfFound=(size_t)((uintptr_t)currElem->nextHigherInMem -(uintptr_t)currElem);
103 //Using a kludge to identify the element that is the top chunk in the 105 //Using a kludge to identify the element that is the top chunk in the
104 // heap -- saving top-of-heap addr in head's nextHigherInMem -- and 106 // heap -- saving top-of-heap addr in head's nextHigherInMem -- and
105 // save addr of start of heap in head's nextLowerInMem 107 // save addr of start of heap in head's nextLowerInMem
106 //Will handle top of Heap specially 108 //Will handle top of Heap specially
107 foundElemIsTopOfHeap = foundElem->nextHigherInMem == 109 foundElemIsTopOfHeap = foundElem->nextHigherInMem ==
108 _VMSMasterEnv->freeListHead->nextHigherInMem; 110 _VMSMasterEnv->freeListHead[procrID]->nextHigherInMem;
109 111
110 //before shave off and try to insert new elem, remove found elem 112 //before shave off and try to insert new elem, remove found elem
111 //note, foundElem will never be the head, so always has valid prevChunk 113 //note, foundElem will never be the head, so always has valid prevChunk
112 foundElem->prevChunkInFreeList->nextChunkInFreeList = 114 foundElem->prevChunkInFreeList->nextChunkInFreeList =
113 foundElem->nextChunkInFreeList; 115 foundElem->nextChunkInFreeList;
122 //if enough, turn extra into new elem & insert it 124 //if enough, turn extra into new elem & insert it
123 if( amountExtra > 64 ) 125 if( amountExtra > 64 )
124 { //make new elem by adding to addr of curr elem then casting 126 { //make new elem by adding to addr of curr elem then casting
125 sizeConsumed = sizeof(MallocProlog) + sizeRequested; 127 sizeConsumed = sizeof(MallocProlog) + sizeRequested;
126 newElem = (MallocProlog *)( (uintptr_t)returnElem + sizeConsumed ); 128 newElem = (MallocProlog *)( (uintptr_t)returnElem + sizeConsumed );
127 newElem->nextLowerInMem = returnElem; //This is evil (but why?) 129 newElem->nextLowerInMem = (MallocProlog*)returnElem;
128 newElem->nextHigherInMem = returnElem->nextHigherInMem; //This is evil (but why?) 130 newElem->nextHigherInMem = returnElem->nextHigherInMem;
129 returnElem->nextHigherInMem = newElem; 131 returnElem->nextHigherInMem = newElem;
130 if( ! foundElemIsTopOfHeap ) 132 if( ! foundElemIsTopOfHeap )
131 { //there is no next higher for top of heap, so can't write to it 133 { //there is no next higher for top of heap, so can't write to it
132 newElem->nextHigherInMem->nextLowerInMem = newElem; 134 newElem->nextHigherInMem->nextLowerInMem = newElem;
133 } 135 }
134 add_chunk_to_free_list( newElem, _VMSMasterEnv->freeListHead ); 136 add_chunk_to_free_list( newElem, _VMSMasterEnv->freeListHead[procrID] );
135 } 137 }
136 else 138 else
137 { 139 {
138 sizeConsumed = sizeOfFound; 140 sizeConsumed = sizeOfFound;
139 } 141 }
156 * otherwise it sends a message to the responsible core. 158 * otherwise it sends a message to the responsible core.
157 */ 159 */
158 void 160 void
159 VMS__free(void *ptrToFree) 161 VMS__free(void *ptrToFree)
160 { 162 {
161 MallocPrologAllocated chunk = (MallocPrologAllocated*)ptrToFree - 1; 163 MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1;
162 if(chunk->procrID == _VMSMasterEnv->currentMasterProcrID) 164 if(chunk->procrID == _VMSMasterEnv->currentMasterProcrID)
163 { 165 {
164 VMS__free_on_core(ptrToFree, _VMSMasterEnv->currentMasterProcrID); 166 VMS__free_on_core(ptrToFree, _VMSMasterEnv->currentMasterProcrID);
165 } 167 }
166 else 168 else
175 * otherwise it sends a message to the responsible core. 177 * otherwise it sends a message to the responsible core.
176 */ 178 */
177 void 179 void
178 VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc) 180 VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc)
179 { 181 {
180 MallocPrologAllocated chunk = (MallocPrologAllocated*)ptrToFree - 1; 182 MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1;
183 printf("Free from core %d for core %d\n", VProc->coreAnimatedBy, chunk->procrID);
181 if(chunk->procrID == VProc->coreAnimatedBy) 184 if(chunk->procrID == VProc->coreAnimatedBy)
182 { 185 {
183 VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy); 186 VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy);
184 } 187 }
185 else 188 else
204 #ifdef MEAS__TIME_MALLOC 207 #ifdef MEAS__TIME_MALLOC
205 int32 startStamp, endStamp; 208 int32 startStamp, endStamp;
206 saveLowTimeStampCountInto( startStamp ); 209 saveLowTimeStampCountInto( startStamp );
207 #endif 210 #endif
208 //======================================================================== 211 //========================================================================
209 212
210 if( ptrToFree < (void*)_VMSMasterEnv->freeListHead->nextLowerInMem || 213 MallocProlog* masterListHead = _VMSMasterEnv->freeListHead[procrID];
211 ptrToFree > (void*)_VMSMasterEnv->freeListHead->nextHigherInMem ) 214
215 if( ptrToFree < (void*)masterListHead->nextLowerInMem ||
216 ptrToFree > (void*)masterListHead->nextHigherInMem )
212 { //outside the range of data owned by VMS's malloc, so do nothing 217 { //outside the range of data owned by VMS's malloc, so do nothing
213 return; 218 return;
214 } 219 }
215 //subtract size of prolog to get pointer to prolog, then cast 220 //subtract size of prolog to get pointer to prolog, then cast
216 elemToFree = (MallocProlog *)((uintptr_t)ptrToFree - sizeof(MallocProlog)); 221 elemToFree = (MallocProlog *)((uintptr_t)ptrToFree - sizeof(MallocProlog));
248 nextHigherElem->prevChunkInFreeList; 253 nextHigherElem->prevChunkInFreeList;
249 //Now, fix-up sequence-in-mem list -- by side-effect, this also 254 //Now, fix-up sequence-in-mem list -- by side-effect, this also
250 // changes size of the lower elem, which is still in free-list 255 // changes size of the lower elem, which is still in free-list
251 nextLowerElem->nextHigherInMem = nextHigherElem->nextHigherInMem; 256 nextLowerElem->nextHigherInMem = nextHigherElem->nextHigherInMem;
252 if( nextHigherElem->nextHigherInMem != 257 if( nextHigherElem->nextHigherInMem !=
253 _VMSMasterEnv->freeListHead->nextHigherInMem ) 258 masterListHead->nextHigherInMem )
254 nextHigherElem->nextHigherInMem->nextLowerInMem = nextLowerElem; 259 nextHigherElem->nextHigherInMem->nextLowerInMem = nextLowerElem;
255 //notice didn't do anything to elemToFree -- it simply is no 260 //notice didn't do anything to elemToFree -- it simply is no
256 // longer reachable from any of the lists. Wonder if could be a 261 // longer reachable from any of the lists. Wonder if could be a
257 // security leak because left valid addresses in it, 262 // security leak because left valid addresses in it,
258 // but don't care for now. 263 // but don't care for now.
261 { //lower is the only of the two that exists and is free, 266 { //lower is the only of the two that exists and is free,
262 //In this case, no adjustment to free-list, just change mem-list. 267 //In this case, no adjustment to free-list, just change mem-list.
263 // By side-effect, changes size of the lower elem 268 // By side-effect, changes size of the lower elem
264 nextLowerElem->nextHigherInMem = elemToFree->nextHigherInMem; 269 nextLowerElem->nextHigherInMem = elemToFree->nextHigherInMem;
265 if( elemToFree->nextHigherInMem != 270 if( elemToFree->nextHigherInMem !=
266 _VMSMasterEnv->freeListHead->nextHigherInMem ) 271 masterListHead->nextHigherInMem )
267 elemToFree->nextHigherInMem->nextLowerInMem = nextLowerElem; 272 elemToFree->nextHigherInMem->nextLowerInMem = nextLowerElem;
268 } 273 }
269 } 274 }
270 else 275 else
271 { //lower either doesn't exist or isn't free, so check higher 276 { //lower either doesn't exist or isn't free, so check higher
278 if( elemToFree->nextChunkInFreeList != NULL ) // end-of-list? 283 if( elemToFree->nextChunkInFreeList != NULL ) // end-of-list?
279 elemToFree->nextChunkInFreeList->prevChunkInFreeList =elemToFree; 284 elemToFree->nextChunkInFreeList->prevChunkInFreeList =elemToFree;
280 //Now chg mem-list. By side-effect, changes size of elemToFree 285 //Now chg mem-list. By side-effect, changes size of elemToFree
281 elemToFree->nextHigherInMem = nextHigherElem->nextHigherInMem; 286 elemToFree->nextHigherInMem = nextHigherElem->nextHigherInMem;
282 if( elemToFree->nextHigherInMem != 287 if( elemToFree->nextHigherInMem !=
283 _VMSMasterEnv->freeListHead->nextHigherInMem ) 288 masterListHead->nextHigherInMem )
284 elemToFree->nextHigherInMem->nextLowerInMem = elemToFree; 289 elemToFree->nextHigherInMem->nextLowerInMem = elemToFree;
285 } 290 }
286 else 291 else
287 { //neither lower nor higher is availabe to coalesce so add to list 292 { //neither lower nor higher is availabe to coalesce so add to list
288 // this makes prev chunk ptr non-null, which indicates it's free 293 // this makes prev chunk ptr non-null, which indicates it's free
289 elemToFree->nextChunkInFreeList = 294 elemToFree->nextChunkInFreeList =
290 _VMSMasterEnv->freeListHead->nextChunkInFreeList; 295 masterListHead->nextChunkInFreeList;
291 _VMSMasterEnv->freeListHead->nextChunkInFreeList = elemToFree; 296 masterListHead->nextChunkInFreeList = elemToFree;
292 if( elemToFree->nextChunkInFreeList != NULL ) // end-of-list? 297 if( elemToFree->nextChunkInFreeList != NULL ) // end-of-list?
293 elemToFree->nextChunkInFreeList->prevChunkInFreeList =elemToFree; 298 elemToFree->nextChunkInFreeList->prevChunkInFreeList =elemToFree;
294 elemToFree->prevChunkInFreeList = _VMSMasterEnv->freeListHead; 299 elemToFree->prevChunkInFreeList = masterListHead;
295 } 300 }
296 } 301 }
297 //============================= MEASUREMENT STUFF ======================== 302 //============================= MEASUREMENT STUFF ========================
298 #ifdef MEAS__TIME_MALLOC 303 #ifdef MEAS__TIME_MALLOC
299 saveLowTimeStampCountInto( endStamp ); 304 saveLowTimeStampCountInto( endStamp );
374 { MallocProlog *freeListHead, *firstChunk; 379 { MallocProlog *freeListHead, *firstChunk;
375 380
376 //Note, this is running in the main thread -- all increases in malloc 381 //Note, this is running in the main thread -- all increases in malloc
377 // mem and all frees of it must be done in this thread, with the 382 // mem and all frees of it must be done in this thread, with the
378 // thread's original stack available 383 // thread's original stack available
384
379 freeListHead = malloc( sizeof(MallocProlog) ); 385 freeListHead = malloc( sizeof(MallocProlog) );
380 firstChunk = malloc( MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE ); 386 firstChunk = malloc( MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE );
381 if( firstChunk == NULL ) {printf("malloc error\n"); exit(1);} 387 if( firstChunk == NULL ) {printf("malloc error\n"); exit(1);}
382 388
383 //Touch memory to avoid page faults 389 //Touch memory to avoid page faults
410 416
411 417
412 /*Designed to be called from the main thread outside of VMS, during cleanup 418 /*Designed to be called from the main thread outside of VMS, during cleanup
413 */ 419 */
414 void 420 void
415 VMS_ext__free_free_list( MallocProlog *freeListHead ) 421 VMS_ext__free_free_list( MallocProlog* freeListHeads[] )
416 { 422 {
417 //stashed a ptr to the one and only bug chunk malloc'd from OS in the 423 //stashed a ptr to the one and only bug chunk malloc'd from OS in the
418 // free list head's next lower in mem pointer 424 // free list head's next lower in mem pointer
419 free( freeListHead->nextLowerInMem ); 425 int i;
420 426 for(i=0; i<NUM_CORES; i++)
427 {
428 free( freeListHeads[i]->nextLowerInMem );
429 }
421 //don't free the head -- it'll be in an array eventually -- free whole 430 //don't free the head -- it'll be in an array eventually -- free whole
422 // array when all the free lists linked from it have already been freed 431 // array when all the free lists linked from it have already been freed
423 } 432 }
424 433