more changes...think first version of memory allocation exists now
authorbdemsky <bdemsky>
Tue, 21 Jun 2011 00:48:57 +0000 (00:48 +0000)
committerbdemsky <bdemsky>
Tue, 21 Jun 2011 00:48:57 +0000 (00:48 +0000)
Robust/src/Runtime/bamboo/multicoregarbage.c
Robust/src/Runtime/bamboo/multicoregarbage.h
Robust/src/Runtime/bamboo/multicoregccompact.c
Robust/src/Runtime/bamboo/multicoremem.c
Robust/src/Runtime/bamboo/multicoremsg.c

index a3b20e5f7c29d21418901cf38f4032114068fa61..474033e8ab5302e56c013e3d850966d8f1b3b3a8 100644 (file)
@@ -151,25 +151,6 @@ void initGC() {
   gc_output_cache_policy_time=0;
 } 
 
-bool gc_checkAllCoreStatus() {
-  for(int i = 0; i < NUMCORESACTIVE; i++) {
-    if(gccorestatus[i] != 0) {
-      return false;
-    }  
-  }  
-  return true;
-}
-
-// NOTE: should be invoked with interrupts turned off
-bool gc_checkAllCoreStatus_I() {
-  for(int i = 0; i < NUMCORESACTIVE; i++) {
-    if(gccorestatus[i] != 0) {
-      return false;
-    }  
-  }  
-  return true;
-}
-
 void checkMarkStatus_p2() {
   // check if the sum of send objs and receive obj are the same
   // yes->check if the info is the latest; no->go on executing
@@ -227,7 +208,7 @@ void checkMarkStatus() {
     gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
     gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
     // check the status of all cores
-    if (gc_checkAllCoreStatus_I()) {
+    if (gc_checkCoreStatus()) {
       // ask for confirm
       if(!waitconfirm) {
         // the first time found all cores stall
@@ -518,7 +499,7 @@ bool gc(struct garbagelist * stackptr) {
   if(0 == BAMBOO_NUM_OF_CORE) {
     GC_PRINTF("Check if we can do gc or not\n");
     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-    if(!gc_checkAllCoreStatus()) {
+    if(!gc_checkCoreStatus()) {
       // some of the cores are still executing the mutator and did not reach
       // some gc safe point, therefore it is not ready to do gc
       gcflag = true;
index 2ba2550ee4049a62c737751ba33d05980439b842..d66261d7368f307830265b8d86fd587d194a2ef2 100644 (file)
@@ -49,6 +49,10 @@ struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
 volatile unsigned int gccorestatus[NUMCORESACTIVE];//records status of each core
                                                    // 1: running gc
                                                    // 0: stall
+
+volatile unsigned int returnedmem[NUMCORESACTIVE];//records status of each core
+                                                   // 1: running gc
+                                                   // 0: stall
 volatile unsigned int gcnumsendobjs[2][NUMCORESACTIVE];//# of objects sent out
 volatile unsigned int gcnumreceiveobjs[2][NUMCORESACTIVE];//# of objects received
 volatile unsigned int gcnumsrobjs_index;//indicates which entry to record the  
@@ -78,7 +82,8 @@ volatile unsigned int gcmovestartaddr;
 volatile bool gctomove;
 
 //keeps track of memory request master was not able to serve
-unsigned int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
+volatile unsigned int maxusefulmems[NUMCORES4GC]; //record pending mem requests
+volatile unsigned int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
 volatile unsigned int gcmovepending;
 
 // shared memory pointer for pointer mapping tbls
@@ -97,6 +102,22 @@ unsigned int * gcmarktbl;
 
 void * gcbaseva; // base va for shared memory without reserved sblocks
 
+static bool gc_checkCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    if(gccorestatus[i]) {
+      return false;
+    }
+  }  
+  return true;
+}
+
+static void gc_resetCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    gccorestatus[i] = 1;
+  }
+}
+
+
 /* Structure to keep track of free space in block */
 enum blockstatus {
   /* BS_USED indicates that we don't have information for this block yet */
@@ -141,6 +162,10 @@ unsigned int size_cachepolicytbl;
 #define GCNUMBLOCK (NUMCORES4GC+(BAMBOO_SHARED_MEM_SIZE-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE)
 #define GCNUMLOCALBLOCK (GCNUMBLOCK/NUMCORES4GC)
 
+/* This macro defines the smallest memoy chunk the master will hand out to another core during compacting */
+
+#define MINMEMORYCHUNKSIZE 32768
+
 /* This macro waits for the given gc phase */
 #define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
 
@@ -240,7 +265,7 @@ INLINE static unsigned int hostcore(void * ptr) {
   { \
     gccorestatus[BAMBOO_NUM_OF_CORE] = 0; \
     while(f) { \
-      if(gc_checkAllCoreStatus()) { \
+      if(gc_checkCoreStatus()) { \
         break; \
       } \
     } \
@@ -261,7 +286,6 @@ INLINE static unsigned int hostcore(void * ptr) {
 
 void initmulticoregcdata();
 void dismulticoregcdata();
-bool gc_checkAllCoreStatus();
 bool gc(struct garbagelist * stackptr); // core coordinator routine
 void gc_collect(struct garbagelist* stackptr); //core collector routine
 void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
@@ -274,7 +298,7 @@ void gc_master(struct garbagelist * stackptr);
 
 
 void transferMarkResults_I();
-void * gcfindSpareMem_I(unsigned int requiredmem,unsigned int requiredcore);
+void * gcfindSpareMem_I(unsigned INTPTR requiredmem, unsigned INTPTR maxbytesneeded, unsigned int requiredcore);
 
 #define INITMULTICOREGCDATA() initmulticoregcdata()
 #define DISMULTICOREGCDATA() dismulticoregcdata()
index cbb1ba0f94b29d9617609a716f213414650432a4..b7973372cd8f6e19f18e2d127970425f0ecca2e7 100644 (file)
@@ -8,29 +8,14 @@
 
 int gc_countRunningCores() {
   int count=0;
-  for(int i = 0; i < NUMCORES4GC; ++i) {
-    if(gccorestatus[i] != 0) {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    if(returnedmem[i]) {
       count++;
     }
   }
   return count;
 }
 
-bool gc_checkCoreStatus() {
-  for(int i = 0; i < NUMCORES4GC; ++i) {
-    if(gccorestatus[i] != 0) {
-      return false;
-    }
-  }  
-  return true;
-}
-
-void gc_resetCoreStatus() {
-  for(int i = 0; i < NUMCORES4GC; ++i) {
-    gccorestatus[i] = 1;
-  }
-}
-
 void initOrig_Dst(struct moveHelper * orig,struct moveHelper * to) {
   // init the dst ptr
   to->localblocknum = 0;
@@ -57,7 +42,7 @@ void getSpaceRemotely(struct moveHelper *to, unsigned int minimumbytes) {
   //set flag to wait for memory
   gctomove=false;
   //send request for memory
-  send_msg_3(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, minimumbytes);
+  send_msg_4(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, minimumbytes, gccurr_heaptop);
   //wait for flag to be set that we received message
   while(!gctomove) ;
 
@@ -107,11 +92,14 @@ void compacthelper(struct moveHelper * orig,struct moveHelper * to) {
     }
   }
   
-  send_msg_3(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, 0);
+  send_msg_4(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, 0, 0);
 }
 
-void * checkNeighbors(int corenum, unsigned INTPTR requiredmem) {
+void * checkNeighbors_I(int corenum, unsigned INTPTR requiredmem, unsigned INTPTR desiredmem) {
   int minblockindex=allocationinfo.lowestfreeblock/NUMCORES4GC;
+  unsigned INTPTR threshold=(desiredmem<MINMEMORYCHUNKSIZE)? desiredmem: MINMEMORYCHUNKSIZE;
+  unsigned INTPTR memcheck=requiredmem>threshold?requiredmem:threshold;
+
   for(int i=0;i<NUM_CORES2TEST;i++) {
     int neighborcore=core2test[corenum][i];
     if (neighborcore!=-1) {
@@ -120,7 +108,7 @@ void * checkNeighbors(int corenum, unsigned INTPTR requiredmem) {
        struct blockrecord * block=&allocationinfo.blocktable[globalblockindex];
        if (block->status==BS_FREE) {
          unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
-         if (requiredmem<freespace) {
+         if (memcheck<=freespace) {
            //we have a block
            //mark block as used
            block->status=BS_USED;
@@ -135,15 +123,18 @@ void * checkNeighbors(int corenum, unsigned INTPTR requiredmem) {
   return NULL;
 }
 
-void * globalSearch(unsigned int topblock, unsigned INTPTR requiredmem) {
+void * globalSearch_I(unsigned int topblock, unsigned INTPTR requiredmem, unsigned INTPTR desiredmem) {
   unsigned int firstfree=NOFREEBLOCK;
+  unsigned INTPTR threshold=(desiredmem<MINMEMORYCHUNKSIZE)? desiredmem: MINMEMORYCHUNKSIZE;
+  unsigned INTPTR memcheck=requiredmem>threshold?requiredmem:threshold;
+
   for(block_t i=allocationinfo.lowestfreeblock;i<topblock;i++) {
     struct blockrecord * block=&allocationinfo.blocktable[i];
     if (block->status==BS_FREE) {
       if(firstfree==NOFREEBLOCK)
        firstfree=i;
       unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
-      if (requiredmem<freespace) {
+      if (memcheck<=freespace) {
        //we have a block
        //mark block as used
        block->status=BS_USED;
@@ -158,17 +149,69 @@ void * globalSearch(unsigned int topblock, unsigned INTPTR requiredmem) {
   return NULL;
 }
 
+void handleOneMemoryRequest(int core, unsigned int lowestblock) {
+  unsigned INTPTR requiredmem=gcrequiredmems[core];
+  unsigned INTPTR desiredmem=maxusefulmems[core];
+  block_t firstfree=NOFREEBLOCK;
+  unsigned INTPTR threshold=(desiredmem<MINMEMORYCHUNKSIZE)? desiredmem: MINMEMORYCHUNKSIZE;
+  unsigned INTPTR memcheck=requiredmem>threshold?requiredmem:threshold;
+
+  for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) {
+    struct blockrecord * block=&allocationinfo.blocktable[searchblock];
+    if (block->status==BS_FREE) {
+      if(firstfree==NOFREEBLOCK)
+       firstfree=searchblock;
+      unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
+      if (freespace>=memcheck) {
+       //TODO: should check memory block at same level on our own core...if that works, use it to preserve locality
+
+       //we have a block
+       //mark block as used
+       block->status=BS_USED;
+       void *blockptr=OFFSET2BASEVA(searchblock)+gcbaseva;
+       unsigned INTPTR usedspace=((block->usedspace-1)&~BAMBOO_CACHE_LINE_MASK)+BAMBOO_CACHE_LINE_SIZE;
+       allocationinfo.lowestfreeblock=firstfree;
+       //taken care of one block
+       gcmovepending--;
+       void *startaddr=blockptr+usedspace;
+       if(BAMBOO_CHECK_SEND_MODE()) {
+         cache_msg_2_I(core,GCMOVESTART,startaddr);
+       } else {
+         send_msg_2_I(core,GCMOVESTART,startaddr);
+       }
+       return;
+      }
+    }
+  }
+  //this is bad...ran out of memory
+  BAMBOO_EXIT();
+}
+
+void handleMemoryRequests_I() {
+  unsigned int lowestblock=allocationinfo.lowestfreeblock;
+  if (lowestblock==NOFREEBLOCK) {
+    lowestblock=numblockspercore*NUMCORES4GC;
+  }
+  
+  for(int i=0;i < NUMCORES4GC; i++) {
+    if (gcrequiredmems[i]) {
+      handleOneMemoryRequest(i, lowestblock);
+      lowestblock=allocationinfo.lowestfreeblock;
+    }
+  }
+}
+
 /* should be invoked with interrupt turned off */
 
-void * gcfindSpareMem_I(unsigned INTPTR requiredmem,unsigned int requiredcore) {
+void * gcfindSpareMem_I(unsigned INTPTR requiredmem, unsigned INTPTR desiredmem,unsigned int requiredcore) {
   if (allocationinfo.lowestfreeblock!=NOFREEBLOCK) {
     //There are spare blocks
     unsigned int topblock=numblockspercore*NUMCORES4GC;
     void *memblock;
     
-    if (memblock=checkNeighbors(requiredcore, requiredmem)) {
+    if (memblock=checkNeighbors_I(requiredcore, requiredmem, desiredmem)) {
       return memblock;
-    } else if (memblock=globalSearch(topblock, requiredmem)) {
+    } else if (memblock=globalSearch_I(topblock, requiredmem, desiredmem)) {
       return memblock;
     }
   }
@@ -180,19 +223,12 @@ void * gcfindSpareMem_I(unsigned INTPTR requiredmem,unsigned int requiredcore) {
   int count=gc_countRunningCores();
   if (gcmovepending==count) {
     // All cores have stopped...hand out memory as necessary to handle all requests
-    
+    handleMemoryRequests_I();
   }
 
   return NULL;
 } 
 
-bool gcfindSpareMem(unsigned int requiredmem,unsigned int requiredcore) {
-  BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-  bool retval=gcfindSpareMem_I(requiredmem, requiredcore);
-  BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-  return retval;
-}
-
 /* This function is performance critical...  spend more time optimizing it */
 
 unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) {
@@ -246,7 +282,6 @@ unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) {
 
 void compact() {
   BAMBOO_ASSERT(COMPACTPHASE == gc_status_info.gcphase);
-  BAMBOO_CACHE_MF();
   
   // initialize structs for compacting
   struct moveHelper orig={0,NULL,NULL,0,NULL,0,0,0,0};
@@ -287,6 +322,7 @@ void master_compact() {
     // init some data strutures for compact phase
     gcrequiredmems[i] = 0;
     gccorestatus[i] = 1;
+    returnedmem[i] = 1;
     //send start compact messages to all cores
     if(i != STARTUPCORE) {
       send_msg_2(i, GCSTARTCOMPACT, numblockspercore);
@@ -294,7 +330,6 @@ void master_compact() {
       gcblock2fill = numblockspercore;
     }
   }
-  BAMBOO_CACHE_MF();
   GCPROFILE_ITEM();
   // compact phase
   compact();
@@ -305,6 +340,10 @@ void master_compact() {
 
   GCPROFILE_ITEM();
 
+  //just in case we didn't get blocks back...
+  if (allocationinfo.lowestfreeblock=NOFREEBLOCK)
+    allocationinfo.lowestfreeblock=numblockspercore*NUMCORES4GC;
+
   GC_PRINTF("compact phase finished \n");
 }
 
index 7deab55c01564e65769b0fd22744ceff80f2b056..d0ca1a3fa04ce515135223564a73f6b0399c9402 100644 (file)
@@ -16,45 +16,15 @@ INLINE void * mallocmem(int tofindb,
   return mem;
 }
 
-// 06/07/11 add a parameter minremain, it specifies the minimum number of 
-// blocks to leave for each core for local allocation. 
-INLINE void * searchBlock4Mem(int* tofindb, 
-                              int* totest,
-                              int gccorenum,
-                              int isize,
-                              int * allocsize,
-                              int minremain) {
-
-  return NULL;
-}
-
-INLINE void * searchBlock4Mem_global(int* tofindb, 
-                                     int* totest,
-                                     int isize,
-                                     int * allocsize) {
-
-  return NULL;
-}
-
 // Only allocate local mem chunks to each core.
 // If a core has used up its local shared memory, start gc.
 void * localmalloc_I(int coren,
                      int isize,
                      int * allocsize) {
-  void * mem=NULL;
-  int gccorenum=(coren<NUMCORES4GC)?(coren):(coren%NUMCORES4GC);
-  int tofindb=gc_core2block[2*gccorenum];
-  int totest=tofindb;
-  mem=searchBlock4Mem(&tofindb,&totest,gccorenum,isize,allocsize,0);
-  if(mem==NULL) {
-    // no more local mem, do not find suitable block
-    *allocsize=0;
-  }
+  void * mem=globalmalloc_I(coren,isize,allocsize);
   return mem;
 } 
 
-#define LOCALMEMRESERVATION 2
-
 #ifdef SMEMF
 // Allocate the local shared memory to each core with the highest priority,
 // if a core has used up its local shared memory, try to allocate the 
@@ -62,27 +32,8 @@ void * localmalloc_I(int coren,
 void * fixedmalloc_I(int coren,
                      int isize,
                      int * allocsize) {
-  void * mem;
-  int k;
-  int gccorenum=(coren<NUMCORES4GC)?(coren):(coren%NUMCORES4GC);
-  int totest,tofindb;
-  int bound=BAMBOO_SMEM_SIZE_L;
-  int foundsmem=0;
-  int size=0;
-  for(k=0;k<NUM_CORES2TEST;k++) {
-    if(core2test[gccorenum][k]==-1) {
-      // try next neighbour
-      continue;
-    }
-    tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
-    mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((GCNUMBLOCK/NUMCORES4GC)>>LOCALMEMRESERVATION));
-    if(mem!=NULL) {
-      return mem;
-    }
-  }
-  // no more memory available on either coren or its neighbour cores
-  *allocsize=0;
-  return NULL;
+  void * mem=globalmalloc_I(coren,isize,allocsize);
+  return mem;
 } 
 #endif 
 
@@ -96,34 +47,35 @@ void * fixedmalloc_I(int coren,
 void * mixedmalloc_I(int coren,
                      int isize,
                      int * allocsize) {
-  void * mem;
-  int k;
-  int gccorenum=(coren<NUMCORES4GC)?(coren):(coren%NUMCORES4GC);
-  int totest,tofindb;
-  int size=0;
-  for(k=0;k<NUM_CORES2TEST;k++) {
-    if(core2test[gccorenum][k]==-1) {
-      // try next neighbour
-      continue;
-    }
-    tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
-    mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((GCNUMBLOCK/NUMCORES4GC)>>LOCALMEMRESERVATION));
-    if(mem!=NULL) {
-      return mem;
-    }
-  }
-
-  // try allocate globally
-  mem=globalmalloc_I(coren,isize,allocsize);
+  void * mem=globalmalloc_I(coren,isize,allocsize);
   return mem;
 } 
 #endif 
 
 // Allocate all the memory chunks globally, do not consider the host cores
 // When all the shared memory are used up, start gc.
-void * globalmalloc_I(int coren,
-                      int isize,
-                      int * allocsize) {
+void * globalmalloc_I(int coren, unsigned INTPTR memcheck, int * allocsize) {
+  block_t firstfree=NOFREEBLOCK;
+  block_t lowestblock=allocationinfo.lowestfreeblock;
+  for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) {
+    struct blockrecord * block=&allocationinfo.blocktable[searchblock];
+    if (block->status==BS_FREE) {
+      if(firstfree==NOFREEBLOCK)
+       firstfree=searchblock;
+      unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
+      if (freespace>=memcheck) {
+       //we have a block
+       //mark block as used
+       block->status=BS_USED;
+       void *blockptr=OFFSET2BASEVA(searchblock)+gcbaseva;
+       unsigned INTPTR usedspace=((block->usedspace-1)&~BAMBOO_CACHE_LINE_MASK)+BAMBOO_CACHE_LINE_SIZE;
+       allocationinfo.lowestfreeblock=firstfree;
+       void *startaddr=blockptr+usedspace;
+       *allocsize=freespace;
+       return startaddr;
+      }
+    }
+  }
   return NULL;
 } 
 
@@ -149,7 +101,6 @@ void * smemalloc_I(int coren, int isize, int * allocsize) {
   if(mem == NULL) {
     // no enough shared global memory
     // trigger gc
-    *allocsize = 0;
     if(!gcflag) {
       gcflag = true;
       if(!gc_status_info.gcprocessing) {
index 094b615f7fd5f7f9b15346f3383de0f050e6ad70..202fcdbed7e41d3acbf09daedb382c8f9e95f545 100644 (file)
@@ -36,7 +36,7 @@ int msgsizearray[] = {
   4, //GCFINISHPRE,           // 0xE7
   2, //GCFINISHINIT,          // 0xE8
   4, //GCFINISHMARK,          // 0xE9
-  3, //GCFINISHCOMPACT,       // 0xEa
+  4, //GCFINISHCOMPACT,       // 0xEa
   3, //GCRETURNMEM,
   2, //GCFINISHUPDATE,         // 0xEb
   1, //GCFINISH,              // 0xEc
@@ -353,14 +353,13 @@ INLINE void processmsg_memrequest_I() {
   MSG_INDEXINC_I();
   // receive a shared memory request msg
   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
-  int allocsize = 0;
-  void * mem = NULL;
 #ifdef MULTICORE_GC
   if(!gc_status_info.gcprocessing || !gcflag) {
     // either not doing GC or the master core has decided to stop GC but 
     // // still sending msgs to other cores to inform them to stop the GC
 #endif
-    mem = smemalloc_I(data2, data1, &allocsize);
+    int allocsize = 0;
+    void * mem = smemalloc_I(data2, data1, &allocsize);
     if(mem != NULL) {
       // send the start_va to request core, cache the msg first
       if(BAMBOO_CHECK_SEND_MODE()) {
@@ -506,6 +505,9 @@ void processmsg_returnmem_I() {
   BLOCKINDEX(blockindex, heaptop);
   unsigned INTPTR localblocknum=GLOBALBLOCK2LOCAL(blockindex);
 
+  //this core is done as far as memory usage is concerned
+  returnedmem[cnum]=0;
+
   struct blockrecord * blockrecord=&allocationinfo.blocktable[blockindex];
 
   blockrecord->status=BS_FREE;
@@ -537,10 +539,12 @@ INLINE void processmsg_gcfinishcompact_I() {
   MSG_INDEXINC_I();  
   unsigned int bytesneeded = msgdata[msgdataindex];
   MSG_INDEXINC_I(); 
+  unsigned int maxbytesneeded = msgdata[msgdataindex];
+  MSG_INDEXINC_I();
 
   if(bytesneeded > 0) {
     // ask for more mem
-    void * startaddr = gcfindSpareMem_I(bytesneeded, cnum);
+    void * startaddr = gcfindSpareMem_I(bytesneeded, maxbytesneeded, cnum);
     if(startaddr) {
       // cache the msg first
       if(BAMBOO_CHECK_SEND_MODE()) {
@@ -548,6 +552,9 @@ INLINE void processmsg_gcfinishcompact_I() {
       } else {
        send_msg_2_I(cnum,GCMOVESTART,startaddr);
       }
+    } else {
+      maxusefulmems[cnum]=maxbytesneeded;
+      gcrequiredmems[cnum]=bytesneeded;
     }
   } else {
     //done with compacting