Fix bug in multicore gc: the master core should send msgs to all the other cores...
authorjzhou <jzhou>
Thu, 5 Aug 2010 18:36:08 +0000 (18:36 +0000)
committerjzhou <jzhou>
Thu, 5 Aug 2010 18:36:08 +0000 (18:36 +0000)
Robust/src/Runtime/mem.c
Robust/src/Runtime/multicoregarbage.c
Robust/src/Runtime/multicoregarbage.h
Robust/src/Runtime/multicoreruntime.h
Robust/src/Runtime/multicoretask.c

index 2263113c2bc367abc952a39d39a07012ff1031b9..227c4ee2e44e1dab3752cb203c4685ce5f15f050 100644 (file)
@@ -24,7 +24,7 @@ void * mycalloc_share(struct garbagelist * stackptr,
        void * p = NULL;
   //int isize = 2*BAMBOO_CACHE_LINE_SIZE-4+(size-1)&(~BAMBOO_CACHE_LINE_MASK);
   int isize = (size & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE);
-       bool hasgc = false;
+       int hasgc = 0;
 memalloc:
   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
 #ifdef DEBUG
@@ -37,12 +37,14 @@ memalloc:
   if(p == NULL) {
                // no more global shared memory
                BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-               if(!hasgc) {
-                       // start gc
-                       gc(stackptr);
-                       hasgc = true;
+               if(hasgc < 5) {
+                   // start gc
+                       if(gc(stackptr)) {
+                         hasgc++;
+                       }
                } else {
                        // no more global shared memory
+                       //BAMBOO_DEBUGPRINT_REG(isize);
                        BAMBOO_EXIT(0xc002);
                }
 
index aeadde7e723b03d951d6fe09b883ff85af624e97..32df09146cdd7b3690b1f9b8f0932ae955c4568b 100644 (file)
@@ -530,7 +530,7 @@ inline void checkMarkStatue() {
   BAMBOO_DEBUGPRINT(0xee0a);
 #endif
 } // void checkMarkStatue()
-
+/*
 inline bool preGC() {
   // preparation for gc
   // make sure to clear all incoming msgs espacially transfer obj msgs
@@ -548,7 +548,7 @@ inline bool preGC() {
       corestatus[i] = 1;
       // send status confirm msg to core i
       send_msg_1(i, STATUSCONFIRM, false);
-    }             // for(i = 1; i < NUMCORESACTIVE; ++i)
+    }   // for(i = 1; i < NUMCORESACTIVE; ++i)
 
 #ifdef DEBUG
     BAMBOO_DEBUGPRINT(0xec02);
@@ -557,7 +557,7 @@ inline bool preGC() {
       if(numconfirm == 0) {
                break;
       }
-    }             // wait for confirmations
+    }   // wait for confirmations
     waitconfirm = false;
     numconfirm = 0;
 #ifdef DEBUG
@@ -594,7 +594,7 @@ inline bool preGC() {
     } else {
       // still have some transfer obj msgs on-the-fly, can not start gc
       return false;
-    }             // if(0 == sumsendobj)
+    }  // if(0 == sumsendobj)
   } else {
 #ifdef DEBUG
     BAMBOO_DEBUGPRINT(0xec07);
@@ -603,7 +603,7 @@ inline bool preGC() {
     // confirmations yet, can not start gc
     return false;
   }       // if((!waitconfirm) ||
-} // bool preGC()
+} // bool preGC()*/
 
 inline void initGC() {
   int i;
@@ -1194,6 +1194,14 @@ inline void moveLObjs() {
     }
   } while(true);
 
+  // TODO
+  /*unsigned long long gc_num_livespace = 0;
+  for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
+       gc_num_livespace += bamboo_smemtbl[tmpi];
+  }
+  BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
+  BAMBOO_DEBUGPRINT_REG(bamboo_free_block);*/
+
 #ifdef GC_PROFILE
   // check how many live space there are
   gc_num_livespace = 0;
@@ -2783,6 +2791,12 @@ inline void flush(struct garbagelist * stackptr) {
 } // flush()
 
 inline void gc_collect(struct garbagelist * stackptr) {
+  //BAMBOO_DEBUGPRINT(0xcccc); // TODO 
+  // 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, false);
+
   // core collector routine
   while(true) {
     if(INITPHASE == gcphase) {
@@ -2867,6 +2881,12 @@ inline void gc_collect(struct garbagelist * stackptr) {
 } // void gc_collect(struct garbagelist * stackptr)
 
 inline void gc_nocollect(struct garbagelist * stackptr) {
+  //BAMBOO_DEBUGPRINT(0xcccc); // TODO
+  // 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, false);
+  
   while(true) {
     if(INITPHASE == gcphase) {
       break;
@@ -2930,11 +2950,11 @@ inline void gc_nocollect(struct garbagelist * stackptr) {
 #endif
 } // void gc_collect(struct garbagelist * stackptr)
 
-inline void gc(struct garbagelist * stackptr) {
+inline bool gc(struct garbagelist * stackptr) {
   // check if do gc
   if(!gcflag) {
     gcprocessing = false;
-    return;
+    return false;
   }
 
   // core coordinator routine
@@ -2943,16 +2963,81 @@ inline void gc(struct garbagelist * stackptr) {
     printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
                   udn_tile_coord_y());
 #endif
-    if(!preGC()) {
-      // not ready to do gc
-      gcflag = true;
-      return;
-    }
-
+       //if(gcnumpre != 0) {
+       bool isallstall = true;
+       gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+       BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+       int ti = 0;
+       for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
+         if(gccorestatus[ti] != 0) {
+               isallstall = false;
+               break;
+         }
+       }
+       if(!isallstall) {
+         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+         // 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
+         // in case that there are some pregc information msg lost, send a confirm
+         // msg to the 'busy' core
+         send_msg_1(ti, GCSTARTPRE, false);
+         gcflag = true;
+         return false;
+       } else {
+         // TODO
 #ifdef GC_PROFILE
     gc_profileStart();
 #endif
-
+         //BAMBOO_DEBUGPRINT(0x1111); // TODO
+pregccheck:
+         //BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+         gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+         gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
+         int sumsendobj = 0;
+#ifdef DEBUG
+         BAMBOO_DEBUGPRINT(0xec04);
+#endif
+         for(int i = 0; i < NUMCORESACTIVE; ++i) {
+               sumsendobj += gcnumsendobjs[0][i];
+#ifdef DEBUG
+               BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
+#endif
+         }  // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+         BAMBOO_DEBUGPRINT(0xec05);
+         BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+         for(int i = 0; i < NUMCORESACTIVE; ++i) {
+               sumsendobj -= gcnumreceiveobjs[0][i];
+#ifdef DEBUG
+               BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
+#endif
+         }  // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+         BAMBOO_DEBUGPRINT(0xec06);
+         BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+         if(0 != sumsendobj) {
+               // there were still some msgs on the fly, wait until there 
+               // are some update pregc information coming and check it again
+               gcprecheck = false;
+               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+               //BAMBOO_DEBUGPRINT(0x2222); // TODO
+               while(true) {
+                 if(gcprecheck) {
+                       break;
+                 }
+               }
+               goto pregccheck;
+         } else {
+               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+         }
+       }
+/*
+#ifdef GC_PROFILE
+    gc_profileStart();
+#endif
+*/
 #ifdef RAWPATH // TODO GC_DEBUG
     printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
     //dumpSMem();
@@ -3342,6 +3427,8 @@ inline void gc(struct garbagelist * stackptr) {
        gcflag = false;
     gcprocessing = false;
   }
+  //if(STARTUPCORE == BAMBOO_NUM_OF_CORE) BAMBOO_DEBUGPRINT(0xeeee); // TODO 
+  return true;
 } // void gc(struct garbagelist * stackptr)
 
 #ifdef GC_PROFILE
index b7f73b9afb49553d8f462ca4418fc4b73f18ff1b..a6722e871cec08d3d645f07c92072db9302e0303 100644 (file)
@@ -76,6 +76,9 @@ volatile bool gcflag;
 volatile bool gcprocessing;
 volatile GCPHASETYPE gcphase; // indicating GC phase
 
+volatile bool gcpreinform; // counter for stopped cores
+volatile bool gcprecheck; // indicates if there are updated pregc information
+
 int gccurr_heaptop;
 struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
 // for mark phase termination
@@ -230,7 +233,7 @@ int gcbaseva; // base va for shared memory without reserved sblocks
 // the next core in the top of the heap
 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
 
-inline void gc(struct garbagelist * stackptr); // core coordinator routine
+inline bool gc(struct garbagelist * stackptr); // core coordinator routine
 inline void gc_collect(struct garbagelist* stackptr); //core collector routine
 inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
 inline void transferMarkResults_I();
index df49ed1010ad345fab2c7ab36607f8a8811e6153..1482c67c84ca3315b83d750ecdbf20a681848d17 100644 (file)
@@ -192,29 +192,31 @@ typedef enum {
   MEMREQUEST,            // 0xE0
   MEMRESPONSE,           // 0xE1
 #ifdef MULTICORE_GC
-  GCSTARTINIT,           // 0xE2
-  GCSTART,               // 0xE3
-  GCSTARTCOMPACT,        // 0xE4
-  GCSTARTMAPINFO,        // 0xE5
-  GCSTARTFLUSH,          // 0xE6
-  GCFINISHINIT,          // 0xE7
-  GCFINISHMARK,          // 0xE8
-  GCFINISHCOMPACT,       // 0xE9
-  GCFINISHMAPINFO,       // 0xEa
-  GCFINISHFLUSH,         // 0xEb
-  GCFINISH,              // 0xEc
-  GCMARKCONFIRM,         // 0xEd
-  GCMARKREPORT,          // 0xEe
-  GCMARKEDOBJ,           // 0xEf
-  GCMOVESTART,           // 0xF0
-  GCMAPREQUEST,          // 0xF1
-  GCMAPINFO,             // 0xF2
-  GCMAPTBL,              // 0xF3
-  GCLOBJREQUEST,         // 0xF4
-  GCLOBJINFO,            // 0xF5
-  GCLOBJMAPPING,         // 0xF6
-#ifdef GC_PROFILE//_S
-  GCPROFILES,            // 0xF7
+  GCSTARTPRE,            // 0xE2
+  GCSTARTINIT,           // 0xE3
+  GCSTART,               // 0xE4
+  GCSTARTCOMPACT,        // 0xE5
+  GCSTARTMAPINFO,        // 0xE6
+  GCSTARTFLUSH,          // 0xE7
+  GCFINISHPRE,           // 0xE8
+  GCFINISHINIT,          // 0xE9
+  GCFINISHMARK,          // 0xEa
+  GCFINISHCOMPACT,       // 0xEb
+  GCFINISHMAPINFO,       // 0xEc
+  GCFINISHFLUSH,         // 0xEd
+  GCFINISH,              // 0xEe
+  GCMARKCONFIRM,         // 0xEf
+  GCMARKREPORT,          // 0xF0
+  GCMARKEDOBJ,           // 0xF1
+  GCMOVESTART,           // 0xF2
+  GCMAPREQUEST,          // 0xF3
+  GCMAPINFO,             // 0xF4
+  GCMAPTBL,              // 0xF5
+  GCLOBJREQUEST,         // 0xF6
+  GCLOBJINFO,            // 0xF7
+  GCLOBJMAPPING,         // 0xF8
+#ifdef GC_PROFILE
+  GCPROFILES,            // 0xF9
 #endif
 #endif
   MSGEND
index f7a830b5cdd146f274c04d14ee3578539bf6828f..0f5e8020a3b0f12f9cdf391b58c645b0c9501662 100644 (file)
@@ -257,6 +257,8 @@ void initruntimedata() {
   gcflag = false;
   gcprocessing = false;
   gcphase = FINISHPHASE;
+  //gcnumpre = 0;
+  gcprecheck = true;
   gccurr_heaptop = 0;
   gcself_numsendobjs = 0;
   gcself_numreceiveobjs = 0;
@@ -750,7 +752,9 @@ inline void run(void * arg) {
     while(true) {
 #ifdef MULTICORE_GC
       // check if need to do GC
-      gc(NULL);
+      if(gcflag) {
+               gc(NULL);
+         }
 #endif
 
       // check if there are new active tasks can be executed
@@ -1875,7 +1879,27 @@ void * smemalloc_I(int coren,
     // no enough shared global memory
     *allocsize = 0;
 #ifdef MULTICORE_GC
-    gcflag = true;
+    //gcflag = true;
+       if(!gcflag) {
+         gcflag = true;
+       // inform other cores to stop and wait for gc
+       gcprecheck = true;
+       for(int i = 0; i < NUMCORESACTIVE; i++) {
+         // reuse the gcnumsendobjs & gcnumreceiveobjs
+         gccorestatus[i] = 1;
+         gcnumsendobjs[0][i] = 0;
+         gcnumreceiveobjs[0][i] = 0;
+       }
+       for(int i = 0; i < NUMCORESACTIVE; i++) {
+         if(i != BAMBOO_NUM_OF_CORE) {
+               if(BAMBOO_CHECK_SEND_MODE()) {
+                 cache_msg_1(i, GCSTARTPRE);
+               } else {
+                 send_msg_1(i, GCSTARTPRE, true);
+               }
+         }
+       }
+       }
     return NULL;
 #else
     BAMBOO_DEBUGPRINT(0xa001);
@@ -1896,6 +1920,7 @@ INLINE int checkMsgLength_I(int size) {
   case STATUSCONFIRM:
   case TERMINATE:
 #ifdef MULTICORE_GC
+  case GCSTARTPRE:
   case GCSTARTINIT:
   case GCSTART:
   case GCSTARTMAPINFO:
@@ -1944,6 +1969,7 @@ INLINE int checkMsgLength_I(int size) {
   case REDIRECTDENY:
   case REDIRECTRELEASE:
 #ifdef MULTICORE_GC
+  case GCFINISHPRE:
   case GCFINISHMARK:
   case GCMOVESTART:
 #ifdef GC_PROFILE//_S
@@ -2074,6 +2100,23 @@ INLINE void processmsg_transobj_I() {
     addNewItem_I(&objqueue, (void *)transObj);
   }
   ++(self_numreceiveobjs);
+#ifdef MULTICORE_GC
+  if(gcprocessing) {
+       if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+         // set the gcprecheck to enable checking again
+         gcprecheck = true;
+       } else {
+         // send a update pregc information msg to the master core
+         if(BAMBOO_CHECK_SEND_MODE()) {
+               cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
+                       self_numsendobjs, self_numreceiveobjs);
+         } else {
+               send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
+                       self_numsendobjs, self_numreceiveobjs, true);
+         }
+       }
+  }
+#endif 
 }
 
 INLINE void processmsg_transtall_I() {
@@ -2359,6 +2402,7 @@ INLINE void processmsg_statusconfirm_I() {
     BAMBOO_DEBUGPRINT(0xe887);
 #endif
 #endif
+       //BAMBOO_DEBUGPRINT(0xffff); // TODO
     // cache the msg first
     if(BAMBOO_CHECK_SEND_MODE()) {
     cache_msg_5(STARTUPCORE, STATUSREPORT,
@@ -2463,10 +2507,28 @@ INLINE void processmsg_memrequest_I() {
       } else {
       send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
       }
-    } // if mem == NULL, the gcflag of the startup core has been set
-    // and the gc should be started later, then a GCSTARTINIT msg
-    // will be sent to the requesting core to notice it to start gc
-    // and try malloc again
+    } else {
+         // if mem == NULL, the gcflag of the startup core has been set
+         // and all the other cores have been informed to start gc
+         // TODO 
+         // inform other cores to stop and wait for gc
+         /*gcprecheck = true;
+         for(int i = 0; i < NUMCORESACTIVE; i++) {
+               // reuse the gcnumsendobjs & gcnumreceiveobjs
+               gccorestatus[i] = 1;
+               gcnumsendobjs[0][i] = 0;
+               gcnumreceiveobjs[0][i] = 0;
+         }
+         for(int i = 0; i < NUMCORESACTIVE; i++) {
+               if(i != BAMBOO_NUM_OF_CORE) {
+                 if(BAMBOO_CHECK_SEND_MODE()) {
+                       cache_msg_1(i, GCSTARTPRE);
+                 } else {
+                       send_msg_1(i, GCSTARTPRE, true);
+                 }
+               }
+         }*/
+       }
 #ifdef MULTICORE_GC
   }
 #endif
@@ -2524,17 +2586,43 @@ INLINE void processmsg_memresponse_I() {
 }
 
 #ifdef MULTICORE_GC
+INLINE void processmsg_gcstartpre_I() {
+  //BAMBOO_DEBUGPRINT(0xc000); // TODO
+  if(gcprocessing) {
+       // already stall for gc
+       // send a update pregc information msg to the master core
+       if(BAMBOO_CHECK_SEND_MODE()) {
+         cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
+                 self_numsendobjs, self_numreceiveobjs);
+       } else {
+         send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
+                 self_numsendobjs, self_numreceiveobjs, true);
+       }
+  } else {
+       // the first time to be informed to start gc
+       gcflag = true;
+       if(!smemflag) {
+         // is waiting for response of mem request
+         // let it return NULL and start gc
+         bamboo_smem_size = 0;
+         bamboo_cur_msp = NULL;
+         smemflag = true;
+         bamboo_smem_zero_top = NULL;
+       }
+  }
+}
+
 INLINE void processmsg_gcstartinit_I() {
-  gcflag = true;
+  //gcflag = true;
   gcphase = INITPHASE;
-  if(!smemflag) {
+  /*if(!smemflag) {
     // is waiting for response of mem request
     // let it return NULL and start gc
     bamboo_smem_size = 0;
     bamboo_cur_msp = NULL;
     smemflag = true;
        bamboo_smem_zero_top = NULL;
-  }
+  }*/
 }
 
 INLINE void processmsg_gcstart_I() {
@@ -2561,6 +2649,33 @@ INLINE void processmsg_gcstartflush_I() {
   gcphase = FLUSHPHASE;
 }
 
+INLINE void processmsg_gcfinishpre_I() {
+  int data1 = msgdata[msgdataindex];
+  MSG_INDEXINC_I();
+  int data2 = msgdata[msgdataindex];
+  MSG_INDEXINC_I();
+  int data3 = msgdata[msgdataindex];
+  MSG_INDEXINC_I();
+  // received a init phase finish msg
+  if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+    // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+    BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+    BAMBOO_EXIT(0xb000);
+  }
+  // All cores should do init GC
+  /*if(gcprecheck && (gcnumpre > 0)) {
+       gcnumpre--;
+  } else {*/
+  if(!gcprecheck) {
+       gcprecheck = true;
+  }
+  gccorestatus[data1] = 0;
+  gcnumsendobjs[0][data1] = data2;
+  gcnumreceiveobjs[0][data1] = data3;
+}
+
 INLINE void processmsg_gcfinishinit_I() {
   int data1 = msgdata[msgdataindex];
   MSG_INDEXINC_I();
@@ -3067,7 +3182,12 @@ processmsg:
 
 #ifdef MULTICORE_GC
     // GC msgs
-    case GCSTARTINIT: {
+    case GCSTARTPRE: {
+      processmsg_gcstartpre_I();
+      break;
+    }                     // case GCSTARTPRE
+       
+       case GCSTARTINIT: {
       processmsg_gcstartinit_I();
       break;
     }                     // case GCSTARTINIT
@@ -3096,7 +3216,12 @@ processmsg:
       break;
     }                     // case GCSTARTFLUSH
 
-    case GCFINISHINIT: {
+    case GCFINISHPRE: {
+      processmsg_gcfinishpre_I();
+      break;
+    }                     // case GCFINISHPRE
+       
+       case GCFINISHINIT: {
       processmsg_gcfinishinit_I();
       break;
     }                     // case GCFINISHINIT
@@ -3494,7 +3619,7 @@ void executetasks() {
 newtask:
   while(hashsize(activetasks)>0) {
 #ifdef MULTICORE_GC
-    gc(NULL);
+    if(gcflag) gc(NULL);
 #endif
 #ifdef DEBUG
     BAMBOO_DEBUGPRINT(0xe990);