changes
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.c
index 95caaa3085bdd39ea46a1e9bb473912f3db74028..90493563666cdf2d3ee66b467408e61613a76341 100644 (file)
@@ -1,19 +1,17 @@
-// TODO: DO NOT support tag!!!
 #ifdef MULTICORE_GC
 #include "runtime.h"
 #include "multicoreruntime.h"
 #include "multicoregarbage.h"
 #include "multicoregcmark.h"
-#include "gcqueue.h"
 #include "multicoregccompact.h"
 #include "multicoregcflush.h"
 #include "multicoregcprofile.h"
 #include "gcqueue.h"
-
-#ifdef SMEMM
-extern unsigned int gcmem_mixed_threshold;
-extern unsigned int gcmem_mixed_usedmem;
-#endif // SMEMM
+#include "multicoremem_helper.h"
+#include "bambooalign.h"
+#ifdef PERFCOUNT
+#include "bme_perf_counter.h"
+#endif
 
 volatile bool gcflag;
 gc_status_t gc_status_info;
@@ -26,7 +24,7 @@ void dumpSMem() {
   int block = 0;
   int sblock = 0;
   unsigned int j = 0;
-  void * i = 0;
+  unsigned int i = 0;
   int coren = 0;
   int x = 0;
   int y = 0;
@@ -34,7 +32,7 @@ void dumpSMem() {
   // reserved blocks for sblocktbl
   printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
         udn_tile_coord_y());
-  for(i=BAMBOO_BASE_VA; (unsinged int)i<(unsigned int)gcbaseva; i+= 4*16) {
+  for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
     printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
         udn_tile_coord_x(), udn_tile_coord_y(),
         *((int *)(i)), *((int *)(i + 4)),
@@ -92,52 +90,53 @@ void dumpSMem() {
 }
 #endif
 
-void initmulticoregcdata() {
-  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
-    // startup core to initialize corestatus[]
-    for(int i = 0; i < NUMCORESACTIVE; i++) {
-      gccorestatus[i] = 1;
-      gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
-      gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
-    } 
-    for(int i = 0; i < NUMCORES4GC; i++) {
-      gcloads[i] = 0;
-      gcrequiredmems[i] = 0;
-      gcstopblock[i] = 0;
-      gcfilledblocks[i] = 0;
+bool gc_checkCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    if(gccorestatus[i]) {
+      return false;
     }
   }
+  return true;
+}
+
+void gc_resetCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    gccorestatus[i] = 1;
+  }
+}
 
+
+void initmulticoregcdata() {
   bamboo_smem_zero_top = NULL;
   gcflag = false;
   gc_status_info.gcprocessing = false;
   gc_status_info.gcphase = FINISHPHASE;
 
   gcprecheck = true;
-  gccurr_heaptop = 0;
-  gcself_numsendobjs = 0;
-  gcself_numreceiveobjs = 0;
-  gcmarkedptrbound = 0;
   gcforwardobjtbl = allocateMGCHash_I(128);
-  gcnumlobjs = 0;
-  gcheaptop = 0;
-  gctopcore = 0;
-  gctopblock = 0;
-  gcmovestartaddr = 0;
-  gctomove = false;
-  gcmovepending = 0;
-  gcblock2fill = 0;
-#ifdef SMEMM
-  gcmem_mixed_threshold=(unsigned int)((BAMBOO_SHARED_MEM_SIZE-bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
-  gcmem_mixed_usedmem = 0;
-#endif
 #ifdef MGC_SPEC
   gc_profile_flag = false;
 #endif
-  gc_localheap_s = false;
-#ifdef GC_CACHE_ADAPT
-  gccachestage = false;
-#endif 
+
+  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+    allocationinfo.blocktable=RUNMALLOC(sizeof(struct blockrecord)*GCNUMBLOCK);
+    for(int i=0; i<GCNUMBLOCK;i++) {
+      if (1==NUMCORES4GC)
+       allocationinfo.blocktable[i].corenum=0;
+      else
+       allocationinfo.blocktable[i].corenum=gc_block2core[(i%(NUMCORES4GC*2))];
+      allocationinfo.blocktable[i].status=BS_FREE;
+      allocationinfo.blocktable[i].usedspace=0;
+      allocationinfo.blocktable[i].freespace=GLOBALBLOCKSIZE(i);
+    }
+    buildCore2Test();
+  }
+
+  //initialize update structures
+  origarraycount=0;
+  for(int i=0;i<NUMCORES4GC;i++) {
+    origblockarray[i]=NULL;
+  }
 
   INIT_MULTICORE_GCPROFILE_DATA();
 }
@@ -154,29 +153,22 @@ void initGC() {
       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
       gcloads[i] = 0;
       gcrequiredmems[i] = 0;
-      gcfilledblocks[i] = 0;
-      gcstopblock[i] = 0;
     } 
     for(int i = NUMCORES4GC; i < NUMCORESACTIVE; i++) {
       gccorestatus[i] = 1;
       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
     }
-    gcheaptop = 0;
-    gctopcore = 0;
-    gctopblock = 0;
     gcnumsrobjs_index = 0;
   } 
   gcself_numsendobjs = 0;
   gcself_numreceiveobjs = 0;
