Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
changeset 134:a9b72021f053 Inter-Master Requests
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 | 3a295609f045 |
| children | 0b49fd35afc1 |
| files | MasterLoop.c ProcrContext.c ProcrContext.h VMS.c VMS.h requests.h scheduling.h vmalloc.c vmalloc.h vutilities.c |
| diffstat | 10 files changed, 174 insertions(+), 132 deletions(-) [+] |
line diff
1.1 --- a/MasterLoop.c Fri Sep 16 14:26:18 2011 +0200 1.2 +++ b/MasterLoop.c Fri Sep 16 16:19:24 2011 +0200 1.3 @@ -11,6 +11,7 @@ 1.4 1.5 #include "VMS.h" 1.6 #include "ProcrContext.h" 1.7 +#include "scheduling.h" 1.8 #include "inter_VMS_request_handlers.h" 1.9 1.10 //===========================================================================
2.1 --- a/ProcrContext.c Fri Sep 16 14:26:18 2011 +0200 2.2 +++ b/ProcrContext.c Fri Sep 16 16:19:24 2011 +0200 2.3 @@ -4,6 +4,7 @@ 2.4 2.5 2.6 #include "VMS.h" 2.7 +#include "ProcrContext.h" 2.8 2.9 /*Create stack, then create __cdecl structure on it and put initialData and 2.10 * pointer to the new structure instance into the parameter positions on
3.1 --- a/ProcrContext.h Fri Sep 16 14:26:18 2011 +0200 3.2 +++ b/ProcrContext.h Fri Sep 16 16:19:24 2011 +0200 3.3 @@ -9,10 +9,13 @@ 3.4 #define _ProcrContext_H 3.5 #define _GNU_SOURCE 3.6 3.7 -#include "VMS.h" 3.8 +typedef struct _VirtProcr VirtProcr; 3.9 +typedef struct _VMSReqst VMSReqst; 3.10 +typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); //initData, animPr 3.11 3.12 -typedef struct _SchedSlot SchedSlot; 3.13 -typedef struct _VirtProcr VirtProcr; 3.14 + 3.15 +#include "VMS_primitive_data_types.h" 3.16 +#include "scheduling.h" 3.17 3.18 /*WARNING: re-arranging this data structure could cause VP switching 3.19 * assembly code to fail -- hard-codes offsets of fields 3.20 @@ -52,13 +55,6 @@ 3.21 }; 3.22 //VirtProcr 3.23 3.24 -struct _SchedSlot 3.25 - { 3.26 - int workIsDone; 3.27 - int needsProcrAssigned; 3.28 - VirtProcr *procrAssignedToSlot; 3.29 - }; 3.30 - 3.31 void saveCoreLoopReturnAddr(void **returnAddress); 3.32 3.33 void switchToVP(VirtProcr *nextProcr); 3.34 @@ -72,7 +68,7 @@ 3.35 void *asmTerminateCoreLoop(VirtProcr *currPr); 3.36 3.37 #define flushRegisters() \ 3.38 - asm volatile ("":::"%rbx", "%r12", "%r13","%r14","%r15") 3.39 + asm volatile ("":::"%rbx", "%r12", "%r13","%r14","%r15"); 3.40 3.41 inline VirtProcr * 3.42 create_procr_helper( VirtProcr *newPr, VirtProcrFnPtr fnPtr,
4.1 --- a/VMS.c Fri Sep 16 14:26:18 2011 +0200 4.2 +++ b/VMS.c Fri Sep 16 16:19:24 2011 +0200 4.3 @@ -13,6 +13,7 @@ 4.4 4.5 #include "VMS.h" 4.6 #include "ProcrContext.h" 4.7 +#include "scheduling.h" 4.8 #include "Queue_impl/BlockingQueue.h" 4.9 #include "Histogram/Histogram.h" 4.10 4.11 @@ -109,7 +110,9 @@ 4.12 for(i=0; i<NUM_CORES; i++) 4.13 { 4.14 _VMSMasterEnv->freeListHead[i] = VMS_ext__create_free_list(); 4.15 + _VMSMasterEnv->interMasterRequestsFor[i] = NULL; 4.16 } 4.17 + _VMSMasterEnv->currentMasterProcrID = 0; 4.18 4.19 4.20 //============================= MEASUREMENT STUFF ======================== 4.21 @@ -768,7 +771,7 @@ 4.22 //======================================================================== 4.23 */ 4.24 //These are the only two that use system free 4.25 - VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 4.26 + VMS_ext__free_free_list( _VMSMasterEnv->freeListHead); 4.27 free( (void *)_VMSMasterEnv ); 4.28 } 4.29
5.1 --- a/VMS.h Fri Sep 16 14:26:18 2011 +0200 5.2 +++ b/VMS.h Fri Sep 16 16:19:24 2011 +0200 5.3 @@ -9,16 +9,16 @@ 5.4 #define _VMS_H 5.5 #define _GNU_SOURCE 5.6 5.7 +#include <pthread.h> 5.8 +#include <sys/time.h> 5.9 + 5.10 #include "VMS_primitive_data_types.h" 5.11 #include "Queue_impl/PrivateQueue.h" 5.12 #include "Histogram/Histogram.h" 5.13 #include "DynArray/DynArray.h" 5.14 #include "Hash_impl/PrivateHash.h" 5.15 #include "vmalloc.h" 5.16 - 5.17 -#include <pthread.h> 5.18 -#include <sys/time.h> 5.19 - 5.20 +#include "requests.h" 5.21 5.22 //=============================== Debug =================================== 5.23 // 5.24 @@ -89,7 +89,7 @@ 5.25 #define VIRT_PROCR_STACK_SIZE 0x8000 /* 32K */ 5.26 5.27 // memory for VMS__malloc 5.28 -#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 /* 256M */ 5.29 +#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x4000000 /* 64M */ 5.30 5.31 #define CACHE_LINE 64 5.32 #define PAGE_SIZE 4096 5.33 @@ -110,106 +110,15 @@ 5.34 //=========================================================================== 5.35 typedef unsigned long long TSCount; 5.36 5.37 -typedef struct _VMSReqst VMSReqst; 5.38 -typedef struct _InterMasterReqst InterMasterReqst; 5.39 typedef struct _IntervalProbe IntervalProbe; 5.40 typedef struct _GateStruc GateStruc; 5.41 5.42 5.43 typedef VirtProcr * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx 5.44 typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv 5.45 -typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); //initData, animPr 5.46 -typedef void VirtProcrFn ( void *, VirtProcr * ); //initData, animPr 5.47 typedef void (*ResumePrFnPtr) ( VirtProcr *, void * ); 5.48 5.49 5.50 -//============= Requests =========== 5.51 -// 5.52 - 5.53 -//VMS Request is the carrier for Slave to Master requests 5.54 -// it has an embedded sub-type request that is pulled out 5.55 -// inside the plugin's request handler 5.56 -enum VMSReqstType //For Slave->Master requests 5.57 - { 5.58 - semantic = 1, //avoid starting enums at 0, for debug reasons 5.59 - createReq, 5.60 - dissipate, 5.61 - VMSSemantic //goes with VMSSemReqst below 5.62 - }; 5.63 - 5.64 -struct _VMSReqst 5.65 - { 5.66 - enum VMSReqstType reqType;//used for dissipate and in future for IO requests 5.67 - void *semReqData; 5.68 - 5.69 - VMSReqst *nextReqst; 5.70 - }; 5.71 -//VMSReqst 5.72 - 5.73 -//This is a sub-type of Slave->Master requests. 5.74 -// It's for Slaves to invoke built-in VMS-core functions that have language-like 5.75 -// behavior. 5.76 -enum VMSSemReqstType //These are equivalent to semantic requests, but for 5.77 - { // VMS's services available directly to app, like OS 5.78 - createProbe = 1, // and probe services -- like a VMS-wide built-in lang 5.79 - openFile, 5.80 - otherIO 5.81 - }; 5.82 - 5.83 -typedef struct 5.84 - { enum VMSSemReqstType reqType; 5.85 - VirtProcr *requestingPr; 5.86 - char *nameStr; //for create probe 5.87 - } 5.88 -VMSSemReq; 5.89 - 5.90 -//These are for Master to Master requests 5.91 -// They get re-cast to the appropriate sub-type of request 5.92 -enum InterMasterReqstType //For Master->Master 5.93 - { 5.94 - destVMSCore = 1, //avoid starting enums at 0, for debug reasons 5.95 - destPlugin 5.96 - }; 5.97 - 5.98 -struct _InterMasterReqst //Doing a trick to save space & time -- allocate 5.99 - { // space for a sub-type then cast first as InterMaster then as sub-type 5.100 - enum InterMasterReqstType reqType; 5.101 - InterMasterReqst *nextReqst; 5.102 - }; 5.103 -//InterMasterReqst (defined above in typedef block) 5.104 - 5.105 - 5.106 -//These are a sub-type of InterMaster requests. The inter-master req gets 5.107 -// re-cast to be of this type, after checking 5.108 -//This ones for requests between internals of VMS-core.. such as malloc 5.109 -enum InterVMSCoreReqType 5.110 - { 5.111 - transfer_free_ptr = 1 //avoid starting enums at 0, for debug reasons 5.112 - }; 5.113 - 5.114 -//Doing a trick to save space & time -- allocate space 5.115 -// for this, cast first as InterMaster then as this 5.116 -typedef struct 5.117 - { 5.118 - enum InterMasterReqstType reqType; //duplicate InterMasterReqst at top 5.119 - InterMasterReqst *nextReqst; 5.120 - 5.121 - enum InterVMSCoreReqType secondReqType; 5.122 - void *freePtr; //pile up fields, add as needed 5.123 - } InterVMSCoreReqst; 5.124 - 5.125 -//This is for requests between plugins on different cores 5.126 -// Here, after casting, the pluginReq is extracted and handed to plugin 5.127 -//Doing a trick to save space & time -- allocate space 5.128 -// for this, cast first as InterMaster then as this 5.129 -typedef struct 5.130 - { 5.131 - enum InterMasterReqstType reqType; //copy InterMasterReqst at top 5.132 - InterMasterReqst *nextReqst; 5.133 - 5.134 - void *pluginReq; //plugin will cast to approp type 5.135 - } InterPluginReqst; 5.136 - 5.137 //==================== Core data structures =================== 5.138 5.139 /*Master Env is the only global variable -- has entry points for any other 5.140 @@ -311,8 +220,6 @@ 5.141 volatile MasterEnv *_VMSMasterEnv; 5.142 5.143 5.144 - 5.145 - 5.146 //=========================== Function Prototypes ========================= 5.147 5.148 5.149 @@ -587,7 +494,6 @@ 5.150 5.151 //===== 5.152 5.153 -#include "ProcrContext.h" 5.154 #include "probes.h" 5.155 #include "vutilities.h" 5.156
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/requests.h Fri Sep 16 16:19:24 2011 +0200 6.3 @@ -0,0 +1,103 @@ 6.4 +/* 6.5 + * File: requests.h 6.6 + * Author: msach 6.7 + * 6.8 + * Created on September 16, 2011, 3:11 PM 6.9 + */ 6.10 + 6.11 +#ifndef REQUESTS_H 6.12 +#define REQUESTS_H 6.13 + 6.14 +#include "ProcrContext.h" 6.15 + 6.16 +typedef struct _InterMasterReqst InterMasterReqst; 6.17 + 6.18 +//============= Requests =========== 6.19 +// 6.20 + 6.21 +//VMS Request is the carrier for Slave to Master requests 6.22 +// it has an embedded sub-type request that is pulled out 6.23 +// inside the plugin's request handler 6.24 +enum VMSReqstType //For Slave->Master requests 6.25 + { 6.26 + semantic = 1, //avoid starting enums at 0, for debug reasons 6.27 + createReq, 6.28 + dissipate, 6.29 + VMSSemantic //goes with VMSSemReqst below 6.30 + }; 6.31 + 6.32 +struct _VMSReqst 6.33 + { 6.34 + enum VMSReqstType reqType;//used for dissipate and in future for IO requests 6.35 + void *semReqData; 6.36 + 6.37 + VMSReqst *nextReqst; 6.38 + }; 6.39 +//VMSReqst 6.40 + 6.41 +//This is a sub-type of Slave->Master requests. 6.42 +// It's for Slaves to invoke built-in VMS-core functions that have language-like 6.43 +// behavior. 6.44 +enum VMSSemReqstType //These are equivalent to semantic requests, but for 6.45 + { // VMS's services available directly to app, like OS 6.46 + createProbe = 1, // and probe services -- like a VMS-wide built-in lang 6.47 + openFile, 6.48 + otherIO 6.49 + }; 6.50 + 6.51 +typedef struct 6.52 + { enum VMSSemReqstType reqType; 6.53 + VirtProcr *requestingPr; 6.54 + char *nameStr; //for create probe 6.55 + } 6.56 +VMSSemReq; 6.57 + 6.58 +//These are for Master to Master requests 6.59 +// They get re-cast to the appropriate sub-type of request 6.60 +enum InterMasterReqstType //For Master->Master 6.61 + { 6.62 + destVMSCore = 1, //avoid starting enums at 0, for debug reasons 6.63 + destPlugin 6.64 + }; 6.65 + 6.66 +struct _InterMasterReqst //Doing a trick to save space & time -- allocate 6.67 + { // space for a sub-type then cast first as InterMaster then as sub-type 6.68 + enum InterMasterReqstType reqType; 6.69 + InterMasterReqst *nextReqst; 6.70 + }; 6.71 +//InterMasterReqst (defined above in typedef block) 6.72 + 6.73 + 6.74 +//These are a sub-type of InterMaster requests. The inter-master req gets 6.75 +// re-cast to be of this type, after checking 6.76 +//This ones for requests between internals of VMS-core.. such as malloc 6.77 +enum InterVMSCoreReqType 6.78 + { 6.79 + transfer_free_ptr = 1 //avoid starting enums at 0, for debug reasons 6.80 + }; 6.81 + 6.82 +//Doing a trick to save space & time -- allocate space 6.83 +// for this, cast first as InterMaster then as this 6.84 +typedef struct 6.85 + { 6.86 + enum InterMasterReqstType reqType; //duplicate InterMasterReqst at top 6.87 + InterMasterReqst *nextReqst; 6.88 + 6.89 + enum InterVMSCoreReqType secondReqType; 6.90 + void *freePtr; //pile up fields, add as needed 6.91 + } InterVMSCoreReqst; 6.92 + 6.93 +//This is for requests between plugins on different cores 6.94 +// Here, after casting, the pluginReq is extracted and handed to plugin 6.95 +//Doing a trick to save space & time -- allocate space 6.96 +// for this, cast first as InterMaster then as this 6.97 +typedef struct 6.98 + { 6.99 + enum InterMasterReqstType reqType; //copy InterMasterReqst at top 6.100 + InterMasterReqst *nextReqst; 6.101 + 6.102 + void *pluginReq; //plugin will cast to approp type 6.103 + } InterPluginReqst; 6.104 + 6.105 +#endif /* REQUESTS_H */ 6.106 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/scheduling.h Fri Sep 16 16:19:24 2011 +0200 7.3 @@ -0,0 +1,23 @@ 7.4 +/* 7.5 + * File: scheduling.h 7.6 + * Author: msach 7.7 + * 7.8 + * Created on September 16, 2011, 2:28 PM 7.9 + */ 7.10 + 7.11 +#ifndef SCHEDULING_H 7.12 +#define SCHEDULING_H 7.13 + 7.14 +#include "ProcrContext.h" 7.15 + 7.16 +typedef struct _SchedSlot SchedSlot; 7.17 + 7.18 +struct _SchedSlot 7.19 + { 7.20 + int workIsDone; 7.21 + int needsProcrAssigned; 7.22 + VirtProcr *procrAssignedToSlot; 7.23 + }; 7.24 + 7.25 +#endif /* SCHEDULING_H */ 7.26 +
8.1 --- a/vmalloc.c Fri Sep 16 14:26:18 2011 +0200 8.2 +++ b/vmalloc.c Fri Sep 16 16:19:24 2011 +0200 8.3 @@ -12,7 +12,7 @@ 8.4 #include <stdlib.h> 8.5 #include <stdio.h> 8.6 8.7 -#include "ProcrContext.h" 8.8 +#include "VMS.h" 8.9 #include "Histogram/Histogram.h" 8.10 8.11 /*Helper function 8.12 @@ -70,6 +70,8 @@ 8.13 MallocPrologAllocated *returnElem; 8.14 ssize_t amountExtra, sizeConsumed,sizeOfFound; 8.15 uint32 foundElemIsTopOfHeap; 8.16 + 8.17 + printf("Malloc on core %d\n", procrID); 8.18 8.19 //============================= MEASUREMENT STUFF ======================== 8.20 #ifdef MEAS__TIME_MALLOC 8.21 @@ -80,7 +82,7 @@ 8.22 8.23 //step up the size to be aligned at 16-byte boundary, prob better ways 8.24 sizeRequested = (sizeRequested + 16) & ~15; 8.25 - currElem = (_VMSMasterEnv->freeListHead[_VMSMasterEnv->currentMasterProcrID]) 8.26 + currElem = (_VMSMasterEnv->freeListHead[procrID]) 8.27 ->nextChunkInFreeList; 8.28 8.29 while( currElem != NULL ) 8.30 @@ -105,7 +107,7 @@ 8.31 // save addr of start of heap in head's nextLowerInMem 8.32 //Will handle top of Heap specially 8.33 foundElemIsTopOfHeap = foundElem->nextHigherInMem == 8.34 - _VMSMasterEnv->freeListHead->nextHigherInMem; 8.35 + _VMSMasterEnv->freeListHead[procrID]->nextHigherInMem; 8.36 8.37 //before shave off and try to insert new elem, remove found elem 8.38 //note, foundElem will never be the head, so always has valid prevChunk 8.39 @@ -124,14 +126,14 @@ 8.40 { //make new elem by adding to addr of curr elem then casting 8.41 sizeConsumed = sizeof(MallocProlog) + sizeRequested; 8.42 newElem = (MallocProlog *)( (uintptr_t)returnElem + sizeConsumed ); 8.43 - newElem->nextLowerInMem = returnElem; //This is evil (but why?) 8.44 - newElem->nextHigherInMem = returnElem->nextHigherInMem; //This is evil (but why?) 8.45 + newElem->nextLowerInMem = (MallocProlog*)returnElem; 8.46 + newElem->nextHigherInMem = returnElem->nextHigherInMem; 8.47 returnElem->nextHigherInMem = newElem; 8.48 if( ! foundElemIsTopOfHeap ) 8.49 { //there is no next higher for top of heap, so can't write to it 8.50 newElem->nextHigherInMem->nextLowerInMem = newElem; 8.51 } 8.52 - add_chunk_to_free_list( newElem, _VMSMasterEnv->freeListHead ); 8.53 + add_chunk_to_free_list( newElem, _VMSMasterEnv->freeListHead[procrID] ); 8.54 } 8.55 else 8.56 { 8.57 @@ -158,7 +160,7 @@ 8.58 void 8.59 VMS__free(void *ptrToFree) 8.60 { 8.61 - MallocPrologAllocated chunk = (MallocPrologAllocated*)ptrToFree - 1; 8.62 + MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1; 8.63 if(chunk->procrID == _VMSMasterEnv->currentMasterProcrID) 8.64 { 8.65 VMS__free_on_core(ptrToFree, _VMSMasterEnv->currentMasterProcrID); 8.66 @@ -177,7 +179,8 @@ 8.67 void 8.68 VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc) 8.69 { 8.70 - MallocPrologAllocated chunk = (MallocPrologAllocated*)ptrToFree - 1; 8.71 + MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1; 8.72 + printf("Free from core %d for core %d\n", VProc->coreAnimatedBy, chunk->procrID); 8.73 if(chunk->procrID == VProc->coreAnimatedBy) 8.74 { 8.75 VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy); 8.76 @@ -206,9 +209,11 @@ 8.77 saveLowTimeStampCountInto( startStamp ); 8.78 #endif 8.79 //======================================================================== 8.80 + 8.81 + MallocProlog* masterListHead = _VMSMasterEnv->freeListHead[procrID]; 8.82 8.83 - if( ptrToFree < (void*)_VMSMasterEnv->freeListHead->nextLowerInMem || 8.84 - ptrToFree > (void*)_VMSMasterEnv->freeListHead->nextHigherInMem ) 8.85 + if( ptrToFree < (void*)masterListHead->nextLowerInMem || 8.86 + ptrToFree > (void*)masterListHead->nextHigherInMem ) 8.87 { //outside the range of data owned by VMS's malloc, so do nothing 8.88 return; 8.89 } 8.90 @@ -250,7 +255,7 @@ 8.91 // changes size of the lower elem, which is still in free-list 8.92 nextLowerElem->nextHigherInMem = nextHigherElem->nextHigherInMem; 8.93 if( nextHigherElem->nextHigherInMem != 8.94 - _VMSMasterEnv->freeListHead->nextHigherInMem ) 8.95 + masterListHead->nextHigherInMem ) 8.96 nextHigherElem->nextHigherInMem->nextLowerInMem = nextLowerElem; 8.97 //notice didn't do anything to elemToFree -- it simply is no 8.98 // longer reachable from any of the lists. Wonder if could be a 8.99 @@ -263,7 +268,7 @@ 8.100 // By side-effect, changes size of the lower elem 8.101 nextLowerElem->nextHigherInMem = elemToFree->nextHigherInMem; 8.102 if( elemToFree->nextHigherInMem != 8.103 - _VMSMasterEnv->freeListHead->nextHigherInMem ) 8.104 + masterListHead->nextHigherInMem ) 8.105 elemToFree->nextHigherInMem->nextLowerInMem = nextLowerElem; 8.106 } 8.107 } 8.108 @@ -280,18 +285,18 @@ 8.109 //Now chg mem-list. By side-effect, changes size of elemToFree 8.110 elemToFree->nextHigherInMem = nextHigherElem->nextHigherInMem; 8.111 if( elemToFree->nextHigherInMem != 8.112 - _VMSMasterEnv->freeListHead->nextHigherInMem ) 8.113 + masterListHead->nextHigherInMem ) 8.114 elemToFree->nextHigherInMem->nextLowerInMem = elemToFree; 8.115 } 8.116 else 8.117 { //neither lower nor higher is availabe to coalesce so add to list 8.118 // this makes prev chunk ptr non-null, which indicates it's free 8.119 elemToFree->nextChunkInFreeList = 8.120 - _VMSMasterEnv->freeListHead->nextChunkInFreeList; 8.121 - _VMSMasterEnv->freeListHead->nextChunkInFreeList = elemToFree; 8.122 + masterListHead->nextChunkInFreeList; 8.123 + masterListHead->nextChunkInFreeList = elemToFree; 8.124 if( elemToFree->nextChunkInFreeList != NULL ) // end-of-list? 8.125 elemToFree->nextChunkInFreeList->prevChunkInFreeList =elemToFree; 8.126 - elemToFree->prevChunkInFreeList = _VMSMasterEnv->freeListHead; 8.127 + elemToFree->prevChunkInFreeList = masterListHead; 8.128 } 8.129 } 8.130 //============================= MEASUREMENT STUFF ======================== 8.131 @@ -376,6 +381,7 @@ 8.132 //Note, this is running in the main thread -- all increases in malloc 8.133 // mem and all frees of it must be done in this thread, with the 8.134 // thread's original stack available 8.135 + 8.136 freeListHead = malloc( sizeof(MallocProlog) ); 8.137 firstChunk = malloc( MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE ); 8.138 if( firstChunk == NULL ) {printf("malloc error\n"); exit(1);} 8.139 @@ -412,12 +418,15 @@ 8.140 /*Designed to be called from the main thread outside of VMS, during cleanup 8.141 */ 8.142 void 8.143 -VMS_ext__free_free_list( MallocProlog *freeListHead ) 8.144 +VMS_ext__free_free_list( MallocProlog* freeListHeads[] ) 8.145 { 8.146 //stashed a ptr to the one and only bug chunk malloc'd from OS in the 8.147 // free list head's next lower in mem pointer 8.148 - free( freeListHead->nextLowerInMem ); 8.149 - 8.150 + int i; 8.151 + for(i=0; i<NUM_CORES; i++) 8.152 + { 8.153 + free( freeListHeads[i]->nextLowerInMem ); 8.154 + } 8.155 //don't free the head -- it'll be in an array eventually -- free whole 8.156 // array when all the free lists linked from it have already been freed 8.157 }
9.1 --- a/vmalloc.h Fri Sep 16 14:26:18 2011 +0200 9.2 +++ b/vmalloc.h Fri Sep 16 16:19:24 2011 +0200 9.3 @@ -67,11 +67,10 @@ 9.4 void 9.5 VMS__free_in_ext( void *ptrToFree ); 9.6 9.7 - 9.8 MallocProlog * 9.9 VMS_ext__create_free_list(); 9.10 9.11 void 9.12 -VMS_ext__free_free_list( MallocProlog *freeListHead ); 9.13 +VMS_ext__free_free_list( MallocProlog* freeListHeads[] ); 9.14 9.15 #endif 9.16 \ No newline at end of file
