initial multicore gargbage collection, not finish yet
authorjzhou <jzhou>
Fri, 31 Jul 2009 00:37:36 +0000 (00:37 +0000)
committerjzhou <jzhou>
Fri, 31 Jul 2009 00:37:36 +0000 (00:37 +0000)
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Flat/BuildCodeMultiCore.java
Robust/src/IR/State.java
Robust/src/Main/Main.java
Robust/src/Runtime/RAW/task_arch.c
Robust/src/Runtime/multicoregarbage.c [new file with mode: 0644]
Robust/src/Runtime/multicoregarbage.h [new file with mode: 0644]
Robust/src/Runtime/multicoreruntime.h
Robust/src/Runtime/multicoretask.c

index b25311c619b3d319710a5015b1561d217609fb1e..ed217a47203ff2398f403faec146235d7eeacf4b 100644 (file)
@@ -592,10 +592,13 @@ public class BuildCode {
       if(!state.MULTICORE) {
        outclassdefs.println("  void * flagptr;");
       } else {
-       outclassdefs.println("  int version;");
-       outclassdefs.println("  struct ___Object___ * original;");
-       //outclassdefs.println("  int numlocks;");        // array for locks
-       outclassdefs.println("  int * lock;");
+        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.OPTIONAL) {
        outclassdefs.println("  int numfses;");
@@ -1300,10 +1303,13 @@ public class BuildCode {
       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
        classdefout.println("  void * flagptr;");
       } else if (state.MULTICORE) {
+        if(state.MULTICOREGC) {
+          classdefout.println("  int marked;");
+        }
        classdefout.println("  int version;");
-       classdefout.println("  struct ___Object___ * original;");
-       //classdefout.println("  int numlocks;");        // array for locks
-       classdefout.println("  int * lock;");
+    classdefout.println("  int * lock;");  // lock entry for this obj
+    classdefout.println("  void * mutex;");  
+    classdefout.println("  int lockcount;");
       }
       if (state.OPTIONAL) {
        classdefout.println("  int numfses;");
index 8e7061c6d9d8203b9be2c4a5c535f5f8e04d808d..4e2a8f7246d4dca7bb9d8d517b3623d4b6f1c1ef 100644 (file)
@@ -391,10 +391,10 @@ public class BuildCodeMultiCore extends BuildCode {
   /* This method outputs code for each task. */
 
   private void outputTaskCode(PrintWriter outtaskdefs, 
-                             PrintWriter outmethod, 
-                             PrintWriter outtask, 
-                             Iterator[] taskits, 
-                             int[] numtasks,
+                                 PrintWriter outmethod, 
+                                 PrintWriter outtask, 
+                                 Iterator[] taskits, 
+                                 int[] numtasks,
                               int[][] numqueues) {
     /* Compile task based program */
     outtaskdefs.println("#include \"task.h\"");
@@ -577,8 +577,8 @@ public class BuildCodeMultiCore extends BuildCode {
   }
 
   private void generateTaskMethod(FlatMethod fm, 
-                                 LocalityBinding lb, 
-                                 PrintWriter output) {
+                                     LocalityBinding lb, 
+                                     PrintWriter output) {
     /*if (State.PRINTFLAT)
         System.out.println(fm.printMethod());*/
     TaskDescriptor task=fm.getTask();
@@ -1042,17 +1042,6 @@ public class BuildCodeMultiCore extends BuildCode {
          isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
                    (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
        }
-       /* no longler use the isolate flag in object structure
-       if(!isolate) {
-         // indentify this object as a shared object
-         // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
-         // is shared, it maybe shared all the time afterwards
-         output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
-         output.println("  " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
-         output.println("  " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
-         output.println("}");
-       }
-       */
 
        Vector<Integer> sendto = new Vector<Integer>();
        Queue<Integer> queue = null;
@@ -1332,8 +1321,8 @@ public class BuildCodeMultiCore extends BuildCode {
   }
 
   protected void outputAliasLockCode(FlatMethod fm, 
-                                    LocalityBinding lb, 
-                                    PrintWriter output) {
+                                        LocalityBinding lb, 
+                                        PrintWriter output) {
     if(this.m_oa == null) {
       return;
     }
index 81a463d6af1a6a02eb875da67c777abb5f19aefa..b835f1021c94e8bffcb74fadda9b134074cf4520 100644 (file)
@@ -60,6 +60,7 @@ public class State {
   public boolean FLATIRGRAPHUSERMETHODS=false;
   public boolean FLATIRGRAPHLIBMETHODS=false;
   public boolean MULTICORE=false;
+       public boolean MULTICOREGC=false;
   public boolean OWNERSHIP=false;
   public int OWNERSHIPALLOCDEPTH=3;
   public boolean OWNERSHIPWRITEDOTS=false;
index 146428666dc02ab02e9821ce59d1035b260834fb..5680006008a45a3a3ca4f0d821274ca438a26628 100644 (file)
@@ -126,6 +126,8 @@ public class Main {
        state.FLATIRGRAPHLIBMETHODS=true;
       } else if (option.equals("-multicore"))
        state.MULTICORE=true;
+      else if (option.equals("-multicoregc"))
+        state.MULTICOREGC=true;
       else if (option.equals("-ownership"))
        state.OWNERSHIP=true;
       else if (option.equals("-ownallocdepth")) {
index 0b0e6b20d3ead0183429923749ca85c8862e6f62..d9746f702744f68440350bda4b46ac346b89baf1 100644 (file)
@@ -3,6 +3,14 @@
 #include "multicoreruntime.h"
 #include "runtime_arch.h"
 
+// data structures for locking
+struct RuntimeHash locktable;
+static struct RuntimeHash* locktbl = &locktable;
+struct LockValue {
+       int redirectlock;
+       int value;
+};
+
 __attribute__((always_inline)) inline void initialization() {
 } // initialization()
 
@@ -723,6 +731,660 @@ __attribute__((always_inline)) inline int receiveMsg() {
   return msgdataindex;
 }
 
+bool getreadlock(void * ptr) {
+  int targetcore = 0;
+  lockobj = (int)ptr;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       lock2require = lockobj;
+  } else {
+       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
+  lockflag = false;
+#ifndef INTERRUPT
+  reside = false;
+#endif
+  lockresult = 0;
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+    int deny = 0;
+       BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf001);
+#endif
+       deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf000);
+#endif
+    if(deny == -1) {
+               // redirected
+               return true;
+       } else {
+               if(lockobj == (int)ptr) {
+                       if(deny) {
+                               lockresult = 0;
+                       } else {
+                               lockresult = 1;
+                       }
+                       lockflag = true;
+#ifndef INTERRUPT
+                       reside = true;
+#endif
+               } else {
+                       // conflicts on lockresults
+                       BAMBOO_EXIT(0xa018);
+               }
+       }
+    return true;
+  } 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);
+  }
+  return true;
+}
+
+void releasewritelock_r(void * lock, void * redirectlock);
+bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
+
+bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
+
+void releasereadlock(void * ptr) {
+  int targetcore = 0;
+  int reallock = 0;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       reallock = (int)ptr;
+  } else {
+       reallock = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+       BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf001);
+#endif
+    // reside on this core
+    if(!RuntimeHashcontainskey(locktbl, reallock)) {
+      // no locks for this object, something is wrong
+      BAMBOO_EXIT(0xa019);
+    } else {
+      int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+      RuntimeHashget(locktbl, reallock, &rwlock_obj);
+         lockvalue = (struct LockValue *)rwlock_obj;
+      lockvalue->value--;
+    }
+       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf000);
+#endif
+    return;
+  } 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);
+  }
+}
+
+// redirected lock request
+bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
+  int targetcore = 0;
+  
+  if(core == BAMBOO_NUM_OF_CORE) {
+         lockobj = (int)ptr;
+         lock2require = (int)redirectlock;
+         lockflag = false;
+#ifndef INTERRUPT
+         reside = false;
+#endif
+         lockresult = 0;
+  }  
+  targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
+  
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+    int deny = processlockrequest(0, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
+       if(deny == -1) {
+               // redirected
+               return true;
+       } else {
+               if(core == BAMBOO_NUM_OF_CORE) {
+                       if(lockobj == (int)ptr) {
+                               if(deny) {
+                                       lockresult = 0;
+                               } else {
+                                       lockresult = 1;
+                                       RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
+                               }
+                               lockflag = true;
+#ifndef INTERRUPT
+                               reside = true;
+#endif
+                       } else {
+                               // conflicts on lockresults
+                               BAMBOO_EXIT(0xa01a);
+                       }
+                       return true;
+               } else {
+                       // 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);
+                       } else {
+                               cache_msg_4(false, core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
+                       }
+               }
+       }
+  } else {
+       // 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);
+       } else {
+               cache_msg_6(false, targetcore, 8, 0, (int)ptr, lock2require, core, BAMBOO_NUM_OF_CORE);
+       }
+  }
+  return true;
+}
+
+// not reentrant
+bool getwritelock(void * ptr) {
+  int targetcore = 0;
+
+  // for 32 bit machine, the size is always 5 words
+  //int msgsize = 5;
+
+  lockobj = (int)ptr;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       lock2require = lockobj;
+  } else {
+       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
+  lockflag = false;
+#ifndef INTERRUPT
+  reside = false;
+#endif
+  lockresult = 0;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe551);
+  BAMBOO_DEBUGPRINT_REG(lockobj);
+  BAMBOO_DEBUGPRINT_REG(lock2require);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+    int deny = 0;
+       BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf001);
+#endif
+       deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf000);
+#endif
+#ifdef DEBUG
+    BAMBOO_DEBUGPRINT(0xe555);
+    BAMBOO_DEBUGPRINT_REG(lockresult);
+#endif
+    if(deny == -1) {
+               // redirected
+               return true;
+       } else {
+               if(lockobj == (int)ptr) {
+                       if(deny) {
+                               lockresult = 0;
+                       } else {
+                               lockresult = 1;
+                       }
+                       lockflag = true;
+#ifndef INTERRUPT
+                       reside = true;
+#endif
+               } else {
+                       // conflicts on lockresults
+                       BAMBOO_EXIT(0xa01b);
+               }
+       }
+    return true;
+  } 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);
+  }
+  return true;
+}
+
+void releasewritelock(void * ptr) {
+  int targetcore = 0;
+  int reallock = 0;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       reallock = (int)ptr;
+  } else {
+       reallock = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe661);
+  BAMBOO_DEBUGPRINT_REG((int)ptr);
+  BAMBOO_DEBUGPRINT_REG(reallock);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+       BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf001);
+#endif
+    // reside on this core
+    if(!RuntimeHashcontainskey(locktbl, reallock)) {
+      // no locks for this object, something is wrong
+      BAMBOO_EXIT(0xa01c);
+    } else {
+      int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+      RuntimeHashget(locktbl, reallock, &rwlock_obj);
+         lockvalue = (struct LockValue *)rwlock_obj;
+      lockvalue->value++;
+    }
+       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf000);
+#endif
+    return;
+  } 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);
+  }
+}
+
+void releasewritelock_r(void * lock, void * redirectlock) {
+  int targetcore = 0;
+  int reallock = (int)lock;
+  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe671);
+  BAMBOO_DEBUGPRINT_REG((int)lock);
+  BAMBOO_DEBUGPRINT_REG(reallock);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+       BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf001);
+#endif
+    // reside on this core
+    if(!RuntimeHashcontainskey(locktbl, reallock)) {
+      // no locks for this object, something is wrong
+      BAMBOO_EXIT(0xa01d);
+    } else {
+      int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT(0xe672);
+#endif
+      RuntimeHashget(locktbl, reallock, &rwlock_obj);
+         lockvalue = (struct LockValue *)rwlock_obj;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+      lockvalue->value++;
+         lockvalue->redirectlock = (int)redirectlock;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+    }
+       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+       BAMBOO_DEBUGPRINT(0xf000);
+#endif
+    return;
+  } 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);
+  }
+}
+
+bool getwritelock_I(void * ptr) {
+  int targetcore = 0;
+  lockobj = (int)ptr;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       lock2require = lockobj;
+  } else {
+       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
+  lockflag = false;
+#ifndef INTERRUPT
+  reside = false;
+#endif
+  lockresult = 0;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe561);
+  BAMBOO_DEBUGPRINT_REG(lockobj);
+  BAMBOO_DEBUGPRINT_REG(lock2require);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+       int deny = processlockrequest(1, (int)lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+       if(deny == -1) {
+               // redirected
+               return true;
+       } else {
+               if(lockobj == (int)ptr) {
+                       if(deny) {
+                               lockresult = 0;
+#ifdef DEBUG
+                               BAMBOO_DEBUGPRINT(0);
+#endif
+                       } else {
+                               lockresult = 1;
+#ifdef DEBUG
+                               BAMBOO_DEBUGPRINT(1);
+#endif
+                       }
+                       lockflag = true;
+#ifndef INTERRUPT
+                       reside = true;
+#endif
+               } else {
+                       // conflicts on lockresults
+                       BAMBOO_EXIT(0xa01e);
+               }
+               return true;
+       }
+  } 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);
+  }
+  return true;
+}
+
+// redirected lock request
+bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
+  int targetcore = 0;
+
+  if(core == BAMBOO_NUM_OF_CORE) {
+         lockobj = (int)ptr;
+         lock2require = (int)redirectlock;
+         lockflag = false;
+#ifndef INTERRUPT
+         reside = false;
+#endif
+         lockresult = 0;
+  }
+  targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe571);
+  BAMBOO_DEBUGPRINT_REG((int)ptr);
+  BAMBOO_DEBUGPRINT_REG((int)redirectlock);
+  BAMBOO_DEBUGPRINT_REG(core);
+  BAMBOO_DEBUGPRINT_REG((int)cache);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+       int deny = processlockrequest(1, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
+       if(deny == -1) {
+               // redirected
+               return true;
+       } else {
+               if(core == BAMBOO_NUM_OF_CORE) {
+                       if(lockobj == (int)ptr) {
+                               if(deny) {
+                                       lockresult = 0;
+                               } else {
+                                       lockresult = 1;
+                                       RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
+                               }
+                               lockflag = true;
+#ifndef INTERRUPT
+                               reside = true;
+#endif
+                       } else {
+                               // conflicts on lockresults
+                               BAMBOO_EXIT(0xa01f);
+                       }
+                       return true;
+               } else {
+                       // 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);
+                       } else {
+                               cache_msg_4(false, core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
+                       }
+               }
+       }
+  } else {
+       // 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);
+       } else {
+               cache_msg_6(false, targetcore, 8, 1, (int)ptr, (int)redirectlock, core, BAMBOO_NUM_OF_CORE);
+       }
+  }
+  return true;
+}
+
+void releasewritelock_I(void * ptr) {
+  int targetcore = 0;
+  int reallock = 0;
+  if(((struct ___Object___ *)ptr)->lock == NULL) {
+       reallock = (int)ptr;
+  } else {
+       reallock = (int)(((struct ___Object___ *)ptr)->lock);
+  }
+  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe681);
+  BAMBOO_DEBUGPRINT_REG((int)ptr);
+  BAMBOO_DEBUGPRINT_REG(reallock);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+    if(!RuntimeHashcontainskey(locktbl, reallock)) {
+      // no locks for this object, something is wrong
+      BAMBOO_EXIT(0xa020);
+    } else {
+      int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+      RuntimeHashget(locktbl, reallock, &rwlock_obj);
+         lockvalue = (struct LockValue *)rwlock_obj;
+      lockvalue->value++;
+    }
+    return;
+  } 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);
+  }
+}
+
+void releasewritelock_I_r(void * lock, void * redirectlock) {
+  int targetcore = 0;
+  int reallock = (int)lock;
+  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#ifdef DEBUG
+  BAMBOO_DEBUGPRINT(0xe691);
+  BAMBOO_DEBUGPRINT_REG((int)lock);
+  BAMBOO_DEBUGPRINT_REG(reallock);
+  BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+  if(targetcore == BAMBOO_NUM_OF_CORE) {
+    // reside on this core
+    if(!RuntimeHashcontainskey(locktbl, reallock)) {
+      // no locks for this object, something is wrong
+      BAMBOO_EXIT(0xa021);
+    } else {
+      int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT(0xe692);
+#endif
+      RuntimeHashget(locktbl, reallock, &rwlock_obj);
+         lockvalue = (struct LockValue *)rwlock_obj;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+      lockvalue->value++;
+         lockvalue->redirectlock = (int)redirectlock;
+#ifdef DEBUG
+      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+    }
+    return;
+  } 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);
+  }
+}
+
+/* this function is to process lock requests. 
+ * can only be invoked in receiveObject() */
+// if return -1: the lock request is redirected
+//            0: the lock request is approved
+//            1: the lock request is denied
+__attribute__((always_inline)) int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
+  int deny = 0;
+  if( ((lock >> 5) % BAMBOO_TOTALCORE) != BAMBOO_NUM_OF_CORE ) {
+         // the lock should not be on this core
+#ifndef TILERA
+         BAMBOO_DEBUGPRINT_REG(requestcore);
+         BAMBOO_DEBUGPRINT_REG(lock);
+         BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
+#endif
+         BAMBOO_EXIT(0xa017);
+  }
+  if(!RuntimeHashcontainskey(locktbl, lock)) {
+         // no locks for this object
+         // first time to operate on this shared object
+         // create a lock for it
+         // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
+         struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
+         lockvalue->redirectlock = 0;
+#ifdef DEBUG
+#ifndef TILERA
+         BAMBOO_DEBUGPRINT(0xe110);
+#endif
+#endif
+         if(locktype == 0) {
+                 lockvalue->value = 1;
+         } else {
+                 lockvalue->value = -1;
+         }
+         RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
+  } else {
+         int rwlock_obj = 0;
+         struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+#ifndef TILERA
+         BAMBOO_DEBUGPRINT(0xe111);
+#endif
+#endif
+         RuntimeHashget(locktbl, lock, &rwlock_obj);
+         lockvalue = (struct LockValue *)(rwlock_obj);
+#ifdef DEBUG
+#ifndef TILERA
+         BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
+#endif
+#endif
+         if(lockvalue->redirectlock != 0) {
+                 // this lock is redirected
+#ifdef DEBUG
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT(0xe112);
+#endif
+#endif
+                 if(locktype == 0) {
+                         getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
+                 } else {
+                         getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
+                 }
+                 return -1;  // redirected
+         } else {
+#ifdef DEBUG
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+#endif
+                 if(0 == lockvalue->value) {
+                         if(locktype == 0) {
+                                 lockvalue->value = 1;
+                         } else {
+                                 lockvalue->value = -1;
+                         }
+                 } else if((lockvalue->value > 0) && (locktype == 0)) {
+                         // read lock request and there are only read locks
+                         lockvalue->value++;
+                 } else {
+                         deny = 1;
+                 }
+#ifdef DEBUG
+#ifndef TILERA
+                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+#endif
+         }
+  }
+  return deny;
+}
+
+__attribute__((always_inline)) void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) {
+       if(!RuntimeHashcontainskey(locktbl, lock)) {
+    // no locks for this object, something is wrong
+#ifdef DEBUG
+               BAMBOO_DEBUGPRINT_REG(lock);
+#endif
+               BAMBOO_EXIT(0xa00b);
+       } else {
+               int rwlock_obj = 0;
+               struct LockValue * lockvalue = NULL;
+               RuntimeHashget(locktbl, lock, &rwlock_obj);
+               lockvalue = (struct LockValue*)(rwlock_obj);
+#ifdef DEBUG
+               BAMBOO_DEBUGPRINT(0xe884);
+               BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+               if(locktype == 0) {
+                       lockvalue->value--;
+               } else {
+                       lockvalue->value++;
+               }
+#ifdef DEBUG
+               BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+               if(isredirect) {
+                       lockvalue->redirectlock = redirectlock;
+               }
+       }
+}
+
 #ifdef PROFILE
 __attribute__((always_inline)) inline void profileTaskStart(char * taskname) {
   if(!taskInfoOverflow) {
diff --git a/Robust/src/Runtime/multicoregarbage.c b/Robust/src/Runtime/multicoregarbage.c
new file mode 100644 (file)
index 0000000..50836ed
--- /dev/null
@@ -0,0 +1,938 @@
+#ifdef MULTICORE_GC
+#include "multicoregarbage.h"
+#include "multicoreruntime.h"
+#include "runtime_arch.h"
+#include "SimpleHash.h"
+#include "GenericHashtable.h"
+
+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];
+       int size = 0;
+       if(type < NUMCLASSES) {
+               // a normal object
+               size = classsize[type];
+       } else {        
+               // an array 
+               struct ArrayObject *ao=(struct ArrayObject *)ptr;
+               int elementsize=classsize[type];
+               int length=ao->___length___; 
+               size=sizeof(struct ArrayObject)+length*elementsize;
+       }
+       *ttype = type;
+       *tsize = size;
+       return(!isLocal(ptr + size));
+}
+
+int hostcore(void * ptr) {
+       // check the host core of ptr
+       int host = 0;
+       int x = 0;
+       int y = 0;
+       RESIDECORE(ptr, &x, &y);
+       host = (x == 0)?(x * bamboo_height + y) : (x * bamboo_height + y - 2);
+       return host;
+}
+
+bool isLocal(void * ptr) {
+       // check if a pointer is in shared heap on this core
+       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;
+                               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(next == NULL)
+       }
+}
+
+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;
+       }
+       return tostart;
+}
+
+void transferMarkResults() {
+       // TODO, need distiguish between send and cache
+       // invoked inside interruptiong handler
+}
+
+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;
+               for(i = 1; i < NUMCORES - 1; i++) {
+                       // send GC start messages to all cores
+                       send_msg_1(true, i, 0x11);
+               }
+               bool isfirst = true;
+               lObjList.head = NULL;
+               lObjList.tail = NULL;
+               mObjList.head = NULL;
+               mObjList.tail = NULL;
+
+               // mark phase
+               while(gcphase == 0) {
+                       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(true, 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)
+               // send msgs to all cores requiring large objs info
+               gcnumconfirm = NUMCORES - 1;
+               for(i = 1; i < NUMCORES; ++i) {
+                       send_msg_1(true, i, 0x1e);
+               }       
+               while(gcnumconfirm != 0) {} // wait for responses
+               // TODO compute load balance
+
+               // TODO cache all large objects
+               for(i = 1; i < NUMCORES; ++i) {
+                       //TODO send start compact messages to all cores
+
+               }
+
+               // compact phase
+               compact();
+               gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+               while(gcphase == 1) {
+                       // check the status of all cores
+                       allStall = true;
+                       for(i = 0; i < NUMCORES; ++i) {
+                               if(gccorestatus[i] != 0) {
+                                       allStall = false;
+                                       break;
+                               }
+                       }       
+                       if(allStall) {
+                               for(i = 0; i < NUMCORES; ++i) {
+                                       gccorestatus[i] = 1;
+                               }
+                               break;
+                       }
+               } // while(gcphase == 1)
+               // TODO merge all mapping information
+               gcphase = 2;
+               for(i = 1; i < NUMCORES; ++i) {
+                       // send start flush messages to all cores
+                       send_msg_1(true, i, 0x13);
+               }
+
+               // flush phase
+               flush();
+               gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+               while(gcphase == 2) {
+                       // check the status of all cores
+                       allStall = true;
+                       for(i = 0; i < NUMCORES; ++i) {
+                               if(gccorestatus[i] != 0) {
+                                       allStall = false;
+                                       break;
+                               }
+                       }       
+                       if(allStall) {
+                               break;
+                       }
+               } // while(gcphase == 2)
+               // TODO merge all mapping information
+               gcphase = 3;
+               for(i = 1; i < NUMCORES; ++i) {
+                       // send gc finish messages to all cores
+                       send_msg_1(true, i, 0x17);
+               }
+
+               // 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);
+       }
+}
+
+void mark(bool isfirst) {
+       if(isfirst) {
+               if(gcphase != 0) {
+                       BAMBOO_EXIT(0xb002);
+               }
+               gcbusystatus = 1;
+               // initialize gctomark queue
+               while(!isEmpty(gctomark)) {
+                       getItem(gctomark);
+               }
+               // enqueue current stack  TODO
+               
+               // enqueue objectsets
+               int 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) {
+                               struct parameterwrapper * parameter = queues[j];
+                               struct ObjectHash * set=parameter->objectset;
+                               struct ObjectNode * ptr=set->listhead;
+                               while(ptr!=NULL) {
+                                       void *orig=(void *)ptr->key;
+                                       addNewItem(gctomark, orig); 
+                                       ptr=ptr->lnext;
+                               }
+                       }
+               }
+               // euqueue current task descriptor
+               for(i=0; i<currtpd->numParameters; i++) {
+         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;
+           }
+       }
+
+       // mark phase
+       while(gcphase == 0) {
+               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 = 
+                                       (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem));  
+                               loi->orig = (INTPTR)ptr;
+                               loi->dst = (INTPTR)0;
+                               loi->length = size;
+                               if(lObjList.head == NULL) {
+                                       lObjList.head = lObjList.tail = loi;
+                               } 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;
+                       pointer=pointerarray[type];
+                       if (pointer==0) {
+                               /* Array of primitives */
+                               /* Do nothing */
+                       } else if (((INTPTR)pointer)==1) {
+                               /* Array of pointers */
+                               struct ArrayObject *ao=(struct ArrayObject *) ptr;
+                               int length=ao->___length___;
+                               int j;
+                               for(j=0; j<length; j++) {
+                                       void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+                                       int host = hostcore(objptr);
+                                       if(BAMBOO_NUM_OF_CORE == host) {
+                                               // on this core
+                                               addNewItem(gctomark, objptr);  
+                                       } else {
+                                               // send a msg to host informing that objptr is active
+                                               send_msg_2(true, host, 0x1a, objptr);
+                                               gcself_numsendobjs++;
+                                       }
+                               }
+                       } else {
+                               INTPTR size=pointer[0];
+                               int i;
+                               for(i=1; i<=size; i++) {
+                                       unsigned int offset=pointer[i];
+                                       void * objptr=*((void **)(((char *)ptr)+offset));
+                                       int host = hostcore(objptr);
+                                       if(BAMBOO_NUM_OF_CORE == host) {
+                                               // on this core
+                                               addNewItem(gctomark, objptr);  
+                                       } else {
+                                               // send a msg to host informing that objptr is active
+                                               send_msg_2(true, host, 0x1a, objptr);
+                                               gcself_numsendobjs++;
+                                       }
+                               }
+                       }
+               } // while(!isEmpty(gctomark))
+               gcbusystatus = false;
+               // send mark finish msg to core coordinator
+               send_msg_4(true, STARTUPCORE, 0x14, BAMBOO_NUM_OF_CORE, gcself_numsendobjs, gcself_numreceiveobjs); 
+
+               if(BAMBOO_NUM_OF_CORE == 0) {
+                       return;
+               }
+       } // while(gcphase == 0)
+} // mark()
+
+void compact() {
+       if(gcphase != 1) {
+               BAMBOO_EXIT(0xb003);
+       }
+       curr_heaptop = 0;
+       struct markedObjItem * moi = mObjList.head;
+       bool iscopy = true;
+       while(moi != NULL) {
+               if((cinstruction == NULL) || (cinstruction->tomoveobjs == NULL) 
+                               || (curr_heaptop < cinstruction->tomoveobjs->starts[0])) {
+                       // objs to compact
+                       int type = ((int *)(moi->orig))[0];
+                       int size = 0;
+                       if(type == -1) {
+                               // do nothing 
+                       }
+                       if(type < NUMCLASSES) {
+                               // a normal object
+                               size = classsize[type];
+                               moi->dst = curr_heaptop;
+                               curr_heaptop += size;
+                               if(iscopy) {
+                                       memcpy(moi->dst, moi->orig, size);
+                                       genputtable(pointertbl, moi->orig, moi->dst);
+                               }
+                       } else {
+                               // an array 
+                               struct ArrayObject *ao=(struct ArrayObject *)ptr;
+                               int elementsize=classsize[type];
+                               int length=ao->___length___;
+                               size=sizeof(struct ArrayObject)+length*elementsize;
+                               moi->dst = curr_heaptop;
+                               curr_heaptop += size;
+                               if(iscopy) {
+                                       memcpy(moi->dst, moi->orig, size);
+                                       genputtable(pointertbl, moi->orig, moi->dst);
+                               }
+                       }
+               } else {
+                       iscopy = false;;
+               }
+               moi = moi->next;
+       } // while(moi != NULL)
+       if(moi == NULL) {
+               if(cinstruction->incomingobjs != NULL) {
+                       for(int j = 0; j < cinstruction->incomingobjs->length; j++) {
+                               // send messages to corresponding cores to start moving
+                               send_msg_2(true, cinstruction->incomingobjs->dsts[j], 0x1b, BAMBOO_NUM_OF_CORE);
+                       }
+               }
+       } else {
+               int num_dsts = cinstruction->tomoveobjs->length;
+               while(num_dsts > 0) {
+                       while(!gctomove) {}
+                       // start moving objects to other cores
+                       gctomove = 0;
+                       while(!isEmpty(gcdsts)) {
+                               int dst = (int)(getItem(gcdsts));
+                               num_dsts--;
+                               int j = 0;
+                               for(j = 0; j < cinstruction->tomoveobjs->length; j++) {
+                                       if(dst == cinstruction->tomoveobjs->dsts[j]) {
+                                               break;
+                                       }
+                               }
+                               INTPTR top = cinstruction->tomoveobjs->dststarts[j];
+                               INTPTR start = cinstruction->tomoveobjs->starts[j];
+                               INTPTR end = cinstruction->tomoveobjs->ends[j];
+                               struct markedObjItem * tomove = getStartItem(moi, start);
+                               do {
+                                       int type = ((int *)(tomove->orig))[0];
+                                       int size = 0;
+                                       if(type == -1) {
+                                               // do nothing
+                                       }
+                                       if(type < NUMCLASSES) {
+                                               // a normal object
+                                               size = classsize[type];
+                                               moi->dst = top;
+                                               top += size;
+                                               memcpy(moi->dst, moi->orig, size);
+                                               genputtable(pointertbl, moi->orig, moi->dst);
+                                       } else {                                                
+                                               // an array 
+                                               struct ArrayObject *ao=(struct ArrayObject *)ptr;
+                                               int elementsize=classsize[type];
+                                               int length=ao->___length___;
+                                               size=sizeof(struct ArrayObject)+length*elementsize;
+                                               moi->dst = top;
+                                               top += size;
+                                               memcpy(moi->dst, moi->orig, size);
+                                               genputtable(pointertbl, moi->orig, moi->dst);
+                                       }
+                                       tomove = tomove->next;
+                               } while(tomove->orig < end);
+                       } // while(!isEmpty(gcdsts))
+               } // while(num_dsts > 0)
+       } // if(moi == NULL) else()
+       if((cinstruction != NULL) && (cinstruction->largeobjs != NULL)) {
+               // move all large objects
+               do {
+                       // dequeue the first large obj
+                       struct largeObjItem * loi = cinstruction->largeobjs;
+                       cinstruction->largeobjs = loi->next;
+                       // move this large obj
+                       memcpy(loi->dst, loi->orig, loi->length);
+                       genputtable(pointertbl, loi->orig, loi->dst);
+                       RUNFREE(loi);
+               }while(cinstruction->largeobjs != NULL);
+       }
+       // send compact finish message to core coordinator
+       send_msg_2(true, STARTUPCORE, 0x15, BAMBOO_NUM_OF_CORE);
+       
+} // compact()
+
+void flush() {
+       struct markedObjItem * moi = mObjList.head;
+       while(moi != NULL) {
+               void * ptr = moi->dst;
+               int type = ((int *)(ptr))[0];
+               // scan all pointers in ptr
+               unsigned INTPTR * pointer;
+               pointer=pointerarray[type];
+               if (pointer==0) {
+                       /* Array of primitives */
+                       /* Do nothing */
+               } else if (((INTPTR)pointer)==1) {
+                       /* Array of pointers */
+                       struct ArrayObject *ao=(struct ArrayObject *) ptr;
+                       int length=ao->___length___;
+                       int j;
+                       for(j=0; j<length; j++) {
+                               void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+                               // change to new address
+                               void *dstptr = gengettable(pointertbl, objptr);
+                               if(NULL == dstptr) {
+                                       // send msg to host core for the mapping info
+                                       obj2map = (int)objptr;
+                                       ismapped = false;
+                                       mappedobj = NULL;
+                                       send_msg_3(true, hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+                                       while(!ismapped) {}
+                                       dstptr = mappedobj;
+                               }
+                               ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dstptr;
+                       }
+               } else {
+                       INTPTR size=pointer[0];
+                       int i;
+                       for(i=1; i<=size; i++) {
+                               unsigned int offset=pointer[i];
+                               void * objptr=*((void **)(((char *)ptr)+offset));
+                               // change to new address
+                               void *dstptr = gengettable(pointertbl, objptr);
+                               if(NULL == dstptr) {
+                                       // send msg to host core for the mapping info
+                                       obj2map = (int)objptr;
+                                       ismapped = false;
+                                       mappedobj = NULL;
+                                       send_msg_3(true, hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+                                       while(!ismapped) {}
+                                       dstptr = mappedobj;
+                               }
+                               *((void **)(((char *)ptr)+offset)) = dstptr;
+                       }
+               }
+               moi = moi->next;
+       } // while(moi != NULL)
+       // send flush finish message to core coordinator
+       send_msg_2(true, STARTUPCORE, 0x16, BAMBOO_NUM_OF_CORE);
+       
+} // flush()
+
+void collect() {
+       // core collector routine
+       // 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();
+
+       lObjList.head = NULL;
+       lObjList.tail = NULL;
+       mObjList.head = NULL;
+       mObjList.tail = NULL;
+       mark(true);
+       compact();
+       while(gcphase != 2) {}
+       flush();
+       
+       while(true) {
+               if(gcphase == 3) {
+                       // 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;
+               }
+       }
+}
+
+/* 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(true, STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+                 } else {
+                         send_msg_5(true, 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(true, gcmsgdata[2], 0x1d, data1, dstptr);
+                       } else {
+                               send_msg_3(true, 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
diff --git a/Robust/src/Runtime/multicoregarbage.h b/Robust/src/Runtime/multicoregarbage.h
new file mode 100644 (file)
index 0000000..8a6283d
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef MULTICORE_GARBAGE_H
+#define MULTICORE_GARBAGE_H
+#include "Queue.h"
+
+// data structures for GC
+#define BAMBOO_NUM_PAGES 1024 * 512
+#define BAMBOO_PAGE_SIZE 4096
+#define BAMBOO_SHARED_MEM_SIZE BAMBOO_PAGE_SIZE * BAMBOO_PAGE_SIZE
+#define BAMBOO_BASE_VA 0xd000000
+#define BAMBOO_SMEM_SIZE 16 * BAMBOO_PAGE_SIZE
+#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;
+       struct markedObjItem * next;
+};
+
+struct largeObjItem {
+       INTPTR orig;
+       INTPTR dst;
+       int length;
+       struct largeObjItem * next;
+};
+
+struct moveObj {
+       INTPTR * starts;
+       INTPTR * ends;
+       INTPTR * dststarts;
+       int * dsts;
+       int length;
+};
+
+struct compactInstr {
+       struct moveObj * tomoveobjs;
+       struct moveObj * incomingobjs;
+       struct largeObjItem * largeobjs;
+};
+
+int 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
+// for mark phase termination
+int gccorestatus[NUMCORES]; // records status of each core
+                           // 1: running gc
+                           // 0: stall
+int gcnumsendobjs[NUMCORES]; // records how many objects a core has sent out
+int gcnumreceiveobjs[NUMCORES]; // records how many objects a core has received
+int gcnumconfirm;
+bool gcwaitconfirm;
+bool gcbusystatus;
+int gcself_numsendobjs;
+int gcself_numreceiveobjs;
+// compact instruction
+struct compactInstr * cinstruction;
+// mapping of old address to new address
+struct genhashtable * pointertbl;
+int obj2map;
+int mappedobj;
+bool ismapped;
+
+#define BLOCKNUM(p, b) \
+       if((p) < BAMBOO_LARGE_SMEM_BOUND) { \
+               (*((int*)b)) = (p) / BAMBOO_SMEM_SIZE_L; \
+       } else { \
+               (*((int*)b)) = NUMCORES + ((p) - BAMBOO_LARGE_SMEM_BOUND) / BAMBOO_SMEM_SIZE; \
+       }
+
+#define RESIDECORE(p, x, y) \
+       int b; \
+       BLOCKNUM((p), &b); \
+       bool reverse = (b / NUMCORES) % 2; \
+       int l = b % NUMCORES; \
+       if(reverse) { \
+               if(l < 16) { \
+                       l += 1; \
+               } else { \
+                       l += 2; \
+               } \
+               (*((int*)y)) = 7 - l / 8; \
+       } else { \
+               if(l > 54) { \
+                       l += 2; \
+               } else if(l > 47) {\
+                       l += 1; \
+               } \
+               (*((int*)y)) = l / 8; \
+       } \
+       if((l/8)%2) { \
+               (*((int*)x)) = 1 - l % 8; \
+       } else { \
+               (*((int*)x)) = l % 8; \
+       }
+
+void gc(); // core coordinator routine
+void collect(); // core collector routine
+int gc_msghandler(); // interruption handler for GC msgs
+
+#endif
+
index 80108f3ca84ce8c7be85e4dc309a819b27407484..fe9f4ed24558debbced721f46ef521e499b0667b 100644 (file)
@@ -31,12 +31,6 @@ int self_numsendobjs;
 int self_numreceiveobjs;
 
 // data structures for locking
-struct RuntimeHash locktable;
-static struct RuntimeHash* locktbl = &locktable;
-struct LockValue {
-       int redirectlock;
-       int value;
-};
 struct RuntimeHash * objRedirectLockTbl;
 int lockobj;
 int lock2require;
@@ -47,6 +41,9 @@ bool lockflag;
 struct Queue objqueue;
 
 // data structures for shared memory allocation
+#ifdef MULTICORE_GC
+#include "multicoregarbage.h"
+#else
 #define BAMBOO_NUM_PAGES 1024 * 512
 #define BAMBOO_PAGE_SIZE 4096
 #define BAMBOO_SHARED_MEM_SIZE BAMBOO_PAGE_SIZE * BAMBOO_PAGE_SIZE
@@ -57,6 +54,7 @@ bool smemflag;
 mspace bamboo_free_msp;
 mspace bamboo_cur_msp;
 int bamboo_smem_size;
+#endif
 
 // for test TODO
 int total_num_t6;
@@ -111,6 +109,22 @@ inline void initCommunication(void) __attribute__((always_inline));
 inline void fakeExecution(void) __attribute__((always_inline));
 inline void terminate(void) __attribute__((always_inline));
 
+// lock related functions
+bool getreadlock(void* ptr);
+void releasereadlock(void* ptr);
+bool getwritelock(void* ptr);
+void releasewritelock(void* ptr);
+bool getwritelock_I(void* ptr);
+void releasewritelock_I(void * ptr);
+/* this function is to process lock requests. 
+ * can only be invoked in receiveObject() */
+// if return -1: the lock request is redirected
+//            0: the lock request is approved
+//            1: the lock request is denied
+inline int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) __attribute_((always_inline));
+inline void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) __attribute_((always_inline));
+
+// msg related functions
 inline void send_msg_1(int targetcore, unsigned long n0) __attribute__((always_inline));
 inline void send_msg_2(int targetcore, unsigned long n0, unsigned long n1) __attribute__((always_inline));
 inline void send_msg_3(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2) __attribute__((always_inline));
