Fix bugs in scheduling simulator. Also add -robustroot setting in Tests/dotest script
[IRC.git] / Robust / src / Runtime / multicoretask.c
index 4f629a9357fd4a2b1cf33b274c66c4b9786445ee..237a1eb810fcf23742e8c0c0d707b4fe6b5de8a9 100644 (file)
@@ -56,7 +56,7 @@ struct RuntimeHash * reverse;
 
 int corestatus[NUMCORES]; // records status of each core
                           // 1: running tasks
-// 0: stall
+                          // 0: stall
 int numsendobjs[NUMCORES]; // records how many objects a core has sent out
 int numreceiveobjs[NUMCORES]; // records how many objects a core has received
 #ifdef RAW
@@ -117,7 +117,7 @@ void releasewritelock(void* ptr);
 // profiling mode of RAW version
 #ifdef RAWPROFILE
 
-#define TASKINFOLENGTH 150
+#define TASKINFOLENGTH 10000
 //#define INTERRUPTINFOLENGTH 500
 
 bool stall;
@@ -128,28 +128,29 @@ typedef struct task_info {
   char* taskName;
   int startTime;
   int endTime;
+  int exitIndex;
+  struct Queue * newObjs; 
 } TaskInfo;
 
 /*typedef struct interrupt_info {
-  int startTime;
-  int endTime;
-} InterruptInfo;*/
+   int startTime;
+   int endTime;
+   } InterruptInfo;*/
 
 TaskInfo * taskInfoArray[TASKINFOLENGTH];
 int taskInfoIndex;
 bool taskInfoOverflow;
 /*InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
-int interruptInfoIndex;
-bool interruptInfoOverflow;*/
+   int interruptInfoIndex;
+   bool interruptInfoOverflow;*/
 int profilestatus[NUMCORES]; // records status of each core
                              // 1: running tasks
-// 0: stall
+                             // 0: stall
 bool transProfileRequestMsg(int targetcore);
 void outputProfileData();
 #endif
 
 #ifdef RAW