-  gcmarkedptrbound = 0;
-  gcnumlobjs = 0;
   gcmovestartaddr = 0;
   gctomove = false;
   gcblock2fill = 0;
   gcmovepending = 0;
   gccurr_heaptop = 0;
-
+  update_origblockptr=NULL;
   gc_queueinit();
 
   MGCHashreset(gcforwardobjtbl);
@@ -185,29 +177,8 @@ void initGC() {
   gc_output_cache_policy_time=0;
 } 
 
-bool gc_checkAllCoreStatus() {
-  BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-  for(int i = 0; i < NUMCORESACTIVE; i++) {
-    if(gccorestatus[i] != 0) {
-      BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-      return false;
-    }  
-  }  
-  BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-  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() {
+  //  tprintf("Check mark status 2\n");
   // 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
   unsigned int sumsendobj = 0;
@@ -227,6 +198,7 @@ void checkMarkStatus_p2() {
       }
     }  
     if(i == NUMCORESACTIVE) {    
+      //tprintf("Mark terminated\n");
       // all the core status info are the latest,stop mark phase
       gc_status_info.gcphase = COMPACTPHASE;
       // restore the gcstatus for all cores
@@ -250,6 +222,7 @@ void checkMarkStatus_p2() {
 }
 
 void checkMarkStatus() {
+  //  tprintf("Check mark status\n");
   if((!waitconfirm)||(waitconfirm && (numconfirm == 0))) {
     unsigned int entry_index = 0;
     if(waitconfirm) {
@@ -260,11 +233,8 @@ void checkMarkStatus() {
       entry_index = gcnumsrobjs_index;
     }
     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-    gccorestatus[BAMBOO_NUM_OF_CORE] = 0;  
-    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
@@ -286,64 +256,39 @@ void checkMarkStatus() {
 } 
 
 // compute load balance for all cores
-int loadbalance(void ** heaptop, unsigned int * topblock, unsigned int * topcore) {
+int loadbalance() {
   // compute load balance
   // get the total loads
+  void * heaptop;
   unsigned int tloads = 0;
   for(int i = 0; i < NUMCORES4GC; i++) {
     tloads += gcloads[i];
+    //tprintf("load: %d %d \n", gcloads[i], i);
   }
-  *heaptop = gcbaseva + tloads;
+  heaptop = gcbaseva + tloads;
 
   unsigned int topblockindex;
   
-  BLOCKINDEX(topblockindex, *heaptop);
+  BLOCKINDEX(topblockindex, heaptop);
   // num of blocks per core
   unsigned int numbpc = (topblockindex+NUMCORES4GC-1)/NUMCORES4GC;
   
-  *topblock = topblockindex;
-  RESIDECORE(*heaptop, *topcore);
   return numbpc;
 }
 
-
-// update the bmmboo_smemtbl to record current shared mem usage
-void updateSmemTbl(unsigned int coren, void * localtop) {
-  unsigned int ltopcore = 0;
-  unsigned int bound = BAMBOO_SMEM_SIZE_L;
-  BLOCKINDEX(ltopcore, localtop);
-  if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
-    bound = BAMBOO_SMEM_SIZE;
-  }
-  unsigned int load = (unsigned INTPTR)(localtop-gcbaseva)%(unsigned int)bound;
-  unsigned int toset = 0;
-  for(int j=0; 1; j++) {
-    for(int i=0; i<2; i++) {
-      toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
-      if(toset < ltopcore) {
-        bamboo_smemtbl[toset]=BLOCKSIZE(toset<NUMCORES4GC);
-#ifdef SMEMM
-        gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
-      } else if(toset == ltopcore) {
-        bamboo_smemtbl[toset] = load;
-#ifdef SMEMM
-        gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
-        return;
-      } else {
-        return;
-      }
-    }
-  }
-}
-
 void gc_collect(struct garbagelist * stackptr) {
   gc_status_info.gcprocessing = true;
   // inform the master that this core is at a gc safe point and is ready to 
   // do gc
   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
 
+  // invalidate all shared mem pointers
+  bamboo_cur_msp = NULL;
+  bamboo_smem_size = 0;
+  bamboo_smem_zero_top = NULL;
+  gcflag = false;
+
+
   // core collector routine
   //wait for init phase
   WAITFORGCPHASE(INITPHASE);
@@ -358,26 +303,20 @@ void gc_collect(struct garbagelist * stackptr) {
   WAITFORGCPHASE(MARKPHASE);
 
   GC_PRINTF("Start mark phase\n");
-  mark(true, stackptr);
+  mark(stackptr);
   GC_PRINTF("Finish mark phase, start compact phase\n");
   compact();
   GC_PRINTF("Finish compact phase\n");
 
   WAITFORGCPHASE(UPDATEPHASE);
 
-  GC_PRINTF("Start flush phase\n");
+  GC_PRINTF("Start update phase\n");
   GCPROFILE_INFO_2_MASTER();
-  flush(stackptr);
-  GC_PRINTF("Finish flush phase\n");
+  update(stackptr);
+  GC_PRINTF("Finish update phase\n");
 
   CACHEADAPT_PHASE_CLIENT();
 
-  // invalidate all shared mem pointers
-  bamboo_cur_msp = NULL;
-  bamboo_smem_size = 0;
-  bamboo_smem_zero_top = NULL;
-  gcflag = false;
-
   WAITFORGCPHASE(FINISHPHASE);
 
   GC_PRINTF("Finish gc! \n");
@@ -388,56 +327,52 @@ void gc_nocollect(struct garbagelist * stackptr) {
   // inform the master that this core is at a gc safe point and is ready to 
   // do gc
   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
+
+  // invalidate all shared mem pointers
+  bamboo_cur_msp = NULL;
+  bamboo_smem_size = 0;
+  bamboo_smem_zero_top = NULL;
+  gcflag = false;
   
   WAITFORGCPHASE(INITPHASE);
 
   GC_PRINTF("Do initGC\n");
   initGC();
   CACHEADAPT_GC(true);
+
   //send init finish msg to core coordinator
   send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
 
+
   WAITFORGCPHASE(MARKPHASE);
 
   GC_PRINTF("Start mark phase\n"); 
-  mark(true, stackptr);
-  GC_PRINTF("Finish mark phase, wait for flush\n");
+  mark(stackptr);
+  GC_PRINTF("Finish mark phase, wait for update\n");
 
   // non-gc core collector routine
   WAITFORGCPHASE(UPDATEPHASE);
 
-  GC_PRINTF("Start flush phase\n");
+  GC_PRINTF("Start update phase\n");
   GCPROFILE_INFO_2_MASTER();
-  flush(stackptr);
-  GC_PRINTF("Finish flush phase\n"); 
+  update(stackptr);
+  GC_PRINTF("Finish update phase\n"); 
 
   CACHEADAPT_PHASE_CLIENT();
 
-  // invalidate all shared mem pointers
-  bamboo_cur_msp = NULL;
-  bamboo_smem_size = 0;
-  bamboo_smem_zero_top = NULL;
-
-  gcflag = false;
   WAITFORGCPHASE(FINISHPHASE);
 
   GC_PRINTF("Finish gc! \n");
 }
 
 void master_mark(struct garbagelist *stackptr) {
-  bool isfirst = true;
 
   GC_PRINTF("Start mark phase \n");
-  GC_SEND_MSG_1_TO_CLIENT(GCSTART);
   gc_status_info.gcphase = MARKPHASE;
+  GC_SEND_MSG_1_TO_CLIENT(GCSTART);
   // mark phase
 
-  while(MARKPHASE == gc_status_info.gcphase) {
-    mark(isfirst, stackptr);
-    isfirst=false;
-    // check gcstatus
-    checkMarkStatus();
-  }
+  mark(stackptr);
 }
 
 void master_getlargeobjs() {
@@ -451,11 +386,7 @@ void master_getlargeobjs() {
   //spin until we have all responses
   while(numconfirm!=0) ;
 
-  // check the heaptop
-  if(gcheaptop < gcmarkedptrbound) {
-    gcheaptop = gcmarkedptrbound;
-  }
-  GCPROFILE_ITEM();
+  GCPROFILE_ITEM_MASTER();
   GC_PRINTF("prepare to cache large objs \n");
 
 }
@@ -464,12 +395,11 @@ void master_getlargeobjs() {
 void master_updaterefs(struct garbagelist * stackptr) {
   gc_status_info.gcphase = UPDATEPHASE;
   GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
-  GCPROFILE_ITEM();
-  GC_PRINTF("Start flush phase \n");
-  // flush phase
-  flush(stackptr);
-  GC_CHECK_ALL_CORE_STATUS(UPDATEPHASE==gc_status_info.gcphase);
-  GC_PRINTF("Finish flush phase \n");
+  GC_PRINTF("Start update phase \n");
+  // update phase
+  update(stackptr);
+  GC_CHECK_ALL_CORE_STATUS();
+  GC_PRINTF("Finish update phase \n");
 }
 
 void master_finish() {
@@ -483,16 +413,18 @@ void master_finish() {
   bamboo_smem_size = 0;
   bamboo_smem_zero_top = NULL;
   
-  GCPROFILE_END();
+  GCPROFILE_END_MASTER();
   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
   CACHEADAPT_OUTPUT_CACHE_POLICY();
   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
   gcflag = false;
+
   GC_SEND_MSG_1_TO_CLIENT(GCFINISH);
-  
-  gc_status_info.gcprocessing = false;
+  gc_status_info.gcprocessing = false;  
+
   if(gcflag) {
     // inform other cores to stop and wait for gc
+    GC_PRINTF("Back to Back gc case\n");
     gcprecheck = true;
     for(int i = 0; i < NUMCORESACTIVE; i++) {
       // reuse the gcnumsendobjs & gcnumreceiveobjs
@@ -504,42 +436,49 @@ void master_finish() {
 }
 
 void gc_master(struct garbagelist * stackptr) {
-  tprintf("start GC !!!!!!!!!!!!! \n");
+  tprintf("start GC!\n");
   gc_status_info.gcprocessing = true;
   gc_status_info.gcphase = INITPHASE;
+  GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
 
   waitconfirm = false;
   numconfirm = 0;
   initGC();
-  GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
   CACHEADAPT_GC(true);
-  GC_PRINTF("Check core status \n");
-  GC_CHECK_ALL_CORE_STATUS(true);
-  GCPROFILE_ITEM();
+  //tprintf("Check core status \n");
+  GC_CHECK_ALL_CORE_STATUS();
   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
   CACHEADAPT_OUTPUT_CACHE_SAMPLING();
   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
-
+  //tprintf("start mark phase\n");
   // do mark phase
+  GCPROFILE_ITEM_MASTER();
   master_mark(stackptr);
-
+  GCPROFILE_ITEM_MASTER();
+  //tprintf("finish mark phase\n");
   // get large objects from all cores
   master_getlargeobjs();
-
+  //tprintf("start compact phase\n");
   // compact the heap
   master_compact();
-  
+  //tprintf("start update phase\n");
   // update the references
   master_updaterefs(stackptr);
-
+  //tprintf("gc master finished update   \n");
   // do cache adaptation
   CACHEADAPT_PHASE_MASTER();
-
+  //tprintf("finish cachdapt phase\n");
   // do finish up stuff
+#ifdef GC_DEBUG
+  for(int i=0;i<GCNUMBLOCK;i++) {
+    struct blockrecord *record=&allocationinfo.blocktable[i];
+    tprintf("%u. used=%u free=%u corenum=%u status=%u, base=%x, ptr=%x\n", i, record->usedspace, record->freespace, record->corenum, record->status, gcbaseva+OFFSET2BASEVA(i), (gcbaseva+OFFSET2BASEVA(i)+record->usedspace));
+  }
+#endif
+
   master_finish();
 
-  GC_PRINTF("gc finished   \n");
-  tprintf("finish GC ! %d \n",gcflag);
+  //tprintf("finish GC ! %d \n",gcflag);
 } 
 
 void pregccheck() {
@@ -569,25 +508,21 @@ void pregccheck() {
 }
 
 void pregcprocessing() {
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)&&(defined(GC_CACHE_ADAPT_POLICY4)||defined(GC_CACHE_ADAPT_POLICY3))
   // disable the timer interrupt
   bamboo_mask_timer_intr();
-#endif
-  // Zero out the remaining memory here because for the GC_CACHE_ADAPT version,
-  // we need to make sure during the gcinit phase the shared heap is not 
-  // touched. Otherwise, there would be problem when adapt the cache strategy.
-  BAMBOO_CLOSE_CUR_MSP();
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
   // get the sampling data 
   bamboo_output_dtlb_sampling();
 #endif
 }
 
 void postgcprocessing() {
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)&&(defined(GC_CACHE_ADAPT_POLICY4)||defined(GC_CACHE_ADAPT_POLICY3))
   // enable the timer interrupt
   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); 
   bamboo_unmask_timer_intr();
+  //turn on sampling again
+  bamboo_dtlb_sampling_init();
 #endif
 }
 
@@ -597,24 +532,27 @@ bool gc(struct garbagelist * stackptr) {
     gc_status_info.gcprocessing = false;
     return false;
   }
+#ifdef PERFCOUNT
+  profile_start(GC_REGION);
+#endif
 
   // core coordinator routine
   if(0 == BAMBOO_NUM_OF_CORE) {
+    GC_PRINTF("start gc! \n");
+    GCPROFILE_START_MASTER();
+
     GC_PRINTF("Check if we can do gc or not\n");
     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-    if(!gc_checkAllCoreStatus()) {
-      // 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;
-      return false;
-    } else {
-      GCPROFILE_START();
-      pregccheck();
-    }
-    GC_PRINTF("start gc! \n");
     pregcprocessing();
+
+    //wait for other cores to catch up
+    while(!gc_checkCoreStatus())
+      ;
+
+    //pregccheck();
     gc_master(stackptr);
   } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
+    GC_PRINTF("Core reporting for gc.\n");
     pregcprocessing();
     gc_collect(stackptr);
   } else {
@@ -622,7 +560,9 @@ bool gc(struct garbagelist * stackptr) {
     gc_nocollect(stackptr);
   }
   postgcprocessing();
-
+#ifdef PERFCOUNT
+  profile_start(APP_REGION);
+#endif
   return true;
 }