Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison vmalloc.c @ 53:42dd44df1bb0
Init changed to only use VMS__malloc & uses VMS__malloc versions of utilities
| author | Me |
|---|---|
| date | Mon, 01 Nov 2010 21:21:32 -0700 |
| parents | 8f7141a9272e |
| children | 3bac84e4e56e |
comparison
equal
deleted
inserted
replaced
| 0:d69b822a5b7a | 1:0d3829b76e44 |
|---|---|
| 6 * | 6 * |
| 7 * Created on November 14, 2009, 9:07 PM | 7 * Created on November 14, 2009, 9:07 PM |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 #include <malloc.h> | 10 #include <malloc.h> |
| 11 #include <stdlib.h> | |
| 11 | 12 |
| 12 #include "VMS.h" | 13 #include "VMS.h" |
| 13 | 14 |
| 14 /*Helper function | 15 /*Helper function |
| 15 *Insert a newly generated free chunk into the first spot on the free list. | 16 *Insert a newly generated free chunk into the first spot on the free list. |
| 121 void | 122 void |
| 122 VMS__free( void *ptrToFree ) | 123 VMS__free( void *ptrToFree ) |
| 123 { MallocProlog *elemToFree, *nextLowerElem, *nextHigherElem; | 124 { MallocProlog *elemToFree, *nextLowerElem, *nextHigherElem; |
| 124 int32 lowerExistsAndIsFree, higherExistsAndIsFree, sizeOfElem; | 125 int32 lowerExistsAndIsFree, higherExistsAndIsFree, sizeOfElem; |
| 125 | 126 |
| 126 if( ptrToFree < _VMSMasterEnv->freeListHead->nextLowerInMem || | 127 if( ptrToFree < (void*)_VMSMasterEnv->freeListHead->nextLowerInMem || |
| 127 ptrToFree > _VMSMasterEnv->freeListHead->nextHigherInMem ) | 128 ptrToFree > (void*)_VMSMasterEnv->freeListHead->nextHigherInMem ) |
| 128 { //outside the range of data owned by VMS's malloc, so do nothing | 129 { //outside the range of data owned by VMS's malloc, so do nothing |
| 129 return; | 130 return; |
| 130 } | 131 } |
| 131 //subtract size of prolog to get pointer to prolog, then cast | 132 //subtract size of prolog to get pointer to prolog, then cast |
| 132 elemToFree = (MallocProlog *)((char *)ptrToFree - sizeof(MallocProlog)); | 133 elemToFree = (MallocProlog *)((char *)ptrToFree - sizeof(MallocProlog)); |
| 133 sizeOfElem =(int32)((char*)elemToFree->nextHigherInMem-(char*)elemToFree); | 134 sizeOfElem =(int32)((char*)elemToFree->nextHigherInMem-(char*)elemToFree); |
| 135 | |
| 136 if( elemToFree->prevChunkInFreeList != NULL ) | |
| 137 { printf( "error: freeing same element twice!" ); exit(1); | |
| 138 } | |
| 139 | |
| 134 _VMSMasterEnv->amtOfOutstandingMem -= sizeOfElem; | 140 _VMSMasterEnv->amtOfOutstandingMem -= sizeOfElem; |
| 135 | 141 |
| 136 nextLowerElem = elemToFree->nextLowerInMem; | 142 nextLowerElem = elemToFree->nextLowerInMem; |
| 137 nextHigherElem = elemToFree->nextHigherInMem; | 143 nextHigherElem = elemToFree->nextHigherInMem; |
| 138 | 144 |
| 207 } | 213 } |
| 208 | 214 |
| 209 } | 215 } |
| 210 | 216 |
| 211 | 217 |
| 218 /*Allocates memory from the external system -- higher overhead | |
| 219 * | |
| 220 *Because of Linux's malloc throwing bizarre random faults when malloc is | |
| 221 * used inside a VMS virtual processor, have to pass this as a request and | |
| 222 * have the core loop do it when it gets around to it -- will look for these | |
| 223 * chores leftover from the previous animation of masterVP the next time it | |
| 224 * goes to animate the masterVP -- so it takes two separate masterVP | |
| 225 * animations, separated by work, to complete an external malloc or | |
| 226 * external free request. | |
| 227 * | |
| 228 *Thinking core loop accepts signals -- just looks if signal-location is | |
| 229 * empty or not -- | |
| 230 */ | |
| 231 void * | |
| 232 VMS__malloc_in_ext( int32 sizeRequested ) | |
| 233 { | |
| 234 /* | |
| 235 //This is running in the master, so no chance for multiple cores to be | |
| 236 // competing for the core's flag. | |
| 237 if( *(_VMSMasterEnv->coreLoopSignalAddr[ 0 ]) != 0 ) | |
| 238 { //something has already signalled to core loop, so save the signal | |
| 239 // and look, next time master animated, to see if can send it. | |
| 240 //Note, the addr to put a signal is in the coreloop's frame, so just | |
| 241 // checks it each time through -- make it volatile to avoid GCC | |
| 242 // optimizations -- it's a coreloop local var that only changes | |
| 243 // after jumping away. The signal includes the addr to send the | |
| 244 //return to -- even if just empty return completion-signal | |
| 245 // | |
| 246 //save the signal in some queue that the master looks at each time | |
| 247 // it starts up -- one loc says if empty for fast common case -- | |
| 248 //something like that -- want to hide this inside this call -- but | |
| 249 // think this has to come as a request -- req handler gives procr | |
| 250 // back to master loop, which gives it back to req handler at point | |
| 251 // it sees that core loop has sent return signal. Something like | |
| 252 // that. | |
| 253 saveTheSignal | |
| 254 | |
| 255 } | |
| 256 coreSigData->type = malloc; | |
| 257 coreSigData->sizeToMalloc = sizeRequested; | |
| 258 coreSigData->locToSignalCompletion = &figureOut; | |
| 259 _VMSMasterEnv->coreLoopSignals[ 0 ] = coreSigData; | |
| 260 */ | |
| 261 //just risk system-stack faults until get this figured out | |
| 262 return malloc( sizeRequested ); | |
| 263 } | |
| 264 | |
| 265 | |
| 266 /*Frees memory that was allocated in the external system -- higher overhead | |
| 267 * | |
| 268 *As noted in external malloc comment, this is clunky 'cause the free has | |
| 269 * to be called in the core loop. | |
| 270 */ | |
| 271 void | |
| 272 VMS__free_in_ext( void *ptrToFree ) | |
| 273 { | |
| 274 //just risk system-stack faults until get this figured out | |
| 275 free( ptrToFree ); | |
| 276 | |
| 277 //TODO: fix this -- so | |
| 278 } | |
| 279 | |
| 280 | |
| 212 /*Designed to be called from the main thread outside of VMS, during init | 281 /*Designed to be called from the main thread outside of VMS, during init |
| 213 */ | 282 */ |
| 214 MallocProlog * | 283 MallocProlog * |
| 215 VMS__create_free_list() | 284 VMS_ext__create_free_list() |
| 216 { MallocProlog *freeListHead, *firstChunk; | 285 { MallocProlog *freeListHead, *firstChunk; |
| 217 | 286 |
| 218 //Note, this is running in the main thread -- all increases in malloc | 287 //Note, this is running in the main thread -- all increases in malloc |
| 219 // mem and all frees of it must be done in this thread, with the | 288 // mem and all frees of it must be done in this thread, with the |
| 220 // thread's original stack available | 289 // thread's original stack available |
| 224 | 293 |
| 225 freeListHead->prevChunkInFreeList = NULL; | 294 freeListHead->prevChunkInFreeList = NULL; |
| 226 //Use this addr to free the heap when cleanup | 295 //Use this addr to free the heap when cleanup |
| 227 freeListHead->nextLowerInMem = firstChunk; | 296 freeListHead->nextLowerInMem = firstChunk; |
| 228 //to identify top-of-heap elem, compare this addr to elem's next higher | 297 //to identify top-of-heap elem, compare this addr to elem's next higher |
| 229 freeListHead->nextHigherInMem = (char *)firstChunk + | 298 freeListHead->nextHigherInMem = (void*)( (char*)firstChunk + |
| 230 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; | 299 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE); |
| 231 freeListHead->nextChunkInFreeList = firstChunk; | 300 freeListHead->nextChunkInFreeList = firstChunk; |
| 232 | 301 |
| 233 firstChunk->nextChunkInFreeList = NULL; | 302 firstChunk->nextChunkInFreeList = NULL; |
| 234 firstChunk->prevChunkInFreeList = freeListHead; | 303 firstChunk->prevChunkInFreeList = freeListHead; |
| 235 //next Higher has to be set to top of chunk, so can calc size in malloc | 304 //next Higher has to be set to top of chunk, so can calc size in malloc |
| 236 firstChunk->nextHigherInMem = (char *)firstChunk + | 305 firstChunk->nextHigherInMem = (void*)( (char*)firstChunk + |
| 237 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; | 306 MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE); |
| 238 firstChunk->nextLowerInMem = NULL; //identifies as bott of heap | 307 firstChunk->nextLowerInMem = NULL; //identifies as bott of heap |
| 308 | |
| 309 _VMSMasterEnv->amtOfOutstandingMem = 0; //none allocated yet | |
| 239 | 310 |
| 240 return freeListHead; | 311 return freeListHead; |
| 241 } | 312 } |
| 242 | 313 |
| 243 | 314 |