@@ -120,9 +134,11 @@ inline void send_msg_6(int targetcore, unsigned long n0, unsigned long n1, unsig
 inline void cache_msg_2(int targetcore, unsigned long n0, unsigned long n1) __attribute__((always_inline));
 inline void cache_msg_3(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2) __attribute__((always_inline));
 inline void cache_msg_4(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2, unsigned long n3) __attribute__((always_inline));
+inline void cache_msg_5(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) __attribute__((always_inline));
 inline void cache_msg_6(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) __attribute__((always_inline));
 inline void transferObject(struct transObjInfo * transObj);
 inline int receiveMsg(void) __attribute__((always_inline));
+inline int receiveGCMsg(void) __attribute__((always_inline));
 
 #ifdef PROFILE
 inline void profileTaskStart(char * taskname) __attribute__((always_inline));
@@ -168,6 +184,7 @@ void outputProfileData();
 //  BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary         //
 //  BAMBOO_EXIT(x): exit routine                                                   //
 //  BAMBOO_MSG_AVAIL(): checking if there are msgs coming in                       //
+//  BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs coming in                   //
 //  BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number              //
 /////////////////////////////////////////////////////////////////////////////////////
 
index f5ed2cc94214227b285e46620694b3888ca9d7fc..fc5da71de4994b0581cce207dd5ae46111372234 100644 (file)
@@ -3,6 +3,7 @@
 #include "multicoreruntime.h"
 #include "runtime_arch.h"
 #include "GenericHashtable.h"
+#if 0
 /*
    extern int injectfailures;
    extern float failurechance;
@@ -13,7 +14,6 @@ extern int instaccum;
 void * curr_heapbase=0;
 void * curr_heaptop=0;
 
-#if 0
 #ifdef CONSCHECK
 #include "instrument.h"
 #endif
@@ -21,26 +21,16 @@ void * curr_heaptop=0;
 
 //  data structures for task invocation
 struct genhashtable * activetasks;
-struct genhashtable * failedtasks;
+//struct genhashtable * failedtasks;  // for recovery
 struct taskparamdescriptor * currtpd;
 #if 0
 struct RuntimeHash * forward;
 struct RuntimeHash * reverse;
 #endif // if 0: for recovery
 
-bool getreadlock(void* ptr);
-void releasereadlock(void* ptr);
-bool getwritelock(void* ptr);
-void releasewritelock(void* ptr);
-void releasewritelock_r(void * lock, void * redirectlock);
-
 // specific functions used inside critical sections
 void enqueueObject_I(void * ptr, struct parameterwrapper ** queues, int length);
 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags);
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
-bool getwritelock_I(void* ptr);
-bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
-void releasewritelock_I(void * ptr);
 
 // main function for each core
 inline void run(void * arg) {
@@ -63,7 +53,7 @@ inline void run(void * arg) {
 #endif
 
   // initialize the arrays
-  if(STARTUPCORE == corenum) {
+  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
     // startup core to initialize corestatus[]
     for(i = 0; i < NUMCORES; ++i) {
       corestatus[i] = 1;
@@ -151,9 +141,9 @@ inline void run(void * arg) {
   initializeexithandler();
 
   // main process of the execution module
-  if(corenum > NUMCORES - 1) {
+  if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
        // non-executing cores, only processing communications
-    failedtasks = NULL;
+    //failedtasks = NULL;
     activetasks = NULL;
 /*#ifdef PROFILE
         BAMBOO_DEBUGPRINT(0xee01);
@@ -172,7 +162,6 @@ inline void run(void * arg) {
          failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
                                        (int (*)(void *,void *)) &comparetpd);
 #endif // #if 0: for recovery
-         failedtasks = NULL;
          /* Create queue of active tasks */
          activetasks=genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
                                        (int(*) (void *,void *)) &comparetpd);
