changes for multicore GC. Chang the lock mechanism for Tilera and messages for GC.
authorjzhou <jzhou>
Sat, 1 Aug 2009 00:28:03 +0000 (00:28 +0000)
committerjzhou <jzhou>
Sat, 1 Aug 2009 00:28:03 +0000 (00:28 +0000)
Robust/src/IR/Flat/BuildCode.java
Robust/src/Runtime/RAW/task_arch.c
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 c11274722ce5e23a8fe5e681f9c0fce0b9346904..61dcf0b31e79bb8da50049a66539fc2388ab9564 100644 (file)
@@ -592,13 +592,13 @@ public class BuildCode {
       if(!state.MULTICORE) {
        outclassdefs.println("  void * flagptr;");
       } else {
-        if(state.MULTICOREGC) {
-          outclassdefs.println("  int marked;");
-        }
         outclassdefs.println("  int version;");
         outclassdefs.println("  int * lock;");  // lock entry for this obj
         outclassdefs.println("  void * mutex;");  
         outclassdefs.println("  int lockcount;");
+        if(state.MULTICOREGC) {
+          outclassdefs.println("  int marked;");
+        }
       }
       if(state.OPTIONAL) {
        outclassdefs.println("  int numfses;");
index d9746f702744f68440350bda4b46ac346b89baf1..cb0c1e182f6a2135d2678f0d8221652a96d038d0 100644 (file)
@@ -146,7 +146,8 @@ inline void transferObject(struct transObjInfo * transObj) {//  __attribute__((a
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_1 (int targetcore, int n0) {
+__attribute__((always_inline)) inline void send_msg_1 (int targetcore, 
+                                                                  int n0) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -214,7 +215,9 @@ __attribute__((always_inline)) inline void send_msg_1 (int targetcore, int n0) {
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_2 (int targetcore, int n0, int n1) {
+__attribute__((always_inline)) inline void send_msg_2 (int targetcore, 
+                                                                  int n0, 
+                                                                                                                                                                                                                        int n1) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -286,7 +289,10 @@ __attribute__((always_inline)) inline void send_msg_2 (int targetcore, int n0, i
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_3 (int targetcore, int n0, int n1, int n2) {
+__attribute__((always_inline)) inline void send_msg_3 (int targetcore, 
+                                                                  int n0, 
+                                                                                                                                                                                                                        int n1, 
+                                                                                                                                                                                                                        int n2) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -362,7 +368,11 @@ __attribute__((always_inline)) inline void send_msg_3 (int targetcore, int n0, i
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_4 (int targetcore, int n0, int n1, int n2, int n3) {
+__attribute__((always_inline)) inline void send_msg_4 (int targetcore, 
+                                                                  int n0, 
+                                                                                                                                                                                                                        int n1, 
+                                                                                                                                                                                                                        int n2, 
+                                                                                                                                                                                                                        int n3) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -442,7 +452,12 @@ __attribute__((always_inline)) inline void send_msg_4 (int targetcore, int n0, i
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_5 (int targetcore, int n0, int n1, int n2, int n3, int n4) {
+__attribute__((always_inline)) inline void send_msg_5 (int targetcore, 
+                                                                  int n0, 
+                                                                                                                                                                                                                        int n1, 
+                                                                                                                                                                                                                        int n2, 
+                                                                                                                                                                                                                        int n3, 
+                                                                                                                                                                                                                        int n4) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -526,7 +541,13 @@ __attribute__((always_inline)) inline void send_msg_5 (int targetcore, int n0, i
   }
 }
 
-__attribute__((always_inline)) inline void send_msg_6 (int targetcore, int n0, int n1, int n2, int n3, int n4, int n5) {
+__attribute__((always_inline)) inline void send_msg_6 (int targetcore, 
+                                                                  int n0, 
+                                                                                                                                                                                                                        int n1, 
+                                                                                                                                                                                                                        int n2, 
+                                                                                                                                                                                                                        int n3, 
+                                                                                                                                                                                                                        int n4, 
+                                                                                                                                                                                                                        int n5) {
   // send this msg
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
@@ -614,7 +635,9 @@ __attribute__((always_inline)) inline void send_msg_6 (int targetcore, int n0, i
   }
 }
 
-__attribute__((always_inline)) inline void cache_msg_2 (int targetcore, int n0, int n1) {
+__attribute__((always_inline)) inline void cache_msg_2 (int targetcore, 
+                                                                   int n0, 
+                                                                                                                                                                                                                               int n1) {
   // cache this msg
 #ifdef DEBUG
   BAMBOO_DEBUGPRINT(0xdede);
@@ -628,7 +651,10 @@ __attribute__((always_inline)) inline void cache_msg_2 (int targetcore, int n0,
   outmsgdata[outmsglast++] = n1;
 }
 
-__attribute__((always_inline)) inline void cache_msg_3 (int targetcore, int n0, int n1, int n2) {
+__attribute__((always_inline)) inline void cache_msg_3 (int targetcore, 
+                                                                   int n0, 
+                                                                                                                                                                                                                               int n1, 
+                                                                                                                                                                                                                               int n2) {
   // cache this msg
 #ifdef DEBUG
   BAMBOO_DEBUGPRINT(0xdede);
@@ -643,7 +669,11 @@ __attribute__((always_inline)) inline void cache_msg_3 (int targetcore, int n0,
   outmsgdata[outmsglast++] = n2;
 }
 
-__attribute__((always_inline)) inline void cache_msg_4 (int targetcore, int n0, int n1, int n2, int n3) {
+__attribute__((always_inline)) inline void cache_msg_4 (int targetcore, 
+                                                                   int n0, 
+                                                                                                                                                                                                                               int n1, 
+                                                                                                                                                                                                                               int n2, 
+                                                                                                                                                                                                                               int n3) {
   // cache this msg
 #ifdef DEBUG
   BAMBOO_DEBUGPRINT(0xdede);
@@ -659,7 +689,36 @@ __attribute__((always_inline)) inline void cache_msg_4 (int targetcore, int n0,
   outmsgdata[outmsglast++] = n3;
 }
 
-__attribute__((always_inline)) inline void cache_msg_6 (int targetcore, int n0, int n1, int n2, int n3, int n4, int n5) {
+__attribute__((always_inline)) inline void cache_msg_5 (int targetcore, 
+                                                                   int n0, 
+                                                                                                                                                                                                                               int n1, 
+                                                                                                                                                                                                                               int n2, 
+                                                                                                                                                                                                                               int n3, 
+                                                                                                                                                                                                                               int n4) {
+  // cache this msg
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xdede);
+#endif
+  isMsgHanging = true;
+  // cache the msg in outmsgdata and send it later
+  // msglength + target core + msg
+  outmsgdata[outmsglast++] = 5;
+  outmsgdata[outmsglast++] = targetcore;
+  outmsgdata[outmsglast++] = n0;
+  outmsgdata[outmsglast++] = n1;
+  outmsgdata[outmsglast++] = n2;
+  outmsgdata[outmsglast++] = n3;
+  outmsgdata[outmsglast++] = n4;
+}
+
+
+__attribute__((always_inline)) inline void cache_msg_6 (int targetcore, 
+                                                                   int n0, 
+                                                                                                                                                                                                                               int n1, 
+                                                                                                                                                                                                                               int n2, 
+                                                                                                                                                                                                                               int n3, 
+                                                                                                                                                                                                                               int n4, 
+                                                                                                                                                                                                                               int n5) {
   // cache this msg
 #ifdef DEBUG
   BAMBOO_DEBUGPRINT(0xdede);
@@ -781,7 +840,8 @@ bool getreadlock(void * ptr) {
   } else {
          // send lock request msg
          // for 32 bit machine, the size is always 5 words
-         send_msg_5(false, targetcore, 2, 0, (int)ptr, lock2require, BAMBOO_NUM_OF_CORE);
+         send_msg_5(targetcore, LOCKREQUEST, 0, (int)ptr, 
+                                      lock2require, BAMBOO_NUM_OF_CORE);
   }
   return true;
 }
@@ -825,7 +885,7 @@ void releasereadlock(void * ptr) {
   } else {
        // send lock release msg
        // for 32 bit machine, the size is always 4 words
-       send_msg_4(false, targetcore, 5, 0, (int)ptr, reallock);
+       send_msg_4(targetcore, LOCKRELEASE, 0, (int)ptr, reallock);
   }
 }
 
@@ -872,9 +932,11 @@ bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
                        // send lock grant/deny request to the root requiring core
                        // check if there is still some msg on sending
                        if((!cache) || (cache && !isMsgSending)) {
-                               send_msg_4(false, core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
+                               send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0, 
+                                                      (int)ptr, (int)redirectlock);
                        } else {
-                               cache_msg_4(false, core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
+                               cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0, 
+                                                       (int)ptr, (int)redirectlock);
                        }
                }
        }
@@ -882,9 +944,11 @@ bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
        // redirect the lock request
        // for 32 bit machine, the size is always 6 words
        if((!cache) || (cache && !isMsgSending)) {
-               send_msg_6(false, targetcore, 8, 0, (int)ptr, lock2require, core, BAMBOO_NUM_OF_CORE);
+               send_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require, 
+                                      core, BAMBOO_NUM_OF_CORE);
        } else {
-               cache_msg_6(false, targetcore, 8, 0, (int)ptr, lock2require, core, BAMBOO_NUM_OF_CORE);
+               cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require, 
+                                       core, BAMBOO_NUM_OF_CORE);
        }
   }
   return true;
@@ -956,7 +1020,8 @@ bool getwritelock(void * ptr) {
   } else {
          // send lock request msg
          // for 32 bit machine, the size is always 5 words
-         send_msg_5(false, targetcore, 2, 1, (int)ptr, lock2require, BAMBOO_NUM_OF_CORE);
+         send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require, 
+                                      BAMBOO_NUM_OF_CORE);
   }
   return true;
 }
@@ -1002,7 +1067,7 @@ void releasewritelock(void * ptr) {
   } else {
        // send lock release msg
        // for 32 bit machine, the size is always 4 words
-       send_msg_4(false,targetcore, 5, 1, (int)ptr, reallock);
+       send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
   }
 }
 
@@ -1052,7 +1117,7 @@ void releasewritelock_r(void * lock, void * redirectlock) {
   } else {
          // send lock release with redirect info msg
          // for 32 bit machine, the size is always 4 words
-         send_msg_4(false, targetcore, 0xb, 1, (int)lock, (int)redirectlock);
+         send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
   }
 }
 
@@ -1110,7 +1175,8 @@ bool getwritelock_I(void * ptr) {
   } else {
          // send lock request msg
          // for 32 bit machine, the size is always 5 words
-         send_msg_5(false, targetcore, 2, 1, (int)ptr, lock2require, BAMBOO_NUM_OF_CORE);
+         send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require, 
+                                      BAMBOO_NUM_OF_CORE);
   }
   return true;
 }
@@ -1168,9 +1234,11 @@ bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
                        // send lock grant/deny request to the root requiring core
                        // check if there is still some msg on sending
                        if((!cache) || (cache && !isMsgSending)) {
-                               send_msg_4(false, core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
+                               send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1, 
+                                                            (int)ptr, (int)redirectlock);
                        } else {
-                               cache_msg_4(false, core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
+                               cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1, 
+                                                       (int)ptr, (int)redirectlock);
                        }
                }
        }
@@ -1178,9 +1246,11 @@ bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
        // redirect the lock request
        // for 32 bit machine, the size is always 6 words
        if((!cache) || (cache && !isMsgSending)) {
-               send_msg_6(false, targetcore, 8, 1, (int)ptr, (int)redirectlock, core, BAMBOO_NUM_OF_CORE);
+               send_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock, 
+                                      core, BAMBOO_NUM_OF_CORE);
        } else {
-               cache_msg_6(false, targetcore, 8, 1, (int)ptr, (int)redirectlock, core, BAMBOO_NUM_OF_CORE);
+               cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock, 
+                                       core, BAMBOO_NUM_OF_CORE);
        }
   }
   return true;
@@ -1219,7 +1289,7 @@ void releasewritelock_I(void * ptr) {
   } else {
        // send lock release msg
        // for 32 bit machine, the size is always 4 words
-       send_msg_4(false, targetcore, 5, 1, (int)ptr, reallock);
+       send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
   }
 }
 