-//#ifdef RAWPROFILE
 #ifdef RAWUSEIO
 int main(void) {
 #else
@@ -195,7 +196,6 @@ int main(int argc, char **argv) {
   for(i = 0; i < 30; ++i) {
     msgdata[i] = -1;
   }
-  //msgdata = NULL;
   msgtype = -1;
   msgdataindex = 0;
   msglength = 30;
@@ -238,8 +238,8 @@ int main(int argc, char **argv) {
   totalexetime = -1;
   taskInfoIndex = 0;
   /*interruptInfoIndex = 0;
-  taskInfoOverflow = false;
-  interruptInfoOverflow = false;*/
+     taskInfoOverflow = false;
+     interruptInfoOverflow = false;*/
 #endif
 
 #ifdef INTERRUPT
@@ -322,7 +322,6 @@ int main(int argc, char **argv) {
     }
   }
 
-  //pthread_exit(NULL);
   while(true) {
   }
 }
@@ -411,11 +410,6 @@ void run(void* arg) {
 #endif
 
   while(true) {
-/*#ifndef INTERRUPT
-          while(receiveObject() != -1) {
-          }
- #endif*/
-
     // check if there are new active tasks can be executed
     executetasks();
 
@@ -443,12 +437,16 @@ void run(void* arg) {
          taskInfo->taskName = "objqueue checking";
          taskInfo->startTime = raw_get_cycle();
          taskInfo->endTime = -1;
+         taskInfo->exitIndex = -1;
+         taskInfo->newObjs = NULL;
        }
        isChecking = true;
       }
 #endif
     while(!isEmpty(&objqueue)) {
       void * obj = NULL;
+      int * locks = NULL;
+      int numlocks = 0;
 #ifdef INTERRUPT
       raw_user_interrupts_off();
 #endif
@@ -461,36 +459,48 @@ void run(void* arg) {
       sendStall = false;
       tocontinue = true;
       objitem = getTail(&objqueue);
-      //obj = objitem->objectptr;
       objInfo = (struct transObjInfo *)objitem->objectptr;
       obj = objInfo->objptr;
 #ifdef RAWDEBUG
       raw_test_pass_reg((int)obj);
 #endif
       // grab lock and flush the obj
-      getreadlock_I(obj);
-      while(!lockflag) {
-       receiveObject();
+      grount = 0;
+      if(((struct ___Object___ *)obj)->numlocks == 0) {
+       locks = obj;
+       numlocks = 1;
+      } else {
+       locks = ((struct ___Object___ *)obj)->locks;
+       numlocks = ((struct ___Object___ *)obj)->numlocks;
       }
-      grount = lockresult;
+      for(; numlocks > 0; numlocks--) {
+       getreadlock_I(locks);
+       while(!lockflag) {
+         receiveObject();
+       }
+       grount = grount || lockresult;
 #ifdef RAWDEBUG
-      raw_test_pass_reg(grount);
+       raw_test_pass_reg(grount);
 #endif
 
-      lockresult = 0;
-      lockobj = 0;
-      lockflag = false;
+       lockresult = 0;
+       lockobj = 0;
+       lockflag = false;
 #ifndef INTERRUPT
-      reside = false;
+       reside = false;
 #endif
 
+       if(grount == 0) {
+         goto grablockfail;
+       }
+
+       locks = (int*)(*locks);
+      }
+
       if(grount == 1) {
        int k = 0;
+       // flush the object
        raw_invalidate_cache_range((int)obj, classsize[((struct ___Object___ *)obj)->type]);
-       // flush the obj
-       /*for(k = 0; k < classsize[((struct ___Object___ *)obj)->type]; ++k) {
-               invalidateAddr(obj + k);
-          }*/
        // enqueue the object
        for(k = 0; k < objInfo->length; ++k) {
          int taskindex = objInfo->queues[2 * k];
@@ -503,18 +513,35 @@ void run(void* arg) {
          enqueueObject_I(obj, queues, 1);
        }
        removeItem(&objqueue, objitem);
-       releasereadlock_I(obj);
+       if(((struct ___Object___ *)obj)->numlocks == 0) {
+         locks = obj;
+         numlocks = 1;
+       } else {
+         locks = ((struct ___Object___ *)obj)->locks;
+         numlocks = ((struct ___Object___ *)obj)->numlocks;
+       }
+       for(; numlocks > 0; numlocks--) {
+         releasereadlock_I(locks);
+         locks = (int *)(*locks);
+       }
        RUNFREE(objInfo->queues);
        RUNFREE(objInfo);
-       /*enqueueObject_I(obj, NULL, 0);
-          removeItem(&objqueue, objitem);
-          releasereadlock_I(obj);*/
       } else {
+grablockfail:
        // can not get lock
        // put it at the end of the queue
        // and try to execute active tasks already enqueued first
        removeItem(&objqueue, objitem);
        addNewItem_I(&objqueue, objInfo);
+       if(((struct ___Object___ *)obj)->numlocks > 0) {
+         //release grabbed locks
+         numlocks = ((struct ___Object___ *)obj)->numlocks - numlocks;
+         locks = ((struct ___Object___ *)obj)->locks;
+         for(; numlocks > 0; numlocks--) {
+           releasereadlock_I(locks);
+           locks = (int *)(*locks);
+         }
+       }
 #ifdef RAWPROFILE
        //isInterrupt = true;
 #endif
@@ -596,7 +623,6 @@ void run(void* arg) {
 #ifdef RAWDEBUG
            raw_test_pass(0xee11);
 #endif
-//#ifdef RAWPROFILE
 #ifdef RAWUSEIO
            totalexetime = raw_get_cycle();
 #else
@@ -707,7 +733,7 @@ void run(void* arg) {
   while(true) {
     switch(receiveObject()) {
     case 0: {
-      printf("[run, %d] receive an object\n", numofcore);
+      //printf("[run, %d] receive an object\n", numofcore);
       sendStall = false;
       // received an object
       // check if there are new active tasks can be executed
@@ -805,15 +831,6 @@ void run(void* arg) {
       break;
     }
 
-      /* case 3: {
-                               printf("[run, %d] receive a terminate msg\n", numofcore);
-                               // receive a terminate Msg
-                               assert(STARTUPCORE != corenum); // only non-startup core can receive such msg
-                               mq_close(mqd[corenum]);
-                               fflush(stdout);
-                               exit(0);
-                               break;
-                       }*/
     default: {
       printf("[run, %d] Error: invalid message type.\n", numofcore);
       fflush(stdout);
@@ -850,12 +867,13 @@ void createstartupobject(int argc, char ** argv) {
 
   startupobject->isolate = 1;
   startupobject->version = 0;
+  startupobject->numlocks = 0;
+  startupobject->locks = NULL;
 
   /* Set initialized flag for startup object */
   flagorandinit(startupobject,1,0xFFFFFFFF);
   enqueueObject(startupobject, NULL, 0);
 #ifdef RAW
-  //flushAll();
   raw_flush_entire_cache();
 #endif
 }
@@ -1427,6 +1445,37 @@ void calCoords(int core_num, int* coordY, int* coordX) {
 }
 #endif
 
+void addAliasLock(void * ptr, int lock) {
+  struct ___Object___ * obj = (struct ___Object___ *)ptr;
+  if(obj->numlocks == 0) {
+    // originally no alias locks associated
+    obj->locks = (int *)lock;
+    *(obj->locks) = 0;
+    obj->numlocks++;
+  } else {
+    // already have some alias locks
+    // insert the new lock into the sorted lock linklist
+    int prev, next;
+    prev = next = (int)obj->locks;
+    while(next != 0) {
+      if(next < lock) {
+       // next is less than lock, move to next node
+       prev = next;
+       next = *((int *)next);
+      } else if(next == lock) {
+       // already have this lock, do nothing
+       return;
+      } else {
+       // insert the lock between prev and next
+       break;
+      }
+    }
+    *(int *)prev = lock;
+    *(int *)lock = next;
+    obj->numlocks++;
+  }
+}
+
 /* Message format for RAW version:
  *      type + Msgbody
  * type: 0 -- transfer object
@@ -1436,7 +1485,7 @@ void calCoords(int core_num, int* coordY, int* coordX) {
  *       4 -- lock deny
  *       5 -- lock release
  *       6 -- transfer profile output msg
- *       7 -- transfer profile ouput finish msg
+ *       7 -- transfer profile output finish msg
  *
  * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
  * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
@@ -1454,21 +1503,15 @@ void transferObject(struct transObjInfo * transObj) {
   int type=((int *)obj)[0];
   int size=classsize[type];
   int targetcore = transObj->targetcore;
-  //assert(type < NUMCLASSES); // can only transfer normal object
 
 #ifdef RAW
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
-  //int isshared = 0;
   // for 32 bit machine, the size of fixed part is always 3 words
-  //int msgsize = sizeof(int) * 2 + sizeof(void *);
   int msgsize = 3 + transObj->length * 2;
   int i = 0;
 
   struct ___Object___ * newobj = (struct ___Object___ *)obj;
-  /*if(0 == newobj->isolate) {
-          isshared = 1;
-     }*/
 
   calCoords(corenum, &self_y, &self_x);
   calCoords(targetcore, &target_y, &target_x);
@@ -1491,7 +1534,7 @@ void transferObject(struct transObjInfo * transObj) {
 #ifdef RAWDEBUG
   raw_test_pass_reg(msgsize);
 #endif
-  gdn_send(obj);
+  gdn_send((int)obj);
 #ifdef RAWDEBUG
   raw_test_pass_reg(obj);
 #endif
@@ -1587,12 +1630,6 @@ void transferObject(struct transObjInfo * transObj) {
     fflush(stdout);
     exit(-1);
   }
-  /*struct ___Object___ * newobj = (struct ___Object___ *)obj;
-     if(0 == newobj->isolate) {
-          newobj = RUNMALLOC(size);
-          memcpy(newobj, obj, size);
-          newobj->original=obj;
-     }*/
   struct transObjInfo * tmptransObj = RUNMALLOC(sizeof(struct transObjInfo));
   memcpy(tmptransObj, transObj, sizeof(struct transObjInfo));
   int * tmpqueue = RUNMALLOC(sizeof(int)*2*tmptransObj->length);
@@ -1764,7 +1801,6 @@ bool transProfileRequestMsg(int targetcore) {
   unsigned msgHdr;
   int self_y, self_x, target_y, target_x;
   // for 32 bit machine, the size is always 4 words
-  //int msgsize = sizeof(int) * 4;
   int msgsize = 2;
 
   calCoords(corenum, &self_y, &self_x);
@@ -1866,15 +1902,42 @@ void outputProfileData() {
 
   if((fp = fopen(fn, "w+")) == NULL) {
     fprintf(stderr, "fopen error\n");
-    return -1;
+    return;
   }
 
-  fprintf(fp, "Task Name, Start Time, End Time, Duration\n");
+  fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
   // output task related info
   for(i = 0; i < taskInfoIndex; i++) {
     TaskInfo* tmpTInfo = taskInfoArray[i];
     int duration = tmpTInfo->endTime - tmpTInfo->startTime;
-    fprintf(fp, "%s, %d, %d, %d\n", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration);
+    fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
+       // summarize new obj info
+       if(tmpTInfo->newObjs != NULL) {
+               struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+               struct RuntimeIterator * iter = NULL;
+               while(0 == isEmpty(tmpTInfo->newObjs)) {
+                       char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+                       if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+                               int num = 0;
+                               RuntimeHashget(nobjtbl, (int)objtype, &num);
+                               RuntimeHashremovekey(nobjtbl, (int)objtype);
+                               num++;
+                               RuntimeHashadd(nobjtbl, (int)objtype, num);
+                       } else {
+                               RuntimeHashadd(nobjtbl, (int)objtype, 1);
+                       }
+                       //fprintf(stderr, "new obj!\n");
+               }
+
+               // output all new obj info
+               iter = RuntimeHashcreateiterator(nobjtbl);
+               while(RunhasNext(iter)) {
+                       char * objtype = (char *)Runkey(iter);
+                       int num = Runnext(iter);
+                       fprintf(fp, ", %s, %d", objtype, num);
+               }
+       }
+       fprintf(fp, "\n");
     if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
       preprocessingtime += duration;
     } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
@@ -1906,45 +1969,87 @@ void outputProfileData() {
 
   fclose(fp);
 #else
-     int i = 0;
-     int j = 0;
-
-     raw_test_pass(0xdddd);
-     // output task related info
-     for(i= 0; i < taskInfoIndex; i++) {
-          TaskInfo* tmpTInfo = taskInfoArray[i];
-          char* tmpName = tmpTInfo->taskName;
-          int nameLen = strlen(tmpName);
-          raw_test_pass(0xddda);
-          for(j = 0; j < nameLen; j++) {
-                  raw_test_pass_reg(tmpName[j]);
-          }
-          raw_test_pass(0xdddb);
-          raw_test_pass_reg(tmpTInfo->startTime);
-          raw_test_pass_reg(tmpTInfo->endTime);
-          raw_test_pass(0xdddc);
-     }
+  int i = 0;
+  int j = 0;
 
-     if(taskInfoOverflow) {
-          raw_test_pass(0xefee);
-     }
+  raw_test_pass(0xdddd);
+  // output task related info
+  for(i= 0; i < taskInfoIndex; i++) {
+    TaskInfo* tmpTInfo = taskInfoArray[i];
+    char* tmpName = tmpTInfo->taskName;
+    int nameLen = strlen(tmpName);
+    raw_test_pass(0xddda);
+    for(j = 0; j < nameLen; j++) {
+      raw_test_pass_reg(tmpName[j]);
+    }
+    raw_test_pass(0xdddb);
+    raw_test_pass_reg(tmpTInfo->startTime);
+    raw_test_pass_reg(tmpTInfo->endTime);
+       raw_test_pass_reg(tmpTInfo->exitIndex);
+       if(tmpTInfo->newObjs != NULL) {
+               struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+               struct RuntimeIterator * iter = NULL;
+               while(0 == isEmpty(tmpTInfo->newObjs)) {
+                       char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+                       if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+                               int num = 0;
+                               RuntimeHashget(nobjtbl, (int)objtype, &num);
+                               RuntimeHashremovekey(nobjtbl, (int)objtype);
+                               num++;
+                               RuntimeHashadd(nobjtbl, (int)objtype, num);
+                       } else {
+                               RuntimeHashadd(nobjtbl, (int)objtype, 1);
+                       }
+               }
+
+               // ouput all new obj info
+               iter = RuntimeHashcreateiterator(nobjtbl);
+               while(RunhasNext(iter)) {
+                       char * objtype = (char *)Runkey(iter);
+                       int num = Runnext(iter);
+                       int nameLen = strlen(objtype);
+                       raw_test_pass(0xddda);
+                       for(j = 0; j < nameLen; j++) {
+                               raw_test_pass_reg(objtype[j]);
+                       }
+                       raw_test_pass(0xdddb);
+                       raw_test_pass_reg(num);
+               }
+       }
+    raw_test_pass(0xdddc);
+  }
 
-     // output interrupt related info
-     /*for(i = 0; i < interruptInfoIndex; i++) {
-          InterruptInfo* tmpIInfo = interruptInfoArray[i];
-          raw_test_pass(0xddde);
-          raw_test_pass_reg(tmpIInfo->startTime);
-          raw_test_pass_reg(tmpIInfo->endTime);
-          raw_test_pass(0xdddf);
+  if(taskInfoOverflow) {
+    raw_test_pass(0xefee);
+  }
+
+  // output interrupt related info
+  /*for(i = 0; i < interruptInfoIndex; i++) {
+       InterruptInfo* tmpIInfo = interruptInfoArray[i];
+       raw_test_pass(0xddde);
+       raw_test_pass_reg(tmpIInfo->startTime);
+       raw_test_pass_reg(tmpIInfo->endTime);
+       raw_test_pass(0xdddf);
      }
 
      if(interruptInfoOverflow) {
-          raw_test_pass(0xefef);
+       raw_test_pass(0xefef);
      }*/
 
-     raw_test_pass(0xeeee);
+  raw_test_pass(0xeeee);
 #endif
 }
+
+inline void setTaskExitIndex(int index) {
+       taskInfoArray[taskInfoIndex]->exitIndex = index;
+}
+
+inline void addNewObjInfo(void * nobj) {
+       if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
+               taskInfoArray[taskInfoIndex]->newObjs = createQueue();
+       }
+       addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
+}
 #endif
 
 // receive object transferred from other cores
@@ -1976,11 +2081,11 @@ int receiveObject() {
   }
 #ifdef RAWPROFILE
   /*if(isInterrupt && (!interruptInfoOverflow)) {
-    // raw_test_pass(0xffff);
-    interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
-    interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
-    interruptInfoArray[interruptInfoIndex]->endTime = -1;
-  }*/
+     // raw_test_pass(0xffff);
+     interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
+     interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
+     interruptInfoArray[interruptInfoIndex]->endTime = -1;
+     }*/
 #endif
 msg:
 #ifdef RAWDEBUG
@@ -2005,38 +2110,6 @@ msg:
     raw_test_pass_reg(msgdata[msgdataindex]);
 #endif
     msgdataindex++;
-
-    /*if(msgdataindex == 0) {
-            // type
-            msgtype = gdn_receive();
-            if(msgtype > 2) {
-                    msglength = 3;
-            } else {
-                    msglength = 4;
-            }
-            if(msgtype != 0) {
-                    msgdata = (int *)RUNMALLOC_I(msglength * sizeof(int));
-                    msgdata[msgdataindex] = msgtype;
-            }
-     #ifdef RAWDEBUG
-            raw_test_pass_reg(msgtype);
-     #endif
-       } else if((msgdataindex == 1) && (msgtype == 0)) {
-            // object transfer msg
-            msglength = gdn_receive();
-            msgdata = (int *)RUNMALLOC_I(msglength * sizeof(int));
-            msgdata[0] = msgtype;
-            msgdata[msgdataindex] = msglength;
-     #ifdef RAWDEBUG
-            raw_test_pass_reg(msgdata[msgdataindex]);
-     #endif
-       } else {
-            msgdata[msgdataindex] = gdn_receive();
-     #ifdef RAWDEBUG
-            raw_test_pass_reg(msgdata[msgdataindex]);
-     #endif
-       }
-       msgdataindex++;*/
   }
 #ifdef RAWDEBUG
   raw_test_pass(0xffff);
@@ -2084,23 +2157,15 @@ msg:
          if(prev == NULL) {
            qitem = getTail(&objqueue);
          } else {
-           qitem = getNext(prev);
+           qitem = getNextQueueItem(prev);
          }
        }
-       //memcpy(transObj->queues, msgdata[3], sizeof(int)*(msglength - 3));
        addNewItem_I(&objqueue, (void *)transObj);
       }
       ++(self_numreceiveobjs);
 #ifdef RAWDEBUG
       raw_test_pass(0xe881);
 #endif
-      /*
-         addNewItem_I(&objqueue, (void *)data2);
-       ++(self_numreceiveobjs);
-       #ifdef RAWDEBUG
-         raw_test_pass(0xe881);
-       #endif
-       */
       break;
     }
 
@@ -2273,6 +2338,7 @@ msg:
       // receive lock release msg
       if(!RuntimeHashcontainskey(locktbl, data2)) {
        // no locks for this object, something is wrong
+       //raw_test_pass_reg(data2);
        raw_test_done(0xa004);
       } else {
        int rwlock_obj = 0;
@@ -2300,7 +2366,6 @@ msg:
       // receive an output request msg
       if(corenum == STARTUPCORE) {
        // startup core can not receive profile output finish msg
-       // return -1
        raw_test_done(0xa00a);
       }
       {
@@ -2350,7 +2415,6 @@ msg:
       // receive a profile output finish msg
       if(corenum != STARTUPCORE) {
        // non startup core can not receive profile output finish msg
-       // return -1
        raw_test_done(0xa00b);
       }
       profilestatus[data1] = 0;
@@ -2361,13 +2425,10 @@ msg:
     default:
       break;
     }
-    //RUNFREE(msgdata);
-    //msgdata = NULL;
     for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
       msgdata[msgdataindex] = -1;
     }
     msgtype = -1;
-    //msgdataindex = 0;
     msglength = 30;
 #ifdef RAWDEBUG
     raw_test_pass(0xe888);
@@ -2380,7 +2441,7 @@ msg:
       interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
       interruptInfoIndex++;
       if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
-       interruptInfoOverflow = true;
+        interruptInfoOverflow = true;
       }
     }*/
 #endif
@@ -2395,7 +2456,7 @@ msg:
       interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
       interruptInfoIndex++;
       if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
-       interruptInfoOverflow = true;
+        interruptInfoOverflow = true;
       }
     }*/
 #endif
@@ -2425,11 +2486,7 @@ msg:
     printf("<receiveObject> index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
     free(msgptr);
     return 2;
-  }       /*else if(((int*)msgptr)[0] == -2) {
-               // terminate msg
-               return 3;
-            } */
-  else {
+  } else {
     // an object
     if(numofcore == STARTUPCORE) {
       ++(numreceiveobjs[numofcore]);
@@ -2468,7 +2525,6 @@ bool getreadlock(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = 0;       //((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 4 words
-  //int msgsize = sizeof(int) * 4;
   int msgsize = 4;
   int tc = TOTALCORE;
 #ifdef INTERRUPT
@@ -2550,7 +2606,7 @@ bool getreadlock(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(0);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
 #endif
@@ -2665,7 +2721,6 @@ void releasereadlock(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = 0;       //((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 3 words
-  //int msgsize = sizeof(int) * 3;
   int msgsize = 3;
   int tc = TOTALCORE;
 #ifdef INTERRUPT
@@ -2718,7 +2773,7 @@ void releasereadlock(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(0);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
   raw_test_pass(0xffff);
@@ -2788,7 +2843,6 @@ bool getreadlock_I(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = ((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 4 words
-  //int msgsize = sizeof(int) * 4;
   int msgsize = 4;
 
   lockobj = (int)ptr;
@@ -2854,7 +2908,7 @@ bool getreadlock_I(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(0);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
 #endif
@@ -2871,7 +2925,6 @@ void releasereadlock_I(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = ((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 3 words
-  //int msgsize = sizeof(int) * 3;
   int msgsize = 3;
 
   if(targetcore == corenum) {
@@ -2908,7 +2961,7 @@ void releasereadlock_I(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(0);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
   raw_test_pass(0xffff);
@@ -2923,7 +2976,6 @@ bool getwritelock(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = 0;       //((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 4 words
-  //int msgsize = sizeof(int) * 4;
   int msgsize= 4;
   int tc = TOTALCORE;
 #ifdef INTERRUPT
@@ -3032,7 +3084,7 @@ bool getwritelock(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(1);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
 #endif
@@ -3150,7 +3202,6 @@ void releasewritelock(void * ptr) {
   int self_y, self_x, target_y, target_x;
   int targetcore = 0;       //((int)ptr >> 5) % TOTALCORE;
   // for 32 bit machine, the size is always 3 words
-  //int msgsize = sizeof(int) * 3;
   int msgsize = 3;
   int tc = TOTALCORE;
 #ifdef INTERRUPT
@@ -3215,7 +3266,7 @@ void releasewritelock(void * ptr) {
 #ifdef RAWDEBUG
   raw_test_pass(1);
 #endif
-  gdn_send(ptr);
+  gdn_send((int)ptr);
 #ifdef RAWDEBUG
   raw_test_pass_reg(ptr);
   raw_test_pass(0xffff);
@@ -3570,18 +3621,13 @@ newtask:
        checkTaskInfo->taskName = "tpd checking";
        checkTaskInfo->startTime = raw_get_cycle();
        checkTaskInfo->endTime = -1;
+       checkTaskInfo->exitIndex = -1;
+       checkTaskInfo->newObjs = NULL;
       }
 #endif
       currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
       genfreekey(activetasks, currtpd);
 
-      /* Check if this task has failed, allow a task that contains optional objects to fire */
-      /*if (gencontains(failedtasks, currtpd)) {
-         // Free up task parameter descriptor
-         RUNFREE(currtpd->parameterArray);
-         RUNFREE(currtpd);
-         goto newtask;
-         }*/
       numparams=currtpd->task->numParameters;
       numtotal=currtpd->task->numTotal;
 
@@ -3591,6 +3637,8 @@ newtask:
       /* Make sure that the parameters are still in the queues */
       for(i=0; i<numparams; i++) {
        void * parameter=currtpd->parameterArray[i];
+       int * locks;
+       int numlocks;
 #ifdef RAW
 #ifdef RAWDEBUG
        raw_test_pass(0xe993);
@@ -3603,46 +3651,80 @@ newtask:
        }
        lock = true;
        // require locks for this parameter if it is not a startup object
-       getwritelock(parameter);
+       if(((struct ___Object___ *)parameter)->numlocks == 0) {
+         numlocks = 1;
+         locks = parameter;
+       } else {
+         numlocks = ((struct ___Object___ *)parameter)->numlocks;
+         locks = ((struct ___Object___ *)parameter)->locks;
+       }
+
        grount = 0;
+       for(; numlocks > 0; numlocks--) {
+         getwritelock(locks);
 
 #ifdef INTERRUPT
-       raw_user_interrupts_off();
+         raw_user_interrupts_off();
 #endif
 #ifdef RAWPROFILE
-       //isInterrupt = false;
+         //isInterrupt = false;
 #endif
-       while(!lockflag) {
-         receiveObject();
-       }
+         while(!lockflag) {
+           receiveObject();
+         }
 #ifndef INTERRUPT
-       if(reside) {
-         while(receiveObject() != -1) {
+         if(reside) {
+           while(receiveObject() != -1) {
+           }
          }
-       }
 #endif
-       grount = lockresult;
+         grount = grount || lockresult;
 
-       lockresult = 0;
-       lockobj = 0;
-       lockflag = false;
+         lockresult = 0;
+         lockobj = 0;
+         lockflag = false;
 #ifndef INTERRUPT
-       reside = false;
+         reside = false;
 #endif
 #ifdef RAWPROFILE
-       //isInterrupt = true;
+         //isInterrupt = true;
 #endif
 #ifdef INTERRUPT
-       raw_user_interrupts_on();
+         raw_user_interrupts_on();
 #endif
 
+         if(grount == 0) {
+           goto grablock_fail;
+         }
+         locks = (int *)(*locks);
+       }
+
        if(grount == 0) {
+grablock_fail:
 #ifdef RAWDEBUG
          raw_test_pass(0xe994);
 #endif
          // can not get the lock, try later
+         // first release all grabbed locks for this parameter
+         numlocks = ((struct ___Object___ *)parameter)->numlocks - numlocks;
+         locks = ((struct ___Object___ *)parameter)->locks;
+         for(; numlocks > 0; numlocks--) {
+           releasewritelock(locks);
+           locks = (int *)(*locks);
+         }
+         // then releas all grabbed locks for previous parameters
          for(j = 0; j < i; ++j) {
-           releasewritelock(taskpointerarray[j+OFFSET]);
+           if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+             locks = taskpointerarray[j+OFFSET];
+             numlocks = 1;
+           } else {
+             locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+             numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+           }
+           for(; numlocks > 0; numlocks--) {
+             releasewritelock(locks);
+             locks = (int *)(*locks);
+           }
          }
          genputtable(activetasks, currtpd, currtpd);
          if(hashsize(activetasks) == 1) {
@@ -3666,10 +3748,6 @@ newtask:
        // flush the object
        {
          raw_invalidate_cache_range((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
-         /*int tmp = 0;
-            for(tmp = 0; tmp < classsize[((struct ___Object___ *)parameter)->type]; ++tmp) {
-                 invalidateAddr(parameter + tmp);
-            }*/
        }
 #endif
        tmpparam = (struct ___Object___ *)parameter;
@@ -3683,8 +3761,7 @@ newtask:
        if(0 == tmpparam->isolate) {
          isolateflags[i] = 0;
          // shared object, need to flush with current value
-         //if(!getreadlock(tmpparam->original)) {
-         //    // fail to get read lock of the original object, try this task later
+         // TODO: need modification according to added alias locks
          if(!getwritelock(tmpparam->original)) {
            // fail to get write lock, release all obtained locks and try this task later
            int j = 0;
@@ -3697,9 +3774,6 @@ newtask:
            goto newtask;
          }
          if(tmpparam->version != tmpparam->original->version) {
-           // some task on another core has changed this object
-           // flush this object
-           //memcpy(tmpparam, tmpparam->original, classsize[tmpparam->type]);
            // release all obtained locks
            int j = 0;
            for(j = 0; j < i; ++j) {
@@ -3725,8 +3799,6 @@ newtask:
                  free(enterflags);
              }
            }
-           // try to enqueue it again to check if it feeds other tasks;
-           //enqueueObject(tmpparam, NULL, 0);
            // Free up task parameter descriptor
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
@@ -3746,9 +3818,29 @@ newtask:
 #endif
            // release grabbed locks
            for(j = 0; j < i; ++j) {
-             releasewritelock(taskpointerarray[j+OFFSET]);
+             if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+               numlocks = 1;
+               locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+             } else {
+               numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+               locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+             }
+             for(; numlocks > 0; numlocks--) {
+               releasewritelock(locks);
+               locks = (int *)(*locks);
+             }
+           }
+           if(((struct ___Object___ *)parameter)->numlocks == 0) {
+             numlocks = 1;
+             locks = parameter;
+           } else {
+             numlocks = ((struct ___Object___ *)parameter)->numlocks;
+             locks = ((struct ___Object___ *)parameter)->locks;
+           }
+           for(; numlocks > 0; numlocks--) {
+             releasewritelock(locks);
+             locks = (int *)(*locks);
            }
-           releasewritelock(parameter);
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
            goto newtask;
@@ -3788,9 +3880,29 @@ newtask:
              free(enterflags);
            // release grabbed locks
            for(j = 0; j < i; ++j) {
-             releasewritelock(taskpointerarray[j+OFFSET]);
+             if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+               numlocks = 1;
+               locks = taskpointerarray[j+OFFSET];
+             } else {
+               numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+               locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+             }
+             for(; numlocks > 0; numlocks--) {
+               releasewritelock(locks);
+               locks = (int *)(*locks);
+             }
+           }
+           if(((struct ___Object___ *)parameter)->numlocks == 0) {
+             numlocks = 1;
+             locks = parameter;
+           } else {
+             numlocks = ((struct ___Object___ *)parameter)->numlocks;
+             locks = ((struct ___Object___ *)parameter)->locks;
+           }
+           for(; numlocks > 0; numlocks--) {
+             releasewritelock(locks);
+             locks = (int *)(*locks);
            }
-           releasewritelock(parameter);
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
 #ifdef RAWPROFILE
@@ -3873,6 +3985,7 @@ parameterpresent:
 #ifdef RAWDEBUG
          raw_test_pass_reg(x);
 #endif
+         raw_test_pass_reg(x);
          raw_test_done(0xa009);
 #else
          exit(-1);
@@ -3886,7 +3999,7 @@ parameterpresent:
             }*/
          /* Actually call task */
 #ifdef PRECISE_GC
-                                                                           ((int *)taskpointerarray)[0]=currtpd->numParameters;
+                                                                                 ((int *)taskpointerarray)[0]=currtpd->numParameters;
          taskpointerarray[1]=NULL;
 #endif
 execute:
@@ -3908,6 +4021,8 @@ execute:
            taskInfo->taskName = currtpd->task->name;
            taskInfo->startTime = raw_get_cycle();
            taskInfo->endTime = -1;
+               taskInfo->exitIndex = -1;
+               taskInfo->newObjs = NULL;
          }
 #endif
 
@@ -3938,6 +4053,8 @@ execute:
            postTaskInfo->taskName = "post task execution";
            postTaskInfo->startTime = raw_get_cycle();
            postTaskInfo->endTime = -1;
+               postTaskInfo->exitIndex = -1;
+               postTaskInfo->newObjs = NULL;
          }
 #endif
 #ifdef RAWDEBUG
@@ -3950,17 +4067,39 @@ execute:
            for(i = 0; i < numparams; ++i) {
              int j = 0;
              struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+             int numlocks;
+             int * locks;
 #ifdef RAWDEBUG
              raw_test_pass(0xe999);
              raw_test_pass(0xdd100000 + tmpparam->flag);
 #endif
-             releasewritelock(tmpparam);
+             if(tmpparam->numlocks == 0) {
+               numlocks = 1;
+               locks = (int*)tmpparam;
+             } else {
+               numlocks = tmpparam->numlocks;
+               locks = tmpparam->locks;
+             }
+             for(; numlocks > 0; numlocks--) {
+               releasewritelock(locks);
+               locks = (int *)(*locks);
+             }
            }
 #elif defined THREADSIMULATE
            for(i = 0; i < numparams; ++i) {
              if(0 == isolateflags[i]) {
                struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
-               releasewritelock(tmpparam);
+               if(tmpparam->numlocks == 0) {
+                 numlocks = 1;
+                 locks = (int*)tmpparam;
+               } else {
+                 numlocks = tmpparam->numlocks;
+                 locks = tmpparam->locks;
+               }
+               for(; numlocks > 0; numlocks--) {
+                 releasewritelock(locks);
+                 locks = (int *)(*locks);
+               }
              }
            }
 #endif