diff 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
line diff
     1.1 --- a/vmalloc.c	Wed Sep 07 19:36:46 2011 +0200
     1.2 +++ b/vmalloc.c	Mon Sep 19 16:12:01 2011 +0200
     1.3 @@ -19,6 +19,12 @@
     1.4  
     1.5  #define MAX_UINT64 0xFFFFFFFFFFFFFFFF
     1.6  
     1.7 +inline void
     1.8 +sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr);
     1.9 +
    1.10 +inline void
    1.11 +sendFreeReqst_master(int receiverID, void *ptrToFree);
    1.12 +
    1.13  //A MallocProlog is a head element if the HigherInMem variable is NULL
    1.14  //A Chunk is free if the prevChunkInFreeList variable is NULL
    1.15  
    1.16 @@ -198,12 +204,32 @@
    1.17      return foundChunk;
    1.18  }
    1.19  
    1.20 +/*
    1.21 + * This function is called by code which is part of the master loop.
    1.22 + * This reads the animating coreID from the MasterEnv and calls the normal malloc
    1.23 + * in VMS__malloc_on_core
    1.24 + */
    1.25 +void *
    1.26 +VMS__malloc( size_t sizeRequested)
    1.27 +{
    1.28 +    return VMS__malloc_on_core(sizeRequested, _VMSMasterEnv->currentMasterProcrID);
    1.29 +}
    1.30 +
    1.31 +/*
    1.32 + * This is called by the plugin. This call to VMS_malloc_on_core is run on the
    1.33 + * slave VPs stack so there is no switch to the VMS runtime.
    1.34 + */
    1.35 +void *
    1.36 +VMS__malloc_in_lib(size_t sizeRequested, VirtProcr *VProcr)
    1.37 +{
    1.38 +    return VMS__malloc_on_core(sizeRequested, VProcr->coreAnimatedBy);
    1.39 +}
    1.40  
    1.41  /*
    1.42   * This is sequential code, meant to only be called from the Master, not from
    1.43   * any slave VPs.
    1.44   */
    1.45 -void *VMS__malloc( size_t sizeRequested )
    1.46 +void *VMS__malloc_on_core( size_t sizeRequested, int procrID )
    1.47   {     
    1.48     //============================= MEASUREMENT STUFF ========================
    1.49     #ifdef MEAS__TIME_MALLOC
    1.50 @@ -212,8 +238,9 @@
    1.51     #endif
    1.52     //========================================================================
    1.53     
    1.54 -   MallocArrays* freeLists = _VMSMasterEnv->freeLists;
    1.55 +   MallocArrays* freeLists = _VMSMasterEnv->freeLists[procrID];
    1.56     MallocProlog* foundChunk;
    1.57 +   MallocPrologAllocated* returnChunk;
    1.58     
    1.59     //Return a small chunk if the requested size is smaller than 128B
    1.60     if(sizeRequested <= LOWER_BOUND)
    1.61 @@ -224,9 +251,10 @@
    1.62         else
    1.63             foundChunk = removeSmallChunk(freeLists, freeListIdx);
    1.64         
    1.65 -       //Mark as allocated
    1.66 -       foundChunk->prevChunkInFreeList = NULL;      
    1.67 -       return foundChunk + 1;
    1.68 +       returnChunk = (MallocPrologAllocated*)foundChunk;
    1.69 +       returnChunk->prevChunkInFreeList = NULL;//indicates elem currently allocated
    1.70 +       returnChunk->procrID = procrID;  
    1.71 +       return returnChunk + 1;
    1.72     }
    1.73     
    1.74     //Calculate the expected container. Start one higher to have a Chunk that's
    1.75 @@ -239,7 +267,9 @@
    1.76         foundChunk = removeChunk(freeLists, containerIdx); 
    1.77     
    1.78     //Mark as allocated
    1.79 -   foundChunk->prevChunkInFreeList = NULL;      
    1.80 +   returnChunk = (MallocPrologAllocated*)foundChunk;
    1.81 +   returnChunk->prevChunkInFreeList = NULL;//indicates elem currently allocated
    1.82 +   returnChunk->procrID = procrID;
    1.83     
    1.84     //============================= MEASUREMENT STUFF ========================
    1.85     #ifdef MEAS__TIME_MALLOC
    1.86 @@ -249,7 +279,79 @@
    1.87     //========================================================================
    1.88     
    1.89     //skip over the prolog by adding its size to the pointer return
    1.90 -   return foundChunk + 1;
    1.91 +   return returnChunk + 1;
    1.92 + }
    1.93 + 
    1.94 + /*
    1.95 + * This free is called for a master loop. It decides whether the allocation of
    1.96 + * chunk was done on the same core. If it was it calls VMS__free_on_core 
    1.97 + * otherwise it sends a message to the responsible core.
    1.98 + */
    1.99 +void
   1.100 +VMS__free(void *ptrToFree)
   1.101 +{
   1.102 +    MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1;
   1.103 +    if(chunk->procrID == _VMSMasterEnv->currentMasterProcrID)
   1.104 +    {
   1.105 +        VMS__free_on_core(ptrToFree, _VMSMasterEnv->currentMasterProcrID);
   1.106 +    }
   1.107 +    else
   1.108 +    {
   1.109 +        sendFreeReqst_master(chunk->procrID, ptrToFree);
   1.110 +        
   1.111 +    }
   1.112 +}
   1.113 +
   1.114 +/*
   1.115 + * This free is called for the plugins. It decides whether the allocation of
   1.116 + * chunk was done on the same core. If it was it calls VMS__free_on_core 
   1.117 + * otherwise it sends a message to the responsible core.
   1.118 + */
   1.119 +void
   1.120 +VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc)
   1.121 +{
   1.122 +    MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1;
   1.123 +    if(chunk->procrID == VProc->coreAnimatedBy)
   1.124 +    {
   1.125 +        VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy);
   1.126 +    }
   1.127 +    else
   1.128 +    {
   1.129 +        sendFreeReqst_lib(chunk->procrID, ptrToFree, VProc);
   1.130 +    }
   1.131 +}
   1.132 +
   1.133 +/* 
   1.134 + * This is called form a masterVP and request an free from a different masterVP.
   1.135 + * The free of the request structure is done after the request is handled.
   1.136 + */
   1.137 +inline void
   1.138 +sendFreeReqst_master(int receiverID, void *ptrToFree)
   1.139 +{
   1.140 +   InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst));
   1.141 +   freeReqst->freePtr = ptrToFree;
   1.142 +   freeReqst->secondReqType = transfer_free_ptr;
   1.143 +
   1.144 +   sendInterMasterReqst(receiverID, (InterMasterReqst*)freeReqst);
   1.145 + }
   1.146 +
   1.147 +/*
   1.148 + * This is called if the free is called from the plugin. This requests an inter
   1.149 + * master request from his master.
   1.150 + */
   1.151 +inline void
   1.152 +sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr )
   1.153 +{
   1.154 +   VMSSemReq reqData;
   1.155 +   InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst));
   1.156 +   freeReqst->freePtr = ptrToFree;
   1.157 +   freeReqst->secondReqType = transfer_free_ptr;
   1.158 +
   1.159 +   reqData.reqType  = interMasterReqst;
   1.160 +   reqData.receiverID   = receiverID;
   1.161 +   reqData.data  = (void*)freeReqst;
   1.162 +
   1.163 +   VMS__send_VMSSem_request( (void*)&reqData, animPr );
   1.164   }
   1.165  
   1.166  /*
   1.167 @@ -257,7 +359,7 @@
   1.168   * any slave VPs.
   1.169   */
   1.170  void
   1.171 -VMS__free( void *ptrToFree )
   1.172 +VMS__free_on_core( void *ptrToFree, int procrID )
   1.173   {
   1.174      
   1.175     //============================= MEASUREMENT STUFF ========================
   1.176 @@ -267,7 +369,7 @@
   1.177     #endif
   1.178     //========================================================================
   1.179     
   1.180 -   MallocArrays* freeLists = _VMSMasterEnv->freeLists;
   1.181 +   MallocArrays* freeLists = _VMSMasterEnv->freeLists[procrID];
   1.182     MallocProlog *chunkToFree = (MallocProlog*)ptrToFree - 1;
   1.183     uint32 containerIdx;
   1.184     
   1.185 @@ -323,8 +425,7 @@
   1.186  VMS_ext__create_free_list()
   1.187  {     
   1.188     //Initialize containers for small chunks and fill with zeros
   1.189 -   _VMSMasterEnv->freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) );
   1.190 -   MallocArrays *freeLists = _VMSMasterEnv->freeLists;
   1.191 +   MallocArrays *freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) );
   1.192     
   1.193     freeLists->smallChunks = 
   1.194             (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*));
   1.195 @@ -355,14 +456,14 @@
   1.196                          MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog*));
   1.197     firstChunk->nextChunkInFreeList = NULL;
   1.198     //previous element in the queue is the container
   1.199 -   firstChunk->prevChunkInFreeList = &freeLists->bigChunks[container-2];
   1.200 +   firstChunk->prevChunkInFreeList = (MallocProlog*)&freeLists->bigChunks[container-2];
   1.201     
   1.202     freeLists->bigChunks[container-2] = firstChunk;
   1.203     //Insert into bit search list
   1.204     if(container <= 65)
   1.205 -       freeLists->bigChunksSearchVector[0] |= ((uint64)1 << (container-2));
   1.206 +       freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2));
   1.207     else
   1.208 -       freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (container-66));
   1.209 +       freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66));
   1.210     
   1.211     //Create dummy chunk to mark the top of stack this is of course
   1.212     //never freed
   1.213 @@ -384,6 +485,6 @@
   1.214     free(freeLists->memSpace);
   1.215     free(freeLists->bigChunks);
   1.216     free(freeLists->smallChunks);
   1.217 -   
   1.218 +   free(freeLists);   
   1.219   }
   1.220