@@ -180,7 +169,7 @@ inline void run(void * arg) {
          /* Process task information */
          processtasks();
          
-         if(STARTUPCORE == corenum) {
+         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
                  /* Create startup object */
                  createstartupobject(argc, argv);
          }
@@ -263,12 +252,12 @@ inline void run(void * arg) {
                                  for(k = 0; k < objInfo->length; ++k) {
                                          int taskindex = objInfo->queues[2 * k];
                                          int paramindex = objInfo->queues[2 * k + 1];
-                                         struct parameterwrapper ** queues = &(paramqueues[corenum][taskindex][paramindex]);
+                                         struct parameterwrapper ** queues = &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
 #ifdef DEBUG
                                          BAMBOO_DEBUGPRINT_REG(taskindex);
                                          BAMBOO_DEBUGPRINT_REG(paramindex);
                                          struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
-                                         tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n", corenum, corenum, (int)obj, (long)obj, tmpptr->flag);
+                                         tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n", BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj, (long)obj, tmpptr->flag);
 #endif
                                          enqueueObject_I(obj, queues, 1);
 #ifdef DEBUG                            
@@ -327,7 +316,7 @@ objqueuebreak:
 
                  if(!tocontinue) {
                          // check if stop
-                         if(STARTUPCORE == corenum) {
+                         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
                                  if(isfirst) {
 #ifdef DEBUG
                                          BAMBOO_DEBUGPRINT(0xee03);
@@ -344,9 +333,9 @@ objqueuebreak:
 #ifdef DEBUG
                                          BAMBOO_DEBUGPRINT(0xf001);
 #endif
-                                         corestatus[corenum] = 0;
-                                         numsendobjs[corenum] = self_numsendobjs;
-                                         numreceiveobjs[corenum] = self_numreceiveobjs;
+                                         corestatus[BAMBOO_NUM_OF_CORE] = 0;
+                                         numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+                                         numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
                                          // check the status of all cores
                                          allStall = true;
 #ifdef DEBUG
@@ -385,11 +374,11 @@ objqueuebreak:
 #ifdef DEBUG
                                                                  BAMBOO_DEBUGPRINT(0xee05);
 #endif
-                                                                 corestatus[corenum] = 1;
+                                                                 corestatus[BAMBOO_NUM_OF_CORE] = 1;
                                                                  for(i = 1; i < NUMCORES; ++i) {       
                                                                          corestatus[i] = 1;
                                                                          // send status confirm msg to core i
-                                                                         send_msg_1(i, 0xc);
+                                                                         send_msg_1(false, i, 0xc);
                                                                  }
                                                                  waitconfirm = true;
                                                                  numconfirm = NUMCORES - 1;
@@ -417,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(false, i, 6, totalexetime);
                                                                  }
                                                                  // pour profiling data on startup core
                                                                  outputProfileData();
@@ -426,7 +415,7 @@ objqueuebreak:
 #ifdef DEBUG
                                                                          BAMBOO_DEBUGPRINT(0xf001);
 #endif
-                                                                         profilestatus[corenum] = 0;
+                                                                         profilestatus[BAMBOO_NUM_OF_CORE] = 0;
                                                                          // check the status of all cores
                                                                          allStall = true;
 #ifdef DEBUG
@@ -501,7 +490,7 @@ objqueuebreak:
                                                          BAMBOO_DEBUGPRINT(0xee0b);
 #endif
                                                          // send stall msg
-                                                         send_msg_4(STARTUPCORE, 1, corenum, self_numsendobjs, self_numreceiveobjs);
+                                                         send_msg_4(false, STARTUPCORE, 1, BAMBOO_NUM_OF_CORE, self_numsendobjs, self_numreceiveobjs);
                                                          sendStall = true;
                                                          isfirst = true;
                                                          busystatus = false;
@@ -516,10 +505,10 @@ objqueuebreak:
                                          BAMBOO_DEBUGPRINT(0xee0c);
 #endif
                                  } // if-else of line 464: if(!sendStall)
-                         } // if-else of line 313: if(STARTUPCORE == corenum
+                         } // if-else of line 313: if(STARTUPCORE == BAMBOO_NUM_OF_CORE
                  } // if-else of line 311: if(!tocontinue)
          } // line 193:  while(true) 