@@ -1261,7 +1331,7 @@ void releasewritelock_I_r(void * lock, void * redirectlock) {
   } else {
        // send lock release msg
        // for 32 bit machine, the size is always 4 words
-       send_msg_4(false, targetcore, 0xb, 1, (int)lock, (int)redirectlock);
+       send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
   }
 }
 
index a52ef83446cdd5b4e6858fc9cd98b47e67447b14..0e1d8e594f0fc1ec5de1b74bc85cee2323d658c5 100644 (file)
@@ -4,15 +4,6 @@
 #include "runtime.h"
 #include "runtime_arch.h"
 
-/*void * m_calloc(int m, int size) {
-        void * p = malloc(m*size);
-        int i = 0;
-        for(i = 0; i < size; ++i) {
- *(char *)(p+i) = 0;
-        }
-        return p;
-   }*/
-
 void * mycalloc(int m, int size) {
   void * p = NULL;
   int isize = size; //2*BAMBOO_CACHE_LINE_SIZE-4+(size-1)&(~BAMBOO_CACHE_LINE_MASK);
index e72f6bf88a4fafcfd919172d3daab996f421b816..407361d574723a64ffec2066abd72830a9cbd990 100644 (file)
@@ -8,22 +8,9 @@
 extern struct genhashtable * activetasks;
 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
 extern struct taskparamdescriptor *currtpd;
-//extern struct RuntimeHash *fdtoobject;
 
-struct largeObjList lObjList;
-struct markedObjList mObjList;
 INTPTR curr_heaptop = 0;
 
-struct markedObjList {
-       struct markedObjItem * head;
-       struct markedObjItem * tail;
-};
-
-struct largeObjList {
-       struct largeObjItem * head;
-       struct largeObjItem * tail;
-};
-
 bool isLarge(void * ptr, int * ttype, int * tsize) {
        // check if a pointer is referring to a large object
        int type = ((int *)ptr)[0];
@@ -58,153 +45,102 @@ bool isLocal(void * ptr) {
        return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
 }
 
-void insertMarkedObj(struct markedObjList * list, struct markedObjItem * toinsert) {
-       // insert a markedObjItem
-       struct markedObjItem * tmp = list->head;
-       if(tmp == NULL) {
-               list->head = toinsert;
-               list->tail = toinsert;
-       } else if(tmp->orig > toinsert->orig) {
-               // insert into the head of the list
-               toinsert->next = tmp;
-               list->head = toinsert;
-       } else {
-               struct markedObjItem * next = tmp->next;
-               while(next != NULL) {
-                       if(next->orig < toinsert->orig) {
-                               tmp = next;
-                               next = tmp->next;
-                       } else if((next->orig == toinsert->orig) || (tmp->orig == toinsert->orig)) {
-                               // has been inserted
-                               RUNFREE(toinsert);
-                               toinsert = NULL;
-                               break;
-                       } else {
-                               // insert after tmp
-                               toinsert->next = next;
-                               tmp->next = tmp;
+void transferMarkResults() {
+       // TODO, need distiguish between send and cache
+       // invoked inside interruptiong handler
+}
+
+void checkMarkStatue() {
+       if((!gcwaitconfirm) || 
+                       (gcwaitconfirm && (gcnumconfirm == 0))) {
+               BAMBOO_START_CRITICAL_SECTION_STATUS();  
+               gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+               gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
+               gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
+               // check the status of all cores
+               bool allStall = true;
+               for(i = 0; i < NUMCORES; ++i) {
+                       if(gccorestatus[i] != 0) {
+                               allStall = false;
                                break;
                        }
-               } // while(next != NULL)
-               if(next == NULL) {
-                       if(tmp->orig == toinsert->orig) {
-                               RUNFREE(toinsert);
-                               toinsert = NULL;
-                       } else {
-                               // insert to the tail of the list
-                               tmp->next = toinsert;
-                               list->tail = toinsert;
+               }
+               if(allStall) {
+                       // 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
+                       int sumsendobj = 0;
+                       for(i = 0; i < NUMCORES; ++i) {
+                               sumsendobj += gcnumsendobjs[i];
+                       }               
+                       for(i = 0; i < NUMCORES; ++i) {
+                               sumsendobj -= gcnumreceiveobjs[i];
                        }
-               } // if(next == NULL)
-       }
+                       if(0 == sumsendobj) {
+                               if(!gcwaitconfirm) {
+                                       // the first time found all cores stall
+                                       // send out status confirm msg to all other cores
+                                       // reset the corestatus array too
+                                       gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+                                       gcwaitconfirm = true;
+                                       gcnumconfirm = NUMCORES - 1;
+                                       for(i = 1; i < NUMCORES; ++i) { 
+                                               gccorestatus[i] = 1;
+                                               // send mark phase finish confirm request msg to core i
+                                               send_msg_1(i, GCMARKCONFIRM);
+                                       }
+                               } else {
+                                       // all the core status info are the latest
+                                       // stop mark phase
+                                       gcphase = COMPACTPHASE;
+                                       // restore the gcstatus for all cores
+                                       for(i = 0; i < NUMCORES; ++i) {
+                                               gccorestatus[i] = 1;
+                                       }
+                               } // if(!gcwautconfirm) else()
+                       } // if(0 == sumsendobj)
+               } // if(allStall)
+               BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
+       } // if((!gcwaitconfirm)...
 }
 
-struct markedObjItem * getStartItem(struct markedObjItem * moi, INTPTR start) {
-       // find the markedobj whose start address is start
-       struct markedObjItem * tostart = moi;
-       while(tostart->orig < start) {
-               tostart = tostart->next;
+void gc() {
+       // check if do gc
+       if(!gcflag) {
+               return;
+       } else {
+               // do gc
+               gcflag = false;
        }
-       return tostart;
-}
 
-void transferMarkResults() {
-       // TODO, need distiguish between send and cache
-       // invoked inside interruptiong handler
-}
+       // TODO, preparation
 
-void gc() {
        // core coordinator routine
        if(0 == BAMBOO_NUM_OF_CORE) {
-               // change to UDN1
-               bme_install_interrupt_handler(INT_UDN_AVAIL, gc_msghandler);
-#ifdef DEBUG
-               tprintf("Process %x(%d): change udn interrupt handler\n", BAMBOO_NUM_OF_CORE, 
-                               BAMBOO_NUM_OF_CORE);
-#endif
-               __insn_mtspr(SPR_UDN_TAG_1, UDN1_DEMUX_TAG);
-               // enable udn interrupts
-               //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
-               __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<1));
-               BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
-
                int i = 0;
                gcwaitconfirm = false;
                gcwaitconfirm = 0;
-               gcphase = 0;
+               gcphase = MARKPHASE;
                for(i = 1; i < NUMCORES - 1; i++) {
                        // send GC start messages to all cores
-                       send_msg_1(i, 0x11);
+                       send_msg_1(i, GCSTART);
                }
                bool isfirst = true;
-               lObjList.head = NULL;
-               lObjList.tail = NULL;
-               mObjList.head = NULL;
-               mObjList.tail = NULL;
+               bool allStall = false;
 
                // mark phase
-               while(gcphase == 0) {
+               while(MARKPHASE == gcphase) {
                        mark(isfirst);
                        if(isfirst) {
                                isfirst = false;
                        }
 
-                       bool allStall = false;
                        // check gcstatus
-                       if((!gcwaitconfirm) || 
-                                       (gcwaitconfirm && (gcnumconfirm == 0))) {
-                               BAMBOO_START_CRITICAL_SECTION_STATUS();  
-                               gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-                               gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
-                               gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
-                               // check the status of all cores
-                               allStall = true;
-                               for(i = 0; i < NUMCORES; ++i) {
-                                       if(gccorestatus[i] != 0) {
-                                               allStall = false;
-                                               break;
-                                       }
-                               }
-                               if(allStall) {
-                                       // 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
-                                       int sumsendobj = 0;
-                                       for(i = 0; i < NUMCORES; ++i) {
-                                               sumsendobj += gcnumsendobjs[i];
-                                       }               
-                                       for(i = 0; i < NUMCORES; ++i) {
-                                               sumsendobj -= gcnumreceiveobjs[i];
-                                       }
-                                       if(0 == sumsendobj) {
-                                               if(!gcwaitconfirm) {
-                                                       // the first time found all cores stall
-                                                       // send out status confirm msg to all other cores
-                                                       // reset the corestatus array too
-                                                       gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
-                                                       gcwaitconfirm = true;
-                                                       gcnumconfirm = NUMCORES - 1;
-                                                       for(i = 1; i < NUMCORES; ++i) { 
-                                                               gccorestatus[i] = 1;
-                                                               // send mark phase finish confirm request msg to core i
-                                                               send_msg_1(i, 0x18);
-                                                       }
-                                               } else {
-                                                       // all the core status info are the latest
-                                                       // stop mark phase
-                                                       gcphase = 1;
-                                                       for(i = 0; i < NUMCORES; ++i) {
-                                                               gccorestatus[i] = 1;
-                                                       }
-                                               } // if(!gcwautconfirm) else()
-                                       } // if(0 == sumsendobj)
-                               } // if(allStall)
-                               BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();  
-                       } // if((!gcwaitconfirm)...
-               }  // while(gcphase == 0)
+                       checkMarkStatue(); 
+               }  // while(MARKPHASE == gcphase)
                // send msgs to all cores requiring large objs info
                gcnumconfirm = NUMCORES - 1;
                for(i = 1; i < NUMCORES; ++i) {
-                       send_msg_1(i, 0x1e);
+                       send_msg_1(i, GCLOBJREQUEST);
                }       
                while(gcnumconfirm != 0) {} // wait for responses
                // TODO compute load balance
@@ -218,7 +154,7 @@ void gc() {
                // compact phase
                compact();
                gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-               while(gcphase == 1) {
+               while(COMPACTPHASE == gcphase) {
                        // check the status of all cores
                        allStall = true;
                        for(i = 0; i < NUMCORES; ++i) {
@@ -228,23 +164,25 @@ void gc() {
                                }
                        }       
                        if(allStall) {
+                               // restore the gcstatus of all cores
                                for(i = 0; i < NUMCORES; ++i) {
                                        gccorestatus[i] = 1;
                                }
                                break;
                        }
-               } // while(gcphase == 1)
+               } // while(COMPACTPHASE == gcphase)
                // TODO merge all mapping information
-               gcphase = 2;
+
+               gcphase = FLUSHPHASE;
                for(i = 1; i < NUMCORES; ++i) {
                        // send start flush messages to all cores
-                       send_msg_1(i, 0x13);
+                       send_msg_1(i, GCSTARTFLUSH);
                }
 
                // flush phase
                flush();
                gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-               while(gcphase == 2) {
+               while(FLUSHPHASE == gcphase) {
                        // check the status of all cores
                        allStall = true;
                        for(i = 0; i < NUMCORES; ++i) {
@@ -256,35 +194,21 @@ void gc() {
                        if(allStall) {
                                break;
                        }
-               } // while(gcphase == 2)
-               // TODO merge all mapping information
-               gcphase = 3;
+               } // while(FLUSHPHASE == gcphase)
+               gcphase = FINISHPHASE;
                for(i = 1; i < NUMCORES; ++i) {
                        // send gc finish messages to all cores
-                       send_msg_1(i, 0x17);
+                       send_msg_1(i, GCFINISH);
                }
-
-               // change to UDN0
-               bme_install_interrupt_handler(INT_UDN_AVAIL, udn_inter_handle);
-#ifdef DEBUG
-               tprintf("Process %x(%d): change back udn interrupt handler\n", BAMBOO_NUM_OF_CORE, 
-                               BAMBOO_NUM_OF_CORE);
-#endif
-               __insn_mtspr(SPR_UDN_TAG_0, UDN0_DEMUX_TAG);
-               // enable udn interrupts
-               //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
-               __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<0));
-               BAMBOO_START_CRITICAL_SECTION_MSG();
-               
                return;
        } else {
-               BAMBOO_EXIT(0xb001);
+               gc_collect();
        }
 }
 
 void mark(bool isfirst) {
        if(isfirst) {
-               if(gcphase != 0) {
+               if(MARKPHASE != gcphase) {
                        BAMBOO_EXIT(0xb002);
                }
                gcbusystatus = 1;
@@ -296,7 +220,7 @@ void mark(bool isfirst) {
                
                // enqueue objectsets
                int i;
-           for(i=0; i<NUMCLASSES; i++) {
+               for(i=0; i<NUMCLASSES; i++) {
                        struct parameterwrapper ** queues=objectqueues[BAMBOO_NUM_OF_CORE][i];
                        int length = numqueues[BAMBOO_NUM_OF_CORE][i];
                        for(j = 0; j < length; ++j) {
@@ -312,31 +236,32 @@ void mark(bool isfirst) {
                }
                // euqueue current task descriptor
                for(i=0; i<currtpd->numParameters; i++) {
-         void *orig=currtpd->parameterArray[i];
-             addNewItem(gctomark, orig);  
-       }
+                       void *orig=currtpd->parameterArray[i];
+                       addNewItem(gctomark, orig);  
+               }
                // euqueue active tasks
                struct genpointerlist * ptr=activetasks->list;
-           while(ptr!=NULL) {
-         struct taskparamdescriptor *tpd=ptr->src;
-             int i;
-         for(i=0; i<tpd->numParameters; i++) {
-                         void * orig=tpd->parameterArray[i];
-                         addNewItem(gctomark, orig); 
-         }
-             ptr=ptr->inext;
-           }
+               while(ptr!=NULL) {
+                       struct taskparamdescriptor *tpd=ptr->src;
+                       int i;
+                       for(i=0; i<tpd->numParameters; i++) {
+                               void * orig=tpd->parameterArray[i];
+                               addNewItem(gctomark, orig); 
+                       }
+                       ptr=ptr->inext;
+               }
        }
 
        // mark phase
-       while(gcphase == 0) {
+       while(MARKPHASE == gcphase) {
                while(!isEmpty(gctomark)) {
                        voit * ptr = getItem(gctomark);
                        int size = 0;
                        int type = 0;
                        if(isLarge(ptr, &type, &size)) {
                                // ptr is a large object
-                               struct largeObjItem * loi = 
+                               // TODO
+/*                             struct largeObjItem * loi = 
                                        (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem));  
                                loi->orig = (INTPTR)ptr;
                                loi->dst = (INTPTR)0;
@@ -346,18 +271,14 @@ void mark(bool isfirst) {
                                } else {
                                        lObjList.tail->next = loi;
                                        lObjList.tail = loi;
-                               }
+                               }*/
                        } else if (isLocal(ptr)) {
                                // ptr is an active object on this core
                                if(type == -1) {
                                        // nothing to do 
                                }
                                curr_heaptop += size;
-                               struct markedObjItem * moi = 
-                                       (struct markedObjItem *)RUNMALLOC(sizeof(struct markedObjItem)); 
-                               moi->orig = (INTPTR)ptr;
-                               moi->dst = (INTPTR)0;
-                               insertMarkedObj(&mObjList, moi);
+
                        }
                        // scan all pointers in ptr
                        unsigned INTPTR * pointer;
@@ -378,7 +299,7 @@ void mark(bool isfirst) {
                                                addNewItem(gctomark, objptr);  
                                        } else {
                                                // send a msg to host informing that objptr is active
-                                               send_msg_2(host, 0x1a, objptr);
+                                               send_msg_2(host, GCMARKEDOBJ, objptr);
                                                gcself_numsendobjs++;
                                        }
                                }
@@ -394,7 +315,7 @@ void mark(bool isfirst) {
                                                addNewItem(gctomark, objptr);  
                                        } else {
                                                // send a msg to host informing that objptr is active
-                                               send_msg_2(host, 0x1a, objptr);
+                                               send_msg_2(host, GCMARKEDOBJ, objptr);
                                                gcself_numsendobjs++;
                                        }
                                }
@@ -402,16 +323,16 @@ void mark(bool isfirst) {
                } // while(!isEmpty(gctomark))
                gcbusystatus = false;
                // send mark finish msg to core coordinator
-               send_msg_4(STARTUPCORE, 0x14, BAMBOO_NUM_OF_CORE, gcself_numsendobjs, gcself_numreceiveobjs); 
+               send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE, gcself_numsendobjs, gcself_numreceiveobjs); 
 
                if(BAMBOO_NUM_OF_CORE == 0) {
                        return;
                }
-       } // while(gcphase == 0)
+       } // while(MARKPHASE == gcphase)
 } // mark()
 
 void compact() {
-       if(gcphase != 1) {
+       if(COMPACTPHASE != gcphase) {
                BAMBOO_EXIT(0xb003);
        }
        curr_heaptop = 0;
@@ -457,7 +378,8 @@ void compact() {
                if(cinstruction->incomingobjs != NULL) {
                        for(int j = 0; j < cinstruction->incomingobjs->length; j++) {
                                // send messages to corresponding cores to start moving
-                               send_msg_2(cinstruction->incomingobjs->dsts[j], 0x1b, BAMBOO_NUM_OF_CORE);
+                               send_msg_2(cinstruction->incomingobjs->dsts[j], GCMOVESTART, 
+                                                      BAMBOO_NUM_OF_CORE);
                        }
                }
        } else {
@@ -521,7 +443,7 @@ void compact() {
                }while(cinstruction->largeobjs != NULL);
        }
        // send compact finish message to core coordinator
-       send_msg_2(STARTUPCORE, 0x15, BAMBOO_NUM_OF_CORE);
+       send_msg_2(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE);
        
 } // compact()
 
@@ -550,7 +472,8 @@ void flush() {
                                        obj2map = (int)objptr;
                                        ismapped = false;
                                        mappedobj = NULL;
-                                       send_msg_3(hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+                                       send_msg_3(hostcore(objptr), GCMAPREQUEST, (int)objptr, 
+                                                              BAMBOO_NUM_OF_CORE);
                                        while(!ismapped) {}
                                        dstptr = mappedobj;
                                }
@@ -569,7 +492,8 @@ void flush() {
                                        obj2map = (int)objptr;
                                        ismapped = false;
                                        mappedobj = NULL;
-                                       send_msg_3(hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+                                       send_msg_3(hostcore(objptr), GCMAPREQUEST, (int)objptr, 
+                                                              BAMBOO_NUM_OF_CORE);
                                        while(!ismapped) {}
                                        dstptr = mappedobj;
                                }
@@ -579,11 +503,11 @@ void flush() {
                moi = moi->next;
        } // while(moi != NULL)
        // send flush finish message to core coordinator
-       send_msg_2(STARTUPCORE, 0x16, BAMBOO_NUM_OF_CORE);
+       send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE);
        
 } // flush()
 
-void collect() {
+void gc_collect() {
        // core collector routine
        // change to UDN1
        bme_install_interrupt_handler(INT_UDN_AVAIL, gc_msghandler);
@@ -603,11 +527,11 @@ void collect() {
        mObjList.tail = NULL;
        mark(true);
        compact();
-       while(gcphase != 2) {}
+       while(FLUSHPHASE != gcphase) {}
        flush();
        
        while(true) {
-               if(gcphase == 3) {
+               if(FINISHPHASE == gcphase) {
                        // change to UDN0
                        bme_install_interrupt_handler(INT_UDN_AVAIL, udn_inter_handle);
 #ifdef DEBUG
@@ -625,314 +549,4 @@ void collect() {
        }
 }
 
-/* Message format:
- *      type + Msgbody
- * type:11 -- GC start
- *      12 -- compact phase start
- *      13 -- flush phase start
- *      14 -- mark phase finish
- *      15 -- compact phase finish
- *      16 -- flush phase finish
- *      17 -- GC finish
- *      18 -- marked phase finish confirm request
- *      19 -- marked phase finish confirm response
- *      1a -- markedObj msg
- *      1b -- start moving objs msg
- *      1c -- ask for mapping info of a markedObj
- *      1d -- mapping info of a markedObj
- *      1e -- large objs info request
- *      1f -- large objs info response
- *
- * GCMsg: 11 (size is always 1 * sizeof(int))
- *        12 + size of msg + (num of objs to move + (start address + end address + dst core + start dst)+)? + (num of incoming objs + (start dst + orig core)+)? + (num of large obj lists + (start address + lenght + start dst)+)?
- *        13 (size is always 1 * sizeof(int))
- *        14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
- *        15/16 + corenum (size is always 2 * sizeof(int))
- *        17 (size is always 1 * sizeof(int))
- *        18 (size if always 1 * sizeof(int))
- *        19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
- *        1a + obj's address (size is always 2 * sizeof(int))
- *        1b + corenum ( size is always 2 * sizeof(int))
- *        1c + obj's address + corenum (size is always 3 * sizeof(int))
- *        1d + obj's address + dst address (size if always 3 * sizeof(int))
- *        1e (size is always 1 * sizeof(int))
- *        1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
- *
- * NOTE: for Tilera, all GCMsgs except the GC start msg should be processed with a different net/port with other msgs
- */
-
-
-int gc_msghandler() {
-  int deny = 0;
-  int i = 0;
-  
-gcmsg:
-  if(receiveGCMsg() == -1) {
-         return -1;
-  }
-
-  if(gcmsgdataindex == gcmsglength) {
-    // received a whole msg
-    int type, data1;             // will receive at least 2 words including type
-    type = gcmsgdata[0];
-    data1 = gcmsgdata[1];
-    switch(gctype) {
-    case 0x12: {
-               // a compact phase start msg
-               if(cinstruction == NULL) {
-                       cinstruction = (struct compactInstr *)RUNMALLOC(sizeof(struct compactInstr));
-               } else {
-                       // clean up out of data info
-                       if(cinstruction->tomoveobjs != NULL) {
-                               RUNFREE(cinstruction->tomoveobjs->starts);
-                               RUNFREE(cinstruction->tomoveobjs->ends);
-                               RUNFREE(cinstruction->tomoveobjs->dststarts);
-                               RUNFREE(cinstruction->tomoveobjs->dsts);
-                               RUNFREE(cinstruction->tomoveobjs);
-                               cinstruction->tomoveobjs = NULL;
-                       }
-                       if(cinstruction->incomingobjs != NULL) {
-                               RUNFREE();
-                               RUNFREE(cinstruction->incomingobjs->starts);
-                               RUNFREE(cinstruction->incomingobjs->dsts);
-                               RUNFREE(cinstruction->incomingobjs);
-                               cinstruction->incomingobjs = NULL;
-                       }
-                       // largeobj items should have been freed when processed
-                       if(cinstruction->largeobjs != NULL) {
-                               BAMBOO_EXIT(0xb005);
-                       }
-               }
-               if(data1 > 2) {
-                       // have objs to move etc.
-                       int startindex = 2;
-                       // process objs to move
-                       int num = gcmsgdata[startindex++];
-                       if(num > 0) {
-                               cinstruction->tomoveobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
-                               cinstruction->tomoveobjs->length = num;
-                               cinstruction->tomoveobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               cinstruction->tomoveobjs->ends = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               cinstruction->tomoveobjs->dststarts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               cinstruction->tomoveobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               for(i = 0; i < num; i++) {
-                                       cinstruction->tomoveobjs->starts[i] = gcmsgdata[startindex++];
-                                       cinstruction->tomoveobjs->ends[i] = gcmsgdata[startindex++];
-                                       cinstruction->tomoveobjs->dsts[i] = gcmsgdata[startindex++];
-                                       cinstruction->tomoveobjs->dststarts[i] = gcmsgdata[startindex++];
-                               }
-                       }
-                       // process incoming objs
-                       num = gcmsgdata[startindex++];
-                       if(num > 0) {
-                               cinstruction->incomingobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
-                               cinstruction->incomingobjs->length = num;
-                               cinstruction->incomingobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               cinstruction->incomingobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
-                               for(i = 0; i < num; i++) {
-                                       cinstruction->incomingobjs->starts[i] = gcmsgdata[startindex++];
-                                       cinstruction->incomingobjs->dsts[i] = gcmsgdata[startindex++];
-                               }
-                       }
-                       // process large objs
-                       num = gcmsgdata[startindex++];
-                       for(i = 0; i < num; i++) {
-                               struct largeObjItem * loi = (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem ));
-                               loi->orig = gcmsgdata[startindex++];
-                               loi->length = gcmsgdata[startindex++];
-                               loi->dst = gcmsgdata[startindex++];
-                               loi->next = NULL;
-                               if(i > 0) {
-                                       cinstruction->largeobjs->next = loi;
-                               }
-                               cinstruction->largeobjs = loi;
-                       }
-               }
-               gcphase = 1;
-               break;
-       }
-
-       case 0x13: {
-               // received a flush phase start msg
-               gcphase = 2;
-               break;
-       }
-
-       case 0x14: {
-               // received a mark phase finish msg
-               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
-                 // non startup core can not receive this msg
-                 // return -1
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(data1);
-#endif
-                 BAMBOO_EXIT(0xb006);
-      } 
-      if(data1 < NUMCORES) {
-                 gccorestatus[data1] = 0;
-                 gcnumsendobjs[data1] = gcmsgdata[2];
-                 gcnumreceiveobjs[data1] = gcmsgdata[3];
-      }
-         break;
-       }
-       
-       case 0x15: {
-               // received a compact phase finish msg
-               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
-                 // non startup core can not receive this msg
-                 // return -1
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(data1);
-#endif
-                 BAMBOO_EXIT(0xb006);
-      } 
-      if(data1 < NUMCORES) {
-                 gccorestatus[data1] = 0;
-      }
-         break;
-       }
-
-       case 0x16: {
-               // received a flush phase finish msg
-               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
-                 // non startup core can not receive this msg
-                 // return -1
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(data1);
-#endif
-                 BAMBOO_EXIT(0xb006);
-      } 
-      if(data1 < NUMCORES) {
-                 gccorestatus[data1] = 0;
-      }
-         break;
-       }
-
-       case 0x17: {
-               // received a GC finish msg
-               gcphase = 3;
-               break;
-       }
-
-       case 0x18: {
-               // received a marked phase finish confirm request msg
-               if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
-                 // wrong core to receive such msg
-                 BAMBOO_EXIT(0xa013);
-      } else {
-                 // send response msg
-                 if(gcisMsgSending) {
-                         cache_msg_5(STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
-                 } else {
-                         send_msg_5(STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
-                 }
-      }
-         break;
-       }
-
-       case 0x19: {
-               // received a marked phase finish confirm response msg
-               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
-                 // wrong core to receive such msg
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(gcmsgdata[2]);
-#endif
-                 BAMBOO_EXIT(0xb014);
-      } else {
-                 if(gcwaitconfirm) {
-                         gcnumconfirm--;
-                 }
-                 gccorestatus[data1] = gcmsgdata[2];
-                 gcnumsendobjs[data1] = gcmsgdata[3];
-                 gcnumreceiveobjs[data1] = gcmsgdata[4];
-      }
-         break;
-       }
-
-       case 0x1a: {
-               // received a markedObj msg
-               addNewItem(gctomark, data1);
-               gcself_numreceiveobjs++;
-               gcbusystatus = true;
-               break;
-       }
-
-       case 0x1b: {
-               // received a start moving objs msg
-               addNewItem_I(gcdsts, data1);
-               tomove = true;
-               break;
-       }
-       
-       case 0x1c: {
-               // received a mapping info request msg
-               void * dstptr = gengettable(pointertbl, data1);
-               if(NULL == dstptr) {
-                       // no such pointer in this core, something is wrong
-                       BAMBOO_EXIT(0xb008);
-               } else {
-                       // send back the mapping info
-                       if(gcisMsgSending) {
-                               cache_msg_3(gcmsgdata[2], 0x1d, data1, dstptr);
-                       } else {
-                               send_msg_3(gcmsgdata[2], 0x1d, data1, dstptr);
-                       }
-               }
-               break;
-       }
-
-       case 0x1d: {
-               // received a mapping info response msg
-               if(data1 != obj2map) {
-                       // obj not matched, something is wrong
-                       BAMBOO_EXIT(0xb009);
-               } else {
-                       mappedobj = gcmsgdata[2];
-                       genputtable(pointertbl, obj2map, mappedobj);
-               }
-               ismapped = true;
-               break;
-       }
-
-       case 0x1e: {
-               // received a large objs info request msg
-               transferMarkResults();
-               break;
-       }
-
-       case 0x1f: {
-               // received a large objs info response msg
-               // TODO
-               gcwaitconfirm--;
-               break;
-       }
-                       
-       default:
-      break;
-    }
-    for(gcmsgdataindex--; gcmsgdataindex > 0; --gcmsgdataindex) {
-      gcmsgdata[gcmsgdataindex] = -1;
-    }
-    gcmsgtype = -1;
-    gcmsglength = 30;
-
-    if(BAMBOO_GCMSG_AVAIL() != 0) {
-      goto gcmsg;
-    }
-#ifdef PROFILE
-       /*if(isInterrupt) {
-           profileTaskEnd();
-    }*/
-#endif
-    return type;
-  } else {
-    // not a whole msg
-#ifdef DEBUG
-#ifndef TILERA
-    BAMBOO_DEBUGPRINT(0xe88d);
-#endif
-#endif
-    return -2;
-  }
-}
 #endif
index 8a6283d1747375657f86c6b31ee117a1e88a789b..e2f8b695f4b474eab287bd120dc73a1927f805b6 100644 (file)
 #define BAMBOO_SMEM_SIZE_L 512 * BAMBOO_PAGE_SIZE
 #define BAMBOO_LARGE_SMEM_BOUND BAMBOO_SMEM_SIZE_L * NUMCORES // NUMCORES = 62
 
-// for GC msgs
-int gcmsgdata[100];
-int gcmsgtype;
-int gcmsgdataindex;
-int gcmsglength;
-#define BAMBOO_OUT_BUF_LENGTH_GC 100
-int gcoutmsgdata[BAMBOO_OUT_BUF_LENGTH_GC];
-int gcoutmsgindex;
-int gcoutmsglast;
-int gcoutmsgleft;
-bool gcisMsgHanging;
-volatile bool gcisMsgSending;
-
 struct markedObjItem {
        INTPTR orig;
        INTPTR dst;
@@ -51,7 +38,15 @@ struct compactInstr {
        struct largeObjItem * largeobjs;
 };
 
-int gcphase; // indicating GC phase
+enum GCPHASETYPE {
+       MARKPHASE = 0x0,   // 0x0
+       COMPACTPHASE,      // 0x1
+       FLUSHPHASE,        // 0x2
+       FINISHPHASE        // 0x3
+};
+
+volatile bool gcflag;
+GCPHASETYPE gcphase; // indicating GC phase
 bool gctomove; // flag indicating if can start moving objects to other cores
 struct Queue * gcdsts;
 struct Queue gctomark; // global queue of objects to mark
@@ -108,8 +103,8 @@ bool ismapped;
        }
 
 void gc(); // core coordinator routine
-void collect(); // core collector routine
-int gc_msghandler(); // interruption handler for GC msgs
+void gc_collect(); // core collector routine
+void transferMarkResults(); 
 
 #endif
 
index fe9f4ed24558debbced721f46ef521e499b0667b..591cad1cdc351a22840ca9567f8399092b4e2d10 100644 (file)
@@ -6,11 +6,11 @@
 ///////////////////////////////////////////////////////////////
 
 // data structures for msgs
+#define BAMBOO_OUT_BUF_LENGTH 300
 int msgdata[30];
 int msgtype;
 int msgdataindex;
 int msglength;
-#define BAMBOO_OUT_BUF_LENGTH 300
 int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
 int outmsgindex;
 int outmsglast;
@@ -18,6 +18,112 @@ int outmsgleft;
 bool isMsgHanging;
 volatile bool isMsgSending;
 
+/* Message format:
+ *      type + Msgbody
+ * type: 0 -- transfer object
+ *       1 -- transfer stall msg
+ *       2 -- lock request
+ *       3 -- lock grount
+ *       4 -- lock deny
+ *       5 -- lock release
+ *       // add for profile info
+ *       6 -- transfer profile output msg
+ *       7 -- transfer profile output finish msg
+ *       // add for alias lock strategy
+ *       8 -- redirect lock request
+ *       9 -- lock grant with redirect info
+ *       a -- lock deny with redirect info
+ *       b -- lock release with redirect info
+ *       c -- status confirm request
+ *       d -- status report msg
+ *       e -- terminate
+ *       f -- requiring for new memory
+ *      10 -- response for new memory request
+ *      11 -- GC start
+ *      12 -- compact phase start
+ *      13 -- flush phase start
+ *      14 -- mark phase finish
+ *      15 -- compact phase finish
+ *      16 -- flush phase finish
+ *      17 -- GC finish
+ *      18 -- marked phase finish confirm request
+ *      19 -- marked phase finish confirm response
+ *      1a -- markedObj msg
+ *      1b -- start moving objs msg
+ *      1c -- ask for mapping info of a markedObj
+ *      1d -- mapping info of a markedObj
+ *      1e -- large objs info request
+ *      1f -- large objs info response
+ *
+ * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
+ * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
+ * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
+ *          3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
+ *          8 + lock type + obj pointer +  redirect lock + root request core + request core (size is always 6 * sizeof(int))
+ *          9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
+ *          b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
+ *          lock type: 0 -- read; 1 -- write
+ * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
+ *             7 + corenum (size is always 2 * sizeof(int))
+ * StatusMsg: c (size is always 1 * sizeof(int))
+ *            d + status + corenum (size is always 3 * sizeof(int))
+ *            status: 0 -- stall; 1 -- busy
+ * TerminateMsg: e (size is always 1 * sizeof(int)
+ * MemoryMsg: f + size + corenum (size is always 3 * sizeof(int))
+ *           10 + base_va + size (size is always 3 * sizeof(int))
+ * GCMsg: 11 (size is always 1 * sizeof(int))
+ *        12 + size of msg + (num of objs to move + (start address + end address + dst core + start dst)+)? + (num of incoming objs + (start dst + orig core)+)? + (num of large obj lists + (start address + lenght + start dst)+)?
+ *        13 (size is always 1 * sizeof(int))
+ *        14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
+ *        15/16 + corenum (size is always 2 * sizeof(int))
+ *        17 (size is always 1 * sizeof(int))
+ *        18 (size if always 1 * sizeof(int))
+ *        19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
+ *        1a + obj's address (size is always 2 * sizeof(int))
+ *        1b + corenum ( size is always 2 * sizeof(int))
+ *        1c + obj's address + corenum (size is always 3 * sizeof(int))
+ *        1d + obj's address + dst address (size if always 3 * sizeof(int))
+ *        1e (size is always 1 * sizeof(int))
+ *        1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
+ */
+enum MSGTYPE {
+       TRANSOBJ = 0x0,  // 0x0
+       TRANSTALL,       // 0x1
+       LOCKREQUEST,     // 0x2
+       LOCKGROUNT,      // 0x3
+       LOCKDENY,        // 0x4
+       LOCKRELEASE,     // 0x5
+       PROFILEOUTPUT,   // 0x6
+       PROFILEFINISH,   // 0x7
+       REDIRECTLOCK,    // 0x8
+       REDIRECTGROUNT,  // 0x9
+       REDIRECTDENY,    // 0xa
+       REDIRECTRELEASE, // 0xb
+       STATUSCONFIRM,   // 0xc
+       STATUSREPORT,    // 0xd
+       TERMINATE,       // 0xe
+       MEMREQUEST,      // 0xf
+       MEMRESPONSE,     // 0x10
+#ifdef MULTICORE_GC
+       GCSTART,         // 0x11
+       GCSTARTCOMPACT,  // 0x12
+       GCSTARTFLUSH,    // 0x13
+       GCFINISHMARK,    // 0x14
+       GCFINISHCOMPACT, // 0x15
+       GCFINISHFLUSH,   // 0x16
+       GCFINISH,        // 0x17
+       GCMARKCONFIRM,   // 0x18
+       GCMARKREPORT,    // 0x19
+       GCMARKEDOBJ,     // 0x1a
+       GCMOVESTART,     // 0x1b
+       GCMAPREQUEST,    // 0x1c
+       GCMAPINFO,       // 0x1d
+       GCLOBJREQUEST,   // 0x1e
+       GCLOBJINFO,      // 0x1f
+#endif
+       MSGEND
+};
+
 // data structures of status for termination
 int corestatus[NUMCORES]; // records status of each core
                           // 1: running tasks
index 2a9bfce5cac72a6091c381bccf9d620f3a179326..38bf9b58446c318031b187802f0484ca17c805ef 100644 (file)
@@ -378,7 +378,7 @@ objqueuebreak:
                                                                  for(i = 1; i < NUMCORES; ++i) {       
                                                                          corestatus[i] = 1;
                                                                          // send status confirm msg to core i
-                                                                         send_msg_1(i, 0xc);
+                                                                         send_msg_1(i, STATUSCONFIRM);
                                                                  }
                                                                  waitconfirm = true;
                                                                  numconfirm = NUMCORES - 1;
@@ -406,7 +406,7 @@ objqueuebreak:
 #endif
                                                                  for(i = 1; i < NUMCORES; ++i) {
                                                                          // send profile request msg to core i
-                                                                         send_msg_2(i, 6, totalexetime);
+                                                                         send_msg_2(i, PROFILEOUTPUT, totalexetime);
                                                                  }
                                                                  // pour profiling data on startup core
                                                                  outputProfileData();
@@ -1081,77 +1081,6 @@ inline void addNewObjInfo(void * nobj) {
 }
 #endif
 
-/* Message format:
- *      type + Msgbody
- * type: 0 -- transfer object
- *       1 -- transfer stall msg
- *       2 -- lock request
- *       3 -- lock grount
- *       4 -- lock deny
- *       5 -- lock release
- *       // add for profile info
- *       6 -- transfer profile output msg
- *       7 -- transfer profile output finish msg
- *       // add for alias lock strategy
- *       8 -- redirect lock request
- *       9 -- lock grant with redirect info
- *       a -- lock deny with redirect info
- *       b -- lock release with redirect info
- *       c -- status confirm request
- *       d -- status report msg
- *       e -- terminate
- *       f -- requiring for new memory
- *      10 -- response for new memory request
- *      11 -- GC start
- *      12 -- compact phase start
- *      13 -- flush phase start
- *      14 -- mark phase finish
- *      15 -- compact phase finish
- *      16 -- flush phase finish
- *      17 -- GC finish
- *      18 -- marked phase finish confirm request
- *      19 -- marked phase finish confirm response
- *      1a -- markedObj msg
- *      1b -- start moving objs msg
- *      1c -- ask for mapping info of a markedObj
- *      1d -- mapping info of a markedObj
- *      1e -- large objs info request
- *      1f -- large objs info response
- *
- * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
- * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
- * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
- *          3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
- *          8 + lock type + obj pointer +  redirect lock + root request core + request core (size is always 6 * sizeof(int))
- *          9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
- *          b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
- *          lock type: 0 -- read; 1 -- write
- * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
- *             7 + corenum (size is always 2 * sizeof(int))
- * StatusMsg: c (size is always 1 * sizeof(int))
- *            d + status + corenum (size is always 3 * sizeof(int))
- *            status: 0 -- stall; 1 -- busy
- * TerminateMsg: e (size is always 1 * sizeof(int)
- * MemoryMsg: f + size + corenum (size is always 3 * sizeof(int))
- *           10 + base_va + size (size is always 3 * sizeof(int))
- * GCMsg: 11 (size is always 1 * sizeof(int))
- *        12 + size of msg + (num of objs to move + (start address + end address + dst core + start dst)+)? + (num of incoming objs + (start dst + orig core)+)? + (num of large obj lists + (start address + lenght + start dst)+)?
- *        13 (size is always 1 * sizeof(int))
- *        14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
- *        15/16 + corenum (size is always 2 * sizeof(int))
- *        17 (size is always 1 * sizeof(int))
- *        18 (size if always 1 * sizeof(int))
- *        19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
- *        1a + obj's address (size is always 2 * sizeof(int))
- *        1b + corenum ( size is always 2 * sizeof(int))
- *        1c + obj's address + corenum (size is always 3 * sizeof(int))
- *        1d + obj's address + dst address (size if always 3 * sizeof(int))
- *        1e (size is always 1 * sizeof(int))
- *        1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
- *
- * NOTE: for Tilera, all GCMsgs except the GC start msg should be processed with a different net/port with other msgs
- */
-
 // receive object transferred from other cores
 // or the terminate message from other cores
 // Should be invoked in critical sections!!
@@ -1176,227 +1105,228 @@ msg:
 
   if(msgdataindex == msglength) {
     // received a whole msg
-    int type, data1;             // will receive at least 2 words including type
+    MSGTYPE type; 
+               int data1;             // will receive at least 2 words including type
     type = msgdata[0];
     data1 = msgdata[1];
     switch(type) {
-    case 0: {
+    case TRANSOBJ: {
       // receive a object transfer msg
       struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
       int k = 0;
 #ifdef DEBUG
 #ifndef TILERA
-         BAMBOO_DEBUGPRINT(0xe880);
+                       BAMBOO_DEBUGPRINT(0xe880);
 #endif
 #endif
       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+                               BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
-                 BAMBOO_EXIT(0xa005);
-      } 
+                               BAMBOO_EXIT(0xa005);
+                       
       // store the object and its corresponding queue info, enqueue it later
-      transObj->objptr = (void *)msgdata[2];                                           // data1 is now size of the msg
+      transObj->objptr = (void *)msgdata[2];   // data1 is now size of the msg
       transObj->length = (msglength - 3) / 2;
       transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
       for(k = 0; k < transObj->length; ++k) {
-                 transObj->queues[2*k] = msgdata[3+2*k];
+                               transObj->queues[2*k] = msgdata[3+2*k];
 #ifdef DEBUG
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
+                               BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
 #endif
 #endif
-                 transObj->queues[2*k+1] = msgdata[3+2*k+1];
+                               transObj->queues[2*k+1] = msgdata[3+2*k+1];
 #ifdef DEBUG
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
+                               BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
 #endif
 #endif
-      }
+                       }
       // check if there is an existing duplicate item
       {
-                 struct QueueItem * qitem = getHead(&objqueue);
-                 struct QueueItem * prev = NULL;
-                 while(qitem != NULL) {
-                         struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
-                         if(tmpinfo->objptr == transObj->objptr) {
-                                 // the same object, remove outdate one
-                                 removeItem(&objqueue, qitem);
-                                 //break;
-                         } else {
-                                 prev = qitem;
-                         }
-                         if(prev == NULL) {
-                                 qitem = getHead(&objqueue);
-                         } else {
-                                 qitem = getNextQueueItem(prev);
-                         }
-                 }
-                 addNewItem_I(&objqueue, (void *)transObj);
-         }
+                               struct QueueItem * qitem = getHead(&objqueue);
+                               struct QueueItem * prev = NULL;
+                               while(qitem != NULL) {
+                                       struct transObjInfo * tmpinfo = 
+                                               (struct transObjInfo *)(qitem->objectptr);
+                                       if(tmpinfo->objptr == transObj->objptr) {
+                                               // the same object, remove outdate one
+                                               removeItem(&objqueue, qitem);
+                                               //break;
+                                       } else {
+                                               prev = qitem;
+                                       }
+                                       if(prev == NULL) {
+                                               qitem = getHead(&objqueue);
+                                       } else {
+                                               qitem = getNextQueueItem(prev);
+                                       }
+                               }
+                               addNewItem_I(&objqueue, (void *)transObj);
+                       }
       ++(self_numreceiveobjs);
       break;
     }
 
-    case 1: {
+    case TRANSTALL: {
       // receive a stall msg
       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // non startup core can not receive stall msg
-                 // return -1
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(data1);
+                               BAMBOO_DEBUGPRINT_REG(data1);
 #endif
-                 BAMBOO_EXIT(0xa006);
+                               BAMBOO_EXIT(0xa006);
       } 
       if(data1 < NUMCORES) {
 #ifdef DEBUG
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe881);
+                               BAMBOO_DEBUGPRINT(0xe881);
 #endif
 #endif
-                 corestatus[data1] = 0;
-                 numsendobjs[data1] = msgdata[2];
-                 numreceiveobjs[data1] = msgdata[3];
+                               corestatus[data1] = 0;
+                               numsendobjs[data1] = msgdata[2];
+                               numreceiveobjs[data1] = msgdata[3];
       }
       break;
     }
 
-    case 2: {
+    case LOCKREQUEST: {
       // receive lock request msg, handle it right now
       // check to see if there is a lock exist for the required obj
-         // data1 -> lock type
-         int data2 = msgdata[2]; // obj pointer
+                       // data1 -> lock type
+                       int data2 = msgdata[2]; // obj pointer
       int data3 = msgdata[3]; // lock
-         int data4 = msgdata[4]; // request core
+                       int data4 = msgdata[4]; // request core
       deny = processlockrequest(data1, data3, data2, data4, data4, true);  // -1: redirected, 0: approved, 1: denied
-         if(deny == -1) {
-                 // this lock request is redirected
-                 break;
-         } else {
-                 // send response msg
-                 // for 32 bit machine, the size is always 4 words
-                 int tmp = deny==1?4:3;
-                 if(isMsgSending) {
-                         cache_msg_4(data4, tmp, data1, data2, data3);
-                 } else {
-                         send_msg_4(data4, tmp, data1, data2, data3);
-                 }
-         }
+                       if(deny == -1) {
+                               // this lock request is redirected
+                               break;
+                       } else {
+                               // send response msg
+                               // for 32 bit machine, the size is always 4 words
+                               int tmp = deny==1?LOCKDENY:LOCKGROUNT;
+                               if(isMsgSending) {
+                                       cache_msg_4(data4, tmp, data1, data2, data3);
+                               } else {
+                                       send_msg_4(data4, tmp, data1, data2, data3);
+                               }
+                       }
       break;
     }
 
-    case 3: {
+    case LOCKGROUNT: {
       // receive lock grount msg
       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+                               BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
-                 BAMBOO_EXIT(0xa007);
+                               BAMBOO_EXIT(0xa007);
       } 
       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
 #ifdef DEBUG
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe882);
+                               BAMBOO_DEBUGPRINT(0xe882);
 #endif
 #endif
-                 lockresult = 1;
-                 lockflag = true;
+                               lockresult = 1;
+                               lockflag = true;
 #ifndef INTERRUPT
-                 reside = false;
+                               reside = false;
 #endif
-         } else {
-                 // conflicts on lockresults
+                       } else {
+                               // conflicts on lockresults
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+                               BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
-                 BAMBOO_EXIT(0xa008);
+                               BAMBOO_EXIT(0xa008);
       }
       break;
     }
 
-    case 4: {
+    case LOCKDENY: {
       // receive lock deny msg
       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+                               BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
-                 BAMBOO_EXIT(0xa009);
+                               BAMBOO_EXIT(0xa009);
       } 
       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
 #ifdef DEBUG
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe883);
+                               BAMBOO_DEBUGPRINT(0xe883);
 #endif
 #endif
-                 lockresult = 0;
-                 lockflag = true;
+                               lockresult = 0;
+                               lockflag = true;
 #ifndef INTERRUPT
-                 reside = false;
+                               reside = false;
 #endif
-      } else {
-                 // conflicts on lockresults
+                               } else {
+                               // conflicts on lockresults
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+                               BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
-                 BAMBOO_EXIT(0xa00a);
+                               BAMBOO_EXIT(0xa00a);
       }
       break;
     }
 
-    case 5: {
+    case LOCKRELEASE: {
       // receive lock release msg
                        processlockrelease(data1, msgdata[2], 0, false);
       break;
     }
 
 #ifdef PROFILE
-    case 6: {
+    case PROFILEOUTPUT: {
       // receive an output profile data request msg
       if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
-                 // startup core can not receive profile output finish msg
-                 BAMBOO_EXIT(0xa00c);
+                               // startup core can not receive profile output finish msg
+                               BAMBOO_EXIT(0xa00c);
       }
 #ifdef DEBUG
 #ifndef TILEAR
-         BAMBOO_DEBUGPRINT(0xe885);
+                       BAMBOO_DEBUGPRINT(0xe885);
 #endif
 #endif
-         stall = true;
-         totalexetime = data1;
-         outputProfileData();
-         if(isMsgSending) {
-                 cache_msg_2(STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
-         } else {
-                 send_msg_2(STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
-         }
+                       stall = true;
+                       totalexetime = data1;
+                       outputProfileData();
+                       if(isMsgSending) {
+                               cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
+                       } else {
+                               send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
+                       }
       break;
     }
 
-    case 7: {
+    case PROFILEFINISH: {
       // receive a profile output finish msg
       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
-                 // non startup core can not receive profile output finish msg
+                               // non startup core can not receive profile output finish msg
 #ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(data1);
+                               BAMBOO_DEBUGPRINT_REG(data1);
 #endif
-                 BAMBOO_EXIT(0xa00d);
+                               BAMBOO_EXIT(0xa00d);
       }
 #ifdef DEBUG
 #ifndef TILERA
-         BAMBOO_DEBUGPRINT(0xe886);
+                       BAMBOO_DEBUGPRINT(0xe886);
 #endif
 #endif
-      profilestatus[data1] = 0;
+                       profilestatus[data1] = 0;
       break;
     }
 #endif
 
-       case 8: {
+       case REDIRECTLOCK: {
          // receive a redirect lock request msg, handle it right now
-      // check to see if there is a lock exist for the required obj
+               // check to see if there is a lock exist for the required obj
          // data1 -> lock type
          int data2 = msgdata[2]; // obj pointer
-      int data3 = msgdata[3]; // redirect lock
+               int data3 = msgdata[3]; // redirect lock
          int data4 = msgdata[4]; // root request core
          int data5 = msgdata[5]; // request core
          deny = processlockrequest(data1, data3, data2, data5, data4, true);
@@ -1407,15 +1337,17 @@ msg:
                  // send response msg
                  // for 32 bit machine, the size is always 4 words
                  if(isMsgSending) {
-                         cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
+                         cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
+                                                       data1, data2, data3);
                  } else {
-                         send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
+                         send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
+                                                      data1, data2, data3);
                  }
          }
          break;
        }
 
-       case 9: {
+       case REDIRECTGROUNT: {
                // receive a lock grant msg with redirect info
                if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
@@ -1423,7 +1355,7 @@ msg:
 #endif
                        BAMBOO_EXIT(0xa00e);
                }
-      if(lockobj == msgdata[2]) {
+               if(lockobj == msgdata[2]) {
 #ifdef DEBUG
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT(0xe891);
@@ -1435,17 +1367,17 @@ msg:
 #ifndef INTERRUPT
                  reside = false;
 #endif
-      } else {
+               } else {
                  // conflicts on lockresults
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa00f);
-      }
+               }
                break;
        }
        
-       case 0xa: {
+       case REDIRECTDENY: {
          // receive a lock deny msg with redirect info
          if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
@@ -1453,7 +1385,7 @@ msg:
 #endif
                  BAMBOO_EXIT(0xa010);
          }
-      if(lockobj == msgdata[2]) {
+               if(lockobj == msgdata[2]) {
 #ifdef DEBUG
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT(0xe892);
@@ -1464,28 +1396,29 @@ msg:
 #ifndef INTERRUPT
                  reside = false;
 #endif
-      } else {
+               } else {
                  // conflicts on lockresults
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa011);
-      }
+               }
                break;
        }
 
-       case 0xb: {
+       case REDIRECTRELEASE: {
          // receive a lock release msg with redirect info
                processlockrelease(data1, msgdata[2], msgdata[3], true);
                break;
        }
        
-       case 0xc: {
+       case STATUSCONFIRM: {
       // receive a status confirm info
-         if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
+         if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
+                               || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
                  // wrong core to receive such msg
                  BAMBOO_EXIT(0xa013);
-      } else {
+               } else {
                  // send response msg
 #ifdef DEBUG
 #ifndef TILERA
@@ -1493,15 +1426,17 @@ msg:
 #endif
 #endif
                  if(isMsgSending) {
-                         cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
+                         cache_msg_3(STARTUPCORE, STATUSREPORT, 
+                                                       busystatus?1:0, BAMBOO_NUM_OF_CORE);
                  } else {
-                         send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
+                         send_msg_3(STARTUPCORE, STATUSREPORT, 
+                                                      busystatus?1:0, BAMBOO_NUM_OF_CORE);
                  }
-      }
+               }
          break;
        }
 
-       case 0xd: {
+       case STATUSREPORT: {
          // receive a status confirm info
          if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // wrong core to receive such msg
@@ -1509,7 +1444,7 @@ msg:
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa014);
-      } else {
+               } else {
 #ifdef DEBUG
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT(0xe888);
@@ -1519,22 +1454,22 @@ msg:
                          numconfirm--;
                  }
                  corestatus[msgdata[2]] = msgdata[1];
-      }
+               }
          break;
        }
 
-       case 0xe: {
+       case TERMINATE: {
          // receive a terminate msg
 #ifdef DEBUG
 #ifndef TILERA
-                                 BAMBOO_DEBUGPRINT(0xe889);
+               BAMBOO_DEBUGPRINT(0xe889);
 #endif
 #endif
-                                 BAMBOO_EXIT(0);
+               BAMBOO_EXIT(0);
          break;
        }
 
-       case 0xf: {
+       case MEMREQUEST: {
          // receive a shared memory request msg
          if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // wrong core to receive such msg
@@ -1542,7 +1477,7 @@ msg:
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa015);
-      } else {
+               } else {
 #ifdef DEBUG
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT(0xe88a);
@@ -1555,17 +1490,17 @@ msg:
                          BAMBOO_EXIT(0xa016);
                  }
                  // send the start_va to request core
-                if(isMsgSending) {
-                         cache_msg_3(msgdata[2], 0x10, mem, msgdata[1]);
-                 } else {
-                         send_msg_3( msgdata[2], 0x10, mem, msgdata[1]);
-                 } 
-      }
+                       if(isMsgSending) {
+                               cache_msg_3(msgdata[2], MEMRESPONSE, mem, msgdata[1]);
+                       } else {
+                               send_msg_3( msgdata[2], MEMRESPONSE, mem, msgdata[1]);
+                       
+               }
          break;
        }
 
-       case 0x10: {
-      // receive a shared memory response msg
+       case MEMRESPONSE: {
+               // receive a shared memory response msg
 #ifdef DEBUG
 #ifndef TILERA
          BAMBOO_DEBUGPRINT(0xe88b);
@@ -1580,53 +1515,299 @@ msg:
          }
          smemflag = true;
          break;
-    }
+       }
 