-  } // right-bracket for if-else of line 153: if(corenum > NUMCORES - 1)
+  } // right-bracket for if-else of line 153: if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
 
 } // run()
 
@@ -849,7 +838,7 @@ void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqu
   int UNUSED, UNUSED2;
   int * enterflags = NULL;
   if((!isnew) && (queues == NULL)) {
-    if(corenum < NUMCORES) {
+    if(BAMBOO_NUM_OF_CORE < NUMCORES) {
                queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
                length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
        } else {
@@ -880,7 +869,7 @@ void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength)
                struct ___Object___ *tagptr=NULL;
                struct parameterwrapper ** queues = vqueues;
                int length = vlength;
-               if(corenum > NUMCORES - 1) {
+               if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
                        return;
                }
                if(queues == NULL) {
@@ -950,7 +939,7 @@ void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlengt
                struct ___Object___ *tagptr=NULL;
                struct parameterwrapper ** queues = vqueues;
                int length = vlength;
-               if(corenum > NUMCORES - 1) {
+               if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
                        return;
                }
                if(queues == NULL) {
@@ -1113,6 +1102,21 @@ inline void addNewObjInfo(void * nobj) {
  *       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))
@@ -1130,15 +1134,24 @@ inline void addNewObjInfo(void * nobj) {
  * 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
  */
 
-/* this function is to process lock requests. 
- * can only be invoked in receiveObject() */
-// if return -1: the lock request is redirected
-//            0: the lock request is approved
-//            1: the lock request is denied
-int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache);
-
 // receive object transferred from other cores
 // or the terminate message from other cores
 // Should be invoked in critical sections!!
@@ -1155,7 +1168,6 @@ int processlockrequest(int locktype, int lock, int obj, int requestcore, int roo
 //                            otherwise -- received msg type
 int receiveObject() {
   int deny = 0;
-  //int targetcore = 0;
   
 msg:
   if(receiveMsg() == -1) {
@@ -1177,15 +1189,12 @@ msg:
          BAMBOO_DEBUGPRINT(0xe880);
 #endif
 #endif
-      if(corenum > NUMCORES - 1) {
+      if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa005);
-      } /*else if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+      } 
       // store the object and its corresponding queue info, enqueue it later
       transObj->objptr = (void *)msgdata[2];                                           // data1 is now size of the msg
       transObj->length = (msglength - 3) / 2;
@@ -1231,17 +1240,14 @@ msg:
 
     case 1: {
       // receive a stall msg
-      if(corenum != STARTUPCORE) {
+      if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // non startup core can not receive stall msg
                  // return -1
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(data1);
 #endif
                  BAMBOO_EXIT(0xa006);
-      } /*else if(waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+      } 
       if(data1 < NUMCORES) {
 #ifdef DEBUG
 #ifndef TILERA
@@ -1257,7 +1263,7 @@ msg:
 
     case 2: {
       // receive lock request msg, handle it right now
-      // check to see if there is a lock exist in locktbl 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]; // lock
@@ -1271,9 +1277,9 @@ 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);
+                         cache_msg_4(false, data4, tmp, data1, data2, data3);
                  } else {
-                         send_msg_4(data4, tmp, data1, data2, data3);
+                         send_msg_4(false, data4, tmp, data1, data2, data3);
                  }
          }
       break;
@@ -1281,15 +1287,12 @@ msg:
 
     case 3: {
       // receive lock grount msg
-      if(corenum > NUMCORES - 1) {
+      if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa007);
-      } /*else if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+      } 
       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
 #ifdef DEBUG
 #ifndef TILERA
@@ -1312,16 +1315,13 @@ msg:
     }
 
     case 4: {
-      // receive lock grount/deny msg
-      if(corenum > NUMCORES - 1) {
+      // receive lock deny msg
+      if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa009);
-      } /*else if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+      } 
       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
 #ifdef DEBUG
 #ifndef TILERA
@@ -1345,45 +1345,14 @@ msg:
 
     case 5: {
       // receive lock release msg
-         /*if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
-      if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
-                 // no locks for this object, something is wrong
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[3]);
-#endif
-                 BAMBOO_EXIT(0xa00b);
-      } else {
-                 int rwlock_obj = 0;
-                 struct LockValue * lockvalue = NULL;
-                 RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
-                 lockvalue = (struct LockValue*)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe884);
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-                 if(data1 == 0) {
-                         lockvalue->value--;
-                 } else {
-                         lockvalue->value++;
-                 }
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-      }
+                       processlockrelease(data1, msgdata[2], 0, false);
       break;
     }
 
 #ifdef PROFILE
     case 6: {
       // receive an output profile data request msg
-      if(corenum == STARTUPCORE) {
+      if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
                  // startup core can not receive profile output finish msg
                  BAMBOO_EXIT(0xa00c);
       }
@@ -1396,16 +1365,16 @@ msg:
          totalexetime = data1;
          outputProfileData();
          if(isMsgSending) {
-                 cache_msg_2(STARTUPCORE, 7, corenum);
+                 cache_msg_2(false, STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
          } else {
-                 send_msg_2(STARTUPCORE, 7, corenum);
+                 send_msg_2(false, STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
          }
       break;
     }
 
     case 7: {
       // receive a profile output finish msg
-      if(corenum != STARTUPCORE) {
+      if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // non startup core can not receive profile output finish msg
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(data1);
@@ -1424,7 +1393,7 @@ msg:
 
        case 8: {
          // receive a redirect lock request msg, handle it right now
-      // check to see if there is a lock exist in locktbl 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
@@ -1438,9 +1407,9 @@ 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(false, data4, deny==1?0xa:9, data1, data2, data3);
                  } else {
-                         send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
+                         send_msg_4(false, data4, deny==1?0xa:9, data1, data2, data3);
                  }
          }
          break;
@@ -1448,15 +1417,12 @@ msg:
 
        case 9: {
                // receive a lock grant msg with redirect info
-               if(corenum > NUMCORES - 1) {
+               if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
                        BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                        BAMBOO_EXIT(0xa00e);
-               }/* else if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+               }
       if(lockobj == msgdata[2]) {
 #ifdef DEBUG
 #ifndef TILERA
@@ -1481,15 +1447,12 @@ msg:
        
        case 0xa: {
          // receive a lock deny msg with redirect info
-         if(corenum > NUMCORES - 1) {
+         if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
 #endif
                  BAMBOO_EXIT(0xa010);
-         }/* else if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
+         }
       if(lockobj == msgdata[2]) {
 #ifdef DEBUG
 #ifndef TILERA
@@ -1498,7 +1461,6 @@ msg:
 #endif
                  lockresult = 0;
                  lockflag = true;
-                 //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
 #ifndef INTERRUPT
                  reside = false;
 #endif
@@ -1514,45 +1476,13 @@ msg:
 
        case 0xb: {
          // receive a lock release msg with redirect info
-         /*if((corenum == STARTUPCORE) && waitconfirm) {
-                 waitconfirm = false;
-                 numconfirm = 0;
-         }*/
-         if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
-                 // no locks for this object, something is wrong
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
-#endif
-                 BAMBOO_EXIT(0xa012);
-      } else {
-                 int rwlock_obj = 0;
-                 struct LockValue * lockvalue = NULL;
-                 RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
-                 lockvalue = (struct LockValue*)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe893);
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-                 if(data1 == 0) {
-                         lockvalue->value--;
-                 } else {
-                         lockvalue->value++;
-                 }
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-                 lockvalue->redirectlock = msgdata[3];
-         }
-         break;
+               processlockrelease(data1, msgdata[2], msgdata[3], true);
+               break;
        }
        
        case 0xc: {
       // receive a status confirm info
-         if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
+         if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
                  // wrong core to receive such msg
                  BAMBOO_EXIT(0xa013);
       } else {
@@ -1563,9 +1493,9 @@ msg:
 #endif
 #endif
                  if(isMsgSending) {
-                         cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
+                         cache_msg_3(false, STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
                  } else {
-                         send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
+                         send_msg_3(false, STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
                  }
       }
          break;
@@ -1573,7 +1503,7 @@ msg:
 
        case 0xd: {
          // receive a status confirm info
-         if(corenum != STARTUPCORE) {
+         if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // wrong core to receive such msg
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
@@ -1606,7 +1536,7 @@ msg:
 
        case 0xf: {
          // receive a shared memory request msg
-         if(corenum != STARTUPCORE) {
+         if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
                  // wrong core to receive such msg
 #ifndef TILERA
                  BAMBOO_DEBUGPRINT_REG(msgdata[2]);
@@ -1618,6 +1548,7 @@ msg:
                  BAMBOO_DEBUGPRINT(0xe88a);
 #endif
 #endif
+                 // TODO change for GC
                  void * mem = mspace_calloc(bamboo_free_msp, 1, msgdata[1]);
                  if(mem == NULL) {
                          BAMBOO_DEBUGPRINT(0xa016);
@@ -1625,9 +1556,9 @@ msg:
                  }
                  // send the start_va to request core
                 if(isMsgSending) {
-                         cache_msg_3(msgdata[2], 0x10, mem, msgdata[1]);
+                         cache_msg_3(false, msgdata[2], 0x10, mem, msgdata[1]);
                  } else {
-                         send_msg_3(msgdata[2], 0x10, mem, msgdata[1]);
+                         send_msg_3(false, msgdata[2], 0x10, mem, msgdata[1]);
                  } 
       }
          break;
@@ -1650,6 +1581,17 @@ msg:
          smemflag = true;
          break;
     }
+
+       case 0x11: {
+      // receive a start GC msg
+#ifdef DEBUG
+#ifndef TILERA
+         BAMBOO_DEBUGPRINT(0xe88c);
+#endif
+#endif
+         collect();
+         break;
+    }
        
     default:
       break;
@@ -1661,7 +1603,7 @@ msg:
     msglength = 30;
 #ifdef DEBUG
 #ifndef TILERA
-    BAMBOO_DEBUGPRINT(0xe88c);
+    BAMBOO_DEBUGPRINT(0xe88d);
 #endif
 #endif
 
@@ -1678,7 +1620,7 @@ msg:
     // not a whole msg
 #ifdef DEBUG
 #ifndef TILERA
-    BAMBOO_DEBUGPRINT(0xe88d);
+    BAMBOO_DEBUGPRINT(0xe88e);
 #endif
 #endif
 #ifdef PROFILE
@@ -1690,630 +1632,8 @@ msg:
   }
 }
 
-/* this function is to process lock requests. 
- * can only be invoked in receiveObject() */
-// if return -1: the lock request is redirected
-//            0: the lock request is approved
-//            1: the lock request is denied
-int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
-  int deny = 0;
-  if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
-         // the lock should not be on this core
-#ifndef TILERA
-         BAMBOO_DEBUGPRINT_REG(requestcore);
-         BAMBOO_DEBUGPRINT_REG(lock);
-         BAMBOO_DEBUGPRINT_REG(corenum);
-#endif
-         BAMBOO_EXIT(0xa017);
-  }
-  /*if((corenum == STARTUPCORE) && waitconfirm) {
-         waitconfirm = false;
-         numconfirm = 0;
-  }*/
-  if(!RuntimeHashcontainskey(locktbl, lock)) {
-         // no locks for this object
-         // first time to operate on this shared object
-         // create a lock for it
-         // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
-         struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
-         lockvalue->redirectlock = 0;
-#ifdef DEBUG
-#ifndef TILERA
-         BAMBOO_DEBUGPRINT(0xe110);
-#endif
-#endif
-         if(locktype == 0) {
-                 lockvalue->value = 1;
-         } else {
-                 lockvalue->value = -1;
-         }
-         RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
-  } else {
-         int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
-#ifndef TILERA
-         BAMBOO_DEBUGPRINT(0xe111);
-#endif
-#endif
-         RuntimeHashget(locktbl, lock, &rwlock_obj);
-         lockvalue = (struct LockValue *)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
-         BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
-#endif
-#endif
-         if(lockvalue->redirectlock != 0) {
-                 // this lock is redirected
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT(0xe112);
-#endif
-#endif
-                 if(locktype == 0) {
-                         getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
-                 } else {
-                         getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
-                 }
-                 return -1;  // redirected
-         } else {
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-                 if(0 == lockvalue->value) {
-                         if(locktype == 0) {
-                                 lockvalue->value = 1;
-                         } else {
-                                 lockvalue->value = -1;
-                         }
-                 } else if((lockvalue->value > 0) && (locktype == 0)) {
-                         // read lock request and there are only read locks
-                         lockvalue->value++;
-                 } else {
-                         deny = 1;
-                 }
-#ifdef DEBUG
-#ifndef TILERA
-                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
-         }
-  }
-  return deny;
-}
-
-bool getreadlock(void * ptr) {
-  int targetcore = 0;
-  lockobj = (int)ptr;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       lock2require = lockobj;
-  } else {
-       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
-  lockflag = false;
-#ifndef INTERRUPT
-  reside = false;
-#endif
-  lockresult = 0;
-
-  if(targetcore == corenum) {
-    // reside on this core
-    int deny = 0;
-       BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf001);
-#endif
-       deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
-       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf000);
-#endif
-    if(deny == -1) {
-               // redirected
-               return true;
-       } else {
-               if(lockobj == (int)ptr) {
-                       if(deny) {
-                               lockresult = 0;
-                       } else {
-                               lockresult = 1;
-                       }
-                       lockflag = true;
-#ifndef INTERRUPT
-                       reside = true;
-#endif
-               } else {
-                       // conflicts on lockresults
-                       BAMBOO_EXIT(0xa018);
-               }
-       }
-    return true;
-  } else {
-         // send lock request msg
-         // for 32 bit machine, the size is always 5 words
-         send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
-  }
-  return true;
-}
-
-void releasereadlock(void * ptr) {
-  int targetcore = 0;
-  int reallock = 0;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       reallock = (int)ptr;
-  } else {
-       reallock = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-  if(targetcore == corenum) {
-       BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf001);
-#endif
-    // reside on this core
-    if(!RuntimeHashcontainskey(locktbl, reallock)) {
-      // no locks for this object, something is wrong
-      BAMBOO_EXIT(0xa019);
-    } else {
-      int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-      RuntimeHashget(locktbl, reallock, &rwlock_obj);
-         lockvalue = (struct LockValue *)rwlock_obj;
-      lockvalue->value--;
-    }
-       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf000);
-#endif
-    return;
-  } else {
-       // send lock release msg
-       // for 32 bit machine, the size is always 4 words
-       send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
-  }
-}
-
-// redirected lock request
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
-  int targetcore = 0;
-  
-  if(core == corenum) {
-         lockobj = (int)ptr;
-         lock2require = (int)redirectlock;
-         lockflag = false;
-#ifndef INTERRUPT
-         reside = false;
-#endif
-         lockresult = 0;
-  }  
-  targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
-  
-  if(targetcore == corenum) {
-    // reside on this core
-    int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
-       if(deny == -1) {
-               // redirected
-               return true;
-       } else {
-               if(core == corenum) {
-                       if(lockobj == (int)ptr) {
-                               if(deny) {
-                                       lockresult = 0;
-                               } else {
-                                       lockresult = 1;
-                                       RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
-                               }
-                               lockflag = true;
-#ifndef INTERRUPT
-                               reside = true;
-#endif
-                       } else {
-                               // conflicts on lockresults
-                               BAMBOO_EXIT(0xa01a);
-                       }
-                       return true;
-               } else {
-                       // 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(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
-                       } else {
-                               cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
-                       }
-               }
-       }
-  } else {
-       // redirect the lock request
-       // for 32 bit machine, the size is always 6 words
-       if((!cache) || (cache && !isMsgSending)) {
-               send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
-       } else {
-               cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
-       }
-  }
-  return true;
-}
-
-// not reentrant
-bool getwritelock(void * ptr) {
-  int targetcore = 0;
-
-  // for 32 bit machine, the size is always 5 words
-  //int msgsize = 5;
-
-  lockobj = (int)ptr;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       lock2require = lockobj;
-  } else {
-       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
-  lockflag = false;
-#ifndef INTERRUPT
-  reside = false;
-#endif
-  lockresult = 0;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe551);
-  BAMBOO_DEBUGPRINT_REG(lockobj);
-  BAMBOO_DEBUGPRINT_REG(lock2require);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-    // reside on this core
-    int deny = 0;
-       BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf001);
-#endif
-       deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
-       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf000);
-#endif
-#ifdef DEBUG
-    BAMBOO_DEBUGPRINT(0xe555);
-    BAMBOO_DEBUGPRINT_REG(lockresult);
-#endif
-    if(deny == -1) {
-               // redirected
-               return true;
-       } else {
-               if(lockobj == (int)ptr) {
-                       if(deny) {
-                               lockresult = 0;
-                       } else {
-                               lockresult = 1;
-                       }
-                       lockflag = true;
-#ifndef INTERRUPT
-                       reside = true;
-#endif
-               } else {
-                       // conflicts on lockresults
-                       BAMBOO_EXIT(0xa01b);
-               }
-       }
-    return true;
-  } else {
-         // send lock request msg
-         // for 32 bit machine, the size is always 5 words
-         send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
-  }
-  return true;
-}
-
-void releasewritelock(void * ptr) {
-  int targetcore = 0;
-  int reallock = 0;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       reallock = (int)ptr;
-  } else {
-       reallock = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe661);
-  BAMBOO_DEBUGPRINT_REG((int)ptr);
-  BAMBOO_DEBUGPRINT_REG(reallock);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-       BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf001);
-#endif
-    // reside on this core
-    if(!RuntimeHashcontainskey(locktbl, reallock)) {
-      // no locks for this object, something is wrong
-      BAMBOO_EXIT(0xa01c);
-    } else {
-      int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-      RuntimeHashget(locktbl, reallock, &rwlock_obj);
-         lockvalue = (struct LockValue *)rwlock_obj;
-      lockvalue->value++;
-    }
-       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf000);
-#endif
-    return;
-  } else {
-       // send lock release msg
-       // for 32 bit machine, the size is always 4 words
-       send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
-  }
-}
-
-void releasewritelock_r(void * lock, void * redirectlock) {
-  int targetcore = 0;
-  int reallock = (int)lock;
-  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe671);
-  BAMBOO_DEBUGPRINT_REG((int)lock);
-  BAMBOO_DEBUGPRINT_REG(reallock);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-       BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf001);
-#endif
-    // reside on this core
-    if(!RuntimeHashcontainskey(locktbl, reallock)) {
-      // no locks for this object, something is wrong
-      BAMBOO_EXIT(0xa01d);
-    } else {
-      int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT(0xe672);
-#endif
-      RuntimeHashget(locktbl, reallock, &rwlock_obj);
-         lockvalue = (struct LockValue *)rwlock_obj;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-      lockvalue->value++;
-         lockvalue->redirectlock = (int)redirectlock;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-    }
-       BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
-       BAMBOO_DEBUGPRINT(0xf000);
-#endif
-    return;
-  } else {
-         // send lock release with redirect info msg
-         // for 32 bit machine, the size is always 4 words
-         send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
-  }
-}
-
-bool getwritelock_I(void * ptr) {
-  int targetcore = 0;
-  lockobj = (int)ptr;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       lock2require = lockobj;
-  } else {
-       lock2require = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
-  lockflag = false;
-#ifndef INTERRUPT
-  reside = false;
-#endif
-  lockresult = 0;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe561);
-  BAMBOO_DEBUGPRINT_REG(lockobj);
-  BAMBOO_DEBUGPRINT_REG(lock2require);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-    // reside on this core
-       int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
-       if(deny == -1) {
-               // redirected
-               return true;
-       } else {
-               if(lockobj == (int)ptr) {
-                       if(deny) {
-                               lockresult = 0;
-#ifdef DEBUG
-                               BAMBOO_DEBUGPRINT(0);
-#endif
-                       } else {
-                               lockresult = 1;
-#ifdef DEBUG
-                               BAMBOO_DEBUGPRINT(1);
-#endif
-                       }
-                       lockflag = true;
-#ifndef INTERRUPT
-                       reside = true;
-#endif
-               } else {
-                       // conflicts on lockresults
-                       BAMBOO_EXIT(0xa01e);
-               }
-               return true;
-       }
-  } else {
-         // send lock request msg
-         // for 32 bit machine, the size is always 5 words
-         send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
-  }
-  return true;
-}
-
-// redirected lock request
-bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
-  int targetcore = 0;
-
-  if(core == corenum) {
-         lockobj = (int)ptr;
-         lock2require = (int)redirectlock;
-         lockflag = false;
-#ifndef INTERRUPT
-         reside = false;
-#endif
-         lockresult = 0;
-  }
-  targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe571);
-  BAMBOO_DEBUGPRINT_REG((int)ptr);
-  BAMBOO_DEBUGPRINT_REG((int)redirectlock);
-  BAMBOO_DEBUGPRINT_REG(core);
-  BAMBOO_DEBUGPRINT_REG((int)cache);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-
-  if(targetcore == corenum) {
-    // reside on this core
-       int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
-       if(deny == -1) {
-               // redirected
-               return true;
-       } else {
-               if(core == corenum) {
-                       if(lockobj == (int)ptr) {
-                               if(deny) {
-                                       lockresult = 0;
-                               } else {
-                                       lockresult = 1;
-                                       RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
-                               }
-                               lockflag = true;
-#ifndef INTERRUPT
-                               reside = true;
-#endif
-                       } else {
-                               // conflicts on lockresults
-                               BAMBOO_EXIT(0xa01f);
-                       }
-                       return true;
-               } else {
-                       // 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(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
-                       } else {
-                               cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
-                       }
-               }
-       }
-  } else {
-       // redirect the lock request
-       // for 32 bit machine, the size is always 6 words
-       if((!cache) || (cache && !isMsgSending)) {
-               send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
-       } else {
-               cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
-       }
-  }
-  return true;
-}
-
-void releasewritelock_I(void * ptr) {
-  int targetcore = 0;
-  int reallock = 0;
-  if(((struct ___Object___ *)ptr)->lock == NULL) {
-       reallock = (int)ptr;
-  } else {
-       reallock = (int)(((struct ___Object___ *)ptr)->lock);
-  }
-  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe681);
-  BAMBOO_DEBUGPRINT_REG((int)ptr);
-  BAMBOO_DEBUGPRINT_REG(reallock);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-    // reside on this core
-    if(!RuntimeHashcontainskey(locktbl, reallock)) {
-      // no locks for this object, something is wrong
-      BAMBOO_EXIT(0xa020);
-    } else {
-      int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-      RuntimeHashget(locktbl, reallock, &rwlock_obj);
-         lockvalue = (struct LockValue *)rwlock_obj;
-      lockvalue->value++;
-    }
-    return;
-  } else {
-       // send lock release msg
-       // for 32 bit machine, the size is always 4 words
-       send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
-  }
-}
-
-void releasewritelock_I_r(void * lock, void * redirectlock) {
-  int targetcore = 0;
-  int reallock = (int)lock;
-  targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
-  BAMBOO_DEBUGPRINT(0xe691);
-  BAMBOO_DEBUGPRINT_REG((int)lock);
-  BAMBOO_DEBUGPRINT_REG(reallock);
-  BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-  if(targetcore == corenum) {
-    // reside on this core
-    if(!RuntimeHashcontainskey(locktbl, reallock)) {
-      // no locks for this object, something is wrong
-      BAMBOO_EXIT(0xa021);
-    } else {
-      int rwlock_obj = 0;
-         struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT(0xe692);
-#endif
-      RuntimeHashget(locktbl, reallock, &rwlock_obj);
-         lockvalue = (struct LockValue *)rwlock_obj;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-      lockvalue->value++;
-         lockvalue->redirectlock = (int)redirectlock;
-#ifdef DEBUG
-      BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-    }
-    return;
-  } else {
-       // send lock release msg
-       // for 32 bit machine, the size is always 4 words
-       send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
-  }
-}
 
-int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
+ent enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
   void * taskpointerarray[MAXTASKPARAMS];
   int j;
   //int numparams=parameter->task->numParameters;
@@ -3096,10 +2416,10 @@ loopstart:
 void printdebug() {
   int i;
   int j;
-  if(corenum > NUMCORES - 1) {
+  if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
     return;
   }
-  for(i=0; i<numtasks[corenum]; i++) {
+  for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
 #ifndef MULTICORE
        printf("%s\n", task->name);
@@ -3153,10 +2473,10 @@ void printdebug() {
 
 void processtasks() {
   int i;
-  if(corenum > NUMCORES - 1) {
+  if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
     return;
   }
-  for(i=0; i<numtasks[corenum]; i++) {
+  for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
     int j;