-       case 0x11: {
-      // receive a start GC msg
+#ifdef MULTICORE_GC
+       // GC msgs
+       case GCSTART: {
+               // receive a start GC msg
 #ifdef DEBUG
 #ifndef TILERA
          BAMBOO_DEBUGPRINT(0xe88c);
 #endif
 #endif
-         collect();
+         // set the GC flag
+               gcflag = true;
          break;
-    }
+       }
+
+       case GCSTARTCOMPACT: {
+               // a compact phase start msg
+               if(cinstruction == NULL) {
+                       cinstruction = 
+                               (struct compactInstr *)RUNMALLOC(sizeof(struct compactInstr));
+               } else {
+                       // clean up out of data info
+                       if(cinstruction->tomoveobjs != NULL) {
+                               RUNFREE(cinstruction->tomoveobjs->starts);
+                               RUNFREE(cinstruction->tomoveobjs->ends);
+                               RUNFREE(cinstruction->tomoveobjs->dststarts);
+                               RUNFREE(cinstruction->tomoveobjs->dsts);
+                               RUNFREE(cinstruction->tomoveobjs);
+                               cinstruction->tomoveobjs = NULL;
+                       }
+                       if(cinstruction->incomingobjs != NULL) {
+                               RUNFREE();
+                               RUNFREE(cinstruction->incomingobjs->starts);
+                               RUNFREE(cinstruction->incomingobjs->dsts);
+                               RUNFREE(cinstruction->incomingobjs);
+                               cinstruction->incomingobjs = NULL;
+                       }
+                       // largeobj items should have been freed when processed
+                       if(cinstruction->largeobjs != NULL) {
+                               BAMBOO_EXIT(0xb005);
+                       }
+               }
+               if(data1 > 2) {
+                       // have objs to move etc.
+                       int startindex = 2;
+                       // process objs to move
+                       int num = msgdata[startindex++];
+                       if(num > 0) {
+                               cinstruction->tomoveobjs = 
+                                       (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
+                               cinstruction->tomoveobjs->length = num;
+                               cinstruction->tomoveobjs->starts = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               cinstruction->tomoveobjs->ends = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               cinstruction->tomoveobjs->dststarts = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               cinstruction->tomoveobjs->dsts = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               for(i = 0; i < num; i++) {
+                                       cinstruction->tomoveobjs->starts[i] = msgdata[startindex++];
+                                       cinstruction->tomoveobjs->ends[i] = msgdata[startindex++];
+                                       cinstruction->tomoveobjs->dsts[i] = msgdata[startindex++];
+                                       cinstruction->tomoveobjs->dststarts[i] = msgdata[startindex++];
+                               }
+                       }
+                       // process incoming objs
+                       num = msgdata[startindex++];
+                       if(num > 0) {
+                               cinstruction->incomingobjs = 
+                                       (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
+                               cinstruction->incomingobjs->length = num;
+                               cinstruction->incomingobjs->starts = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               cinstruction->incomingobjs->dsts = 
+                                       (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+                               for(i = 0; i < num; i++) {
+                                       cinstruction->incomingobjs->starts[i] = msgdata[startindex++];
+                                       cinstruction->incomingobjs->dsts[i] = msgdata[startindex++];
+                               }
+                       }
+                       // process large objs
+                       num = msgdata[startindex++];
+                       for(i = 0; i < num; i++) {
+                               struct largeObjItem * loi = 
+                                       (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem ));
+                               loi->orig = msgdata[startindex++];
+                               loi->length = msgdata[startindex++];
+                               loi->dst = msgdata[startindex++];
+                               loi->next = NULL;
+                               if(i > 0) {
+                                       cinstruction->largeobjs->next = loi;
+                               }
+                               cinstruction->largeobjs = loi;
+                       }
+               }
+               gcphase = COMPACTPHASE;
+               break;
+       }
+
+       case GCSTARTFLUSH: {
+               // received a flush phase start msg
+               gcphase = FLUSHPHASE;
+               break;
+       }
+
+       case GCFINISHMARK: {
+               // received a mark phase finish msg
+               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+                 // non startup core can not receive this msg
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+                 BAMBOO_EXIT(0xb006);
+               } 
+               if(data1 < NUMCORES) {
+                       gccorestatus[data1] = 0;
+                       gcnumsendobjs[data1] = gcmsgdata[2];
+                       gcnumreceiveobjs[data1] = gcmsgdata[3];
+               }
+         break;
+       }
        
-    default:
-      break;
-    }
-    for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
-      msgdata[msgdataindex] = -1;
-    }
-    msgtype = -1;
-    msglength = 30;
+       case GCFINISHCOMPACT: {
+               // received a compact phase finish msg
+               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+                 // non startup core can not receive this msg
+                 // return -1
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+                 BAMBOO_EXIT(0xb006);
+               } 
+               if(data1 < NUMCORES) {
+                 gccorestatus[data1] = 0;
+               }
+         break;
+       }
+
+       case GCFINISHFLUSH: {
+               // received a flush phase finish msg
+               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+                 // non startup core can not receive this msg
+                 // return -1
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+                 BAMBOO_EXIT(0xb006);
+               } 
+               if(data1 < NUMCORES) {
+                 gccorestatus[data1] = 0;
+               }
+         break;
+       }
+
+       case GCFINISH: {
+               // received a GC finish msg
+               gcphase = FINISHPHASE;
+               break;
+       }
+
+       case GCMARKCONFIRM: {
+               // received a marked phase finish confirm request msg
+               if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
+                               || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
+                 // wrong core to receive such msg
+                 BAMBOO_EXIT(0xa013);
+               } else {
+                 // send response msg
+                 if(isMsgSending) {
+                         cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
+                                                       gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+                 } else {
+                         send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
+                                                      gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+                 }
+               }
+         break;
+       }
+
+       case GCMARKREPORT: {
+               // received a marked phase finish confirm response msg
+               if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+                 // wrong core to receive such msg
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
+#endif
+                 BAMBOO_EXIT(0xb014);
+               } else {
+                 if(gcwaitconfirm) {
+                         gcnumconfirm--;
+                 }
+                 gccorestatus[data1] = gcmsgdata[2];
+                 gcnumsendobjs[data1] = gcmsgdata[3];
+                 gcnumreceiveobjs[data1] = gcmsgdata[4];
+               }
+         break;
+       }
+
+       case GCMARKEDOBJ: {
+               // received a markedObj msg
+               addNewItem(gctomark, data1);
+               gcself_numreceiveobjs++;
+               gcbusystatus = true;
+               break;
+       }
+
+       case GCMOVESTART: {
+               // received a start moving objs msg
+               addNewItem_I(gcdsts, data1);
+               tomove = true;
+               break;
+       }
+       
+       case GCMAPREQUEST: {
+               // received a mapping info request msg
+               void * dstptr = gengettable(pointertbl, data1);
+               if(NULL == dstptr) {
+                       // no such pointer in this core, something is wrong
+                       BAMBOO_EXIT(0xb008);
+               } else {
+                       // send back the mapping info
+                       if(isMsgSending) {
+                               cache_msg_3(msgdata[2], GCMAPINFO, data1, dstptr);
+                       } else {
+                               send_msg_3(msgdata[2], GCMAPINFO,data1, dstptr);
+                       }
+               }
+               break;
+       }
+
+       case GCMAPINFO: {
+               // received a mapping info response msg
+               if(data1 != obj2map) {
+                       // obj not matched, something is wrong
+                       BAMBOO_EXIT(0xb009);
+               } else {
+                       mappedobj = msgdata[2];
+                       genputtable(pointertbl, obj2map, mappedobj);
+               }
+               ismapped = true;
+               break;
+       }
+
+       case GCLOBJREQUEST: {
+               // received a large objs info request msg
+               transferMarkResults();
+               break;
+       }
+
+       case GCLOBJINFO: {
+               // received a large objs info response msg
+               // TODO
+               gcwaitconfirm--;
+               break;
+       }
+#endif
+
+       default:
+               break;
+       }
+       for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
+               msgdata[msgdataindex] = -1;
+       }
+       msgtype = -1;
+       msglength = 30;
 #ifdef DEBUG
 #ifndef TILERA
-    BAMBOO_DEBUGPRINT(0xe88d);
+       BAMBOO_DEBUGPRINT(0xe88d);
 #endif
 #endif
 
-    if(BAMBOO_MSG_AVAIL() != 0) {
-      goto msg;
-    }
+       if(BAMBOO_MSG_AVAIL() != 0) {
+               goto msg;
+       }
 #ifdef PROFILE
-       /*if(isInterrupt) {
-           profileTaskEnd();
-    }*/
+/*if(isInterrupt) {
+               profileTaskEnd();
+       }*/
 #endif
-    return type;
-  } else {
-    // not a whole msg
+       return type;
+} else {
+       // not a whole msg
 #ifdef DEBUG
 #ifndef TILERA
-    BAMBOO_DEBUGPRINT(0xe88e);
+       BAMBOO_DEBUGPRINT(0xe88e);
 #endif
 #endif
 #ifdef PROFILE
-/*    if(isInterrupt) {
-          profileTaskEnd();
-      }*/
+/*  if(isInterrupt) {
+                 profileTaskEnd();
+               }*/
 #endif
     return -2;
   }