09d817e65a9364432da162560dbb221100937e52
[IRC.git] / Robust / src / Runtime / multicoretask.c
1 #ifdef TASK
2 #include "runtime.h"
3 #ifndef RAW
4 #include "structdefs.h"
5 #include "mem.h"
6 #include "checkpoint.h"
7 #include "Queue.h"
8 #include "SimpleHash.h"
9 #include "GenericHashtable.h"
10 #include <sys/select.h>
11 #include <sys/types.h>
12 #include <sys/mman.h>
13 #include <string.h>
14 #include <signal.h>
15 #include <assert.h>
16 #include <errno.h>
17 #endif
18 #ifdef RAW
19 #ifdef RAWPROFILE
20 #ifdef RAWUSEIO
21 #include "stdio.h"
22 #include "string.h"
23 #endif
24 #endif
25 #include <raw.h>
26 #include <raw_compiler_defs.h>
27 #elif defined THREADSIMULATE
28 // use POSIX message queue
29 // for each core, its message queue named as
30 // /msgqueue_corenum
31 #include <mqueue.h>
32 #include <sys/stat.h>
33 #endif
34 /*
35    extern int injectfailures;
36    extern float failurechance;
37  */
38 extern int debugtask;
39 extern int instaccum;
40
41 #ifdef RAW
42 #define TOTALCORE raw_get_num_tiles()
43 #endif
44
45 #ifdef CONSCHECK
46 #include "instrument.h"
47 #endif
48
49 struct genhashtable * activetasks;
50 struct genhashtable * failedtasks;
51 struct taskparamdescriptor * currtpd;
52 #ifndef RAW
53 struct RuntimeHash * forward;
54 struct RuntimeHash * reverse;
55 #endif
56
57 int corestatus[NUMCORES]; // records status of each core
58                           // 1: running tasks
59                           // 0: stall
60 int numsendobjs[NUMCORES]; // records how many objects a core has sent out
61 int numreceiveobjs[NUMCORES]; // records how many objects a core has received
62 int numconfirm;
63 bool waitconfirm;
64 bool busystatus;
65 #ifdef RAW
66 struct RuntimeHash locktable;
67 static struct RuntimeHash* locktbl = &locktable;
68 struct LockValue {
69         int redirectlock;
70         int value;
71 };
72 struct RuntimeHash * objRedirectLockTbl;
73 void * curr_heapbase=0;
74 void * curr_heaptop=0;
75 int self_numsendobjs;
76 int self_numreceiveobjs;
77 int lockobj;
78 int lock2require;
79 int lockresult;
80 bool lockflag;
81 #ifndef INTERRUPT
82 bool reside;
83 #endif
84 struct Queue objqueue;
85 int msgdata[30];
86 int msgtype;
87 int msgdataindex;
88 int msglength;
89 int outmsgdata[30];
90 int outmsgindex;
91 int outmsglast;
92 int outmsgleft;
93 bool isMsgHanging;
94 volatile bool isMsgSending;
95 void calCoords(int core_num, int* coordY, int* coordX);
96 #elif defined THREADSIMULATE
97 static struct RuntimeHash* locktbl;
98 struct thread_data {
99   int corenum;
100   int argc;
101   char** argv;
102   int numsendobjs;
103   int numreceiveobjs;
104 };
105 struct thread_data thread_data_array[NUMCORES];
106 mqd_t mqd[NUMCORES];
107 static pthread_key_t key;
108 static pthread_rwlock_t rwlock_tbl;
109 static pthread_rwlock_t rwlock_init;
110
111 void run(void * arg);
112 #endif
113
114 bool transStallMsg(int targetcore);
115 void transStatusConfirmMsg(int targetcore);
116 int receiveObject();
117 bool getreadlock(void* ptr);
118 void releasereadlock(void* ptr);
119 #ifdef RAW
120 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
121 #endif
122 bool getwritelock(void* ptr);
123 void releasewritelock(void* ptr);
124 void releasewritelock_r(void * lock, void * redirectlock);
125 #ifdef RAW
126 bool getwritelock_I(void* ptr);
127 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
128 void releasewritelock_I(void * ptr);
129 #endif
130
131 // profiling mode of RAW version
132 #ifdef RAWPROFILE
133
134 #define TASKINFOLENGTH 10000
135 //#define INTERRUPTINFOLENGTH 500
136
137 bool stall;
138 //bool isInterrupt;
139 int totalexetime;
140
141 typedef struct task_info {
142   char* taskName;
143   int startTime;
144   int endTime;
145   int exitIndex;
146   struct Queue * newObjs; 
147 } TaskInfo;
148
149 /*typedef struct interrupt_info {
150    int startTime;
151    int endTime;
152    } InterruptInfo;*/
153
154 TaskInfo * taskInfoArray[TASKINFOLENGTH];
155 int taskInfoIndex;
156 bool taskInfoOverflow;
157 /*InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
158    int interruptInfoIndex;
159    bool interruptInfoOverflow;*/
160 int profilestatus[NUMCORES]; // records status of each core
161                              // 1: running tasks
162                              // 0: stall
163 bool transProfileRequestMsg(int targetcore);
164 void outputProfileData();
165 #endif
166
167 #ifdef RAW
168 #ifdef RAWUSEIO
169 int main(void) {
170 #else
171 void begin() {
172 #endif
173 #else
174 int main(int argc, char **argv) {
175 #endif
176 #ifdef RAW
177   int i = 0;
178   int argc = 1;
179   char ** argv = NULL;
180   bool sendStall = false;
181   bool isfirst = true;
182   bool tocontinue = false;
183   struct QueueItem * objitem = NULL;
184   struct transObjInfo * objInfo = NULL;
185   int grount = 0;
186   bool allStall = true;
187   int sumsendobj = 0;
188
189   corenum = raw_get_abs_pos_x() + raw_get_array_size_x() * raw_get_abs_pos_y();
190
191   // initialize the arrays
192   if(STARTUPCORE == corenum) {
193     // startup core to initialize corestatus[]
194     for(i = 0; i < NUMCORES; ++i) {
195       corestatus[i] = 1;
196       numsendobjs[i] = 0;                   // assume all variables in RAW are local variables! MAY BE WRONG!!!
197       numreceiveobjs[i] = 0;
198     }
199         numconfirm = 0;
200         waitconfirm = false;
201 #ifdef RAWPROFILE
202     for(i = 0; i < NUMCORES; ++i) {
203       profilestatus[i] = 1;
204     }
205 #endif
206   }
207   busystatus = true;
208   self_numsendobjs = 0;
209   self_numreceiveobjs = 0;
210   for(i = 0; i < 30; ++i) {
211     msgdata[i] = -1;
212   }
213   msgtype = -1;
214   msgdataindex = 0;
215   msglength = 30;
216
217   for(i = 0; i < 30; ++i) {
218     outmsgdata[i] = -1;
219   }
220   outmsgindex = 0;
221   outmsglast = 0;
222   outmsgleft = 0;
223   isMsgHanging = false;
224   isMsgSending = false;
225
226   // create the lock table, lockresult table and obj queue
227   locktable.size = 20;
228   locktable.bucket = (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
229   /* Set allocation blocks*/
230   locktable.listhead=NULL;
231   locktable.listtail=NULL;
232   /*Set data counts*/
233   locktable.numelements = 0;
234   lockobj = 0;
235   lock2require = 0;
236   lockresult = 0;
237   lockflag = false;
238 #ifndef INTERRUPT
239   reside = false;
240 #endif
241   objqueue.head = NULL;
242   objqueue.tail = NULL;
243   lockRedirectTbl = allocateRuntimeHash(20);
244   objRedirectLockTbl = allocateRuntimeHash(20);
245
246 #ifdef RAWPROFILE
247   stall = false;
248   //isInterrupt = true;
249   totalexetime = -1;
250   taskInfoIndex = 0;
251   /*interruptInfoIndex = 0;
252      taskInfoOverflow = false;
253      interruptInfoOverflow = false;*/
254 #endif
255
256 #ifdef INTERRUPT
257   if (corenum < NUMCORES) {
258     // set up interrupts
259     setup_ints();
260     raw_user_interrupts_on();
261   }
262 #endif
263
264 #elif defined THREADSIMULATE
265   errno = 0;
266   int tids[NUMCORES];
267   int rc[NUMCORES];
268   pthread_t threads[NUMCORES];
269   int i = 0;
270
271   // initialize three arrays and msg queue array
272   char * pathhead = "/msgqueue_";
273   int targetlen = strlen(pathhead);
274   for(i = 0; i < NUMCORES; ++i) {
275     corestatus[i] = 1;
276     numsendobjs[i] = 0;
277     numreceiveobjs[i] = 0;
278
279     char corenumstr[3];
280     int sourcelen = 0;
281     if(i < 10) {
282       corenumstr[0] = i + '0';
283       corenumstr[1] = '\0';
284       sourcelen = 1;
285     } else if(i < 100) {
286       corenumstr[1] = i %10 + '0';
287       corenumstr[0] = (i / 10) + '0';
288       corenumstr[2] = '\0';
289       sourcelen = 2;
290     } else {
291       printf("Error: i >= 100\n");
292       fflush(stdout);
293       exit(-1);
294     }
295     char path[targetlen + sourcelen + 1];
296     strcpy(path, pathhead);
297     strncat(path, corenumstr, sourcelen);
298     int oflags = O_RDONLY|O_CREAT|O_NONBLOCK;
299     int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
300     mq_unlink(path);
301     mqd[i]= mq_open(path, oflags, omodes, NULL);
302     if(mqd[i] == -1) {
303       printf("[Main] mq_open %s fails: %d, error: %s\n", path, mqd[i], strerror(errno));
304       exit(-1);
305     } else {
306       printf("[Main] mq_open %s returns: %d\n", path, mqd[i]);
307     }
308   }
309
310   // create the key
311   pthread_key_create(&key, NULL);
312
313   // create the lock table and initialize its mutex
314   locktbl = allocateRuntimeHash(20);
315   int rc_locktbl = pthread_rwlock_init(&rwlock_tbl, NULL);
316   printf("[Main] initialize the rwlock for lock table: %d error: \n", rc_locktbl, strerror(rc_locktbl));
317
318   for(i = 0; i < NUMCORES; ++i) {
319     thread_data_array[i].corenum = i;
320     thread_data_array[i].argc = argc;
321     thread_data_array[i].argv = argv;
322     thread_data_array[i].numsendobjs = 0;
323     thread_data_array[i].numreceiveobjs = 0;
324     printf("[main] creating thread %d\n", i);
325     rc[i] = pthread_create(&threads[i], NULL, run, (void *)&thread_data_array[i]);
326     if (rc[i]) {
327       printf("[main] ERROR; return code from pthread_create() is %d\n", rc[i]);
328       fflush(stdout);
329       exit(-1);
330     }
331   }
332
333   while(true) {
334   }
335 }
336
337 void run(void* arg) {
338   struct thread_data * my_tdata = (struct thread_data *)arg;
339   pthread_setspecific(key, (void *)my_tdata->corenum);
340   int argc = my_tdata->argc;
341   char** argv = my_tdata->argv;
342   printf("[run, %d] Thread %d runs: %x\n", my_tdata->corenum, my_tdata->corenum, (int)pthread_self());
343   fflush(stdout);
344
345 #endif
346
347 #ifdef BOEHM_GC
348   GC_init(); // Initialize the garbage collector
349 #endif
350 #ifdef CONSCHECK
351   initializemmap();
352 #endif
353 #ifndef RAW
354   processOptions();
355 #endif
356   initializeexithandler();
357   /* Create table for failed tasks */
358 #ifdef RAW
359   if(corenum > NUMCORES - 1) {
360     failedtasks = NULL;
361     activetasks = NULL;
362 /*#ifdef RAWPROFILE
363         raw_test_pass(0xee01);
364         raw_test_pass_reg(taskInfoIndex);
365         raw_test_pass_reg(taskInfoOverflow);
366         if(!taskInfoOverflow) {
367         TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
368         taskInfoArray[taskInfoIndex] = taskInfo;
369         taskInfo->taskName = "msg handling";
370         taskInfo->startTime = raw_get_cycle();
371         taskInfo->endTime = -1;
372         }
373  #endif*/
374 #ifdef RAWPROFILE
375     //isInterrupt = false;
376 #endif
377     while(true) {
378       receiveObject();
379     }
380   } else {
381 #endif
382   /*failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
383                                    (int (*)(void *,void *)) &comparetpd);*/
384   failedtasks = NULL;
385   /* Create queue of active tasks */
386   activetasks=genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
387                                    (int(*) (void *,void *)) &comparetpd);
388
389   /* Process task information */
390   processtasks();
391
392   if(STARTUPCORE == corenum) {
393     /* Create startup object */
394     createstartupobject(argc, argv);
395   }
396
397 #ifdef RAW
398 #ifdef RAWDEBUG
399   raw_test_pass(0xee00);
400 #endif
401
402   while(true) {
403     // check if there are new active tasks can be executed
404     executetasks();
405
406 #ifndef INTERRUPT
407     while(receiveObject() != -1) {
408     }
409 #endif
410
411 #ifdef RAWDEBUG
412     raw_test_pass(0xee01);
413 #endif
414
415     // check if there are some pending objects, if yes, enqueue them and executetasks again
416     tocontinue = false;
417 #ifdef RAWPROFILE
418     {
419       bool isChecking = false;
420       if(!isEmpty(&objqueue)) {
421         if(!taskInfoOverflow) {
422           TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
423           taskInfoArray[taskInfoIndex] = taskInfo;
424           taskInfo->taskName = "objqueue checking";
425           taskInfo->startTime = raw_get_cycle();
426           taskInfo->endTime = -1;
427           taskInfo->exitIndex = -1;
428           taskInfo->newObjs = NULL;
429         }
430         isChecking = true;
431       }
432 #endif
433     while(!isEmpty(&objqueue)) {
434       void * obj = NULL;
435 #ifdef INTERRUPT
436       raw_user_interrupts_off();
437 #endif
438 #ifdef RAWPROFILE
439       //isInterrupt = false;
440 #endif
441 #ifdef RAWDEBUG
442       raw_test_pass(0xeee1);
443 #endif
444       sendStall = false;
445       tocontinue = true;
446       objitem = getTail(&objqueue);
447       objInfo = (struct transObjInfo *)objitem->objectptr;
448       obj = objInfo->objptr;
449 #ifdef RAWDEBUG
450       raw_test_pass_reg((int)obj);
451 #endif
452       // grab lock and flush the obj
453       grount = 0;
454         getwritelock_I(obj);
455         while(!lockflag) {
456           receiveObject();
457         }
458         grount = lockresult;
459 #ifdef RAWDEBUG
460         raw_test_pass_reg(grount);
461 #endif
462
463         lockresult = 0;
464         lockobj = 0;
465         lock2require = 0;
466         lockflag = false;
467 #ifndef INTERRUPT
468         reside = false;
469 #endif
470
471       if(grount == 1) {
472         int k = 0;
473         // flush the object
474 #ifdef RAWCACHEFLUSH
475         raw_invalidate_cache_range((int)obj, classsize[((struct ___Object___ *)obj)->type]);
476 #endif
477         // enqueue the object
478         for(k = 0; k < objInfo->length; ++k) {
479           int taskindex = objInfo->queues[2 * k];
480           int paramindex = objInfo->queues[2 * k + 1];
481           struct parameterwrapper ** queues = &(paramqueues[corenum][taskindex][paramindex]);
482 #ifdef RAWDEBUG
483           raw_test_pass_reg(taskindex);
484           raw_test_pass_reg(paramindex);
485 #endif
486           enqueueObject_I(obj, queues, 1);
487         }
488         removeItem(&objqueue, objitem);
489           releasewritelock_I(obj);
490         RUNFREE(objInfo->queues);
491         RUNFREE(objInfo);
492       } else {
493         // can not get lock
494         // put it at the end of the queue
495         // and try to execute active tasks already enqueued first
496         removeItem(&objqueue, objitem);
497         addNewItem_I(&objqueue, objInfo);
498 #ifdef RAWPROFILE
499         //isInterrupt = true;
500 #endif
501 #ifdef INTERRUPT
502         raw_user_interrupts_on();
503 #endif
504         break;
505       }
506 #ifdef INTERRUPT
507       raw_user_interrupts_on();
508 #endif
509     }
510 #ifdef RAWPROFILE
511     if(isChecking && (!taskInfoOverflow)) {
512       taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
513       taskInfoIndex++;
514       if(taskInfoIndex == TASKINFOLENGTH) {
515         taskInfoOverflow = true;
516       }
517     }
518   }
519 #endif
520 #ifdef RAWDEBUG
521     raw_test_pass(0xee02);
522 #endif
523
524     if(!tocontinue) {
525       // check if stop
526       if(STARTUPCORE == corenum) {
527         if(isfirst) {
528 #ifdef RAWDEBUG
529           raw_test_pass(0xee03);
530 #endif
531           isfirst = false;
532         }
533         if((!waitconfirm) || 
534                         (waitconfirm && (numconfirm == 0))) {
535 #ifdef RAWDEBUG
536           raw_test_pass(0xee04);
537 #endif
538 #ifdef INTERRUPT
539                 raw_user_interrupts_off();
540 #endif
541                 corestatus[corenum] = 0;
542                 numsendobjs[corenum] = self_numsendobjs;
543                 numreceiveobjs[corenum] = self_numreceiveobjs;
544                 // check the status of all cores
545                 allStall = true;
546 #ifdef RAWDEBUG
547                 raw_test_pass_reg(NUMCORES);
548 #endif
549                 for(i = 0; i < NUMCORES; ++i) {
550 #ifdef RAWDEBUG
551                   raw_test_pass(0xe000 + corestatus[i]);
552 #endif
553                   if(corestatus[i] != 0) {
554                 allStall = false;
555                     break;
556                   }
557                 }
558                 if(allStall) {
559                         if(!waitconfirm) {
560                                 // the first time found all cores stall
561                                 // send out status confirm msg to all other cores
562                                 // reset the corestatus array too
563 #ifdef RAWDEBUG
564           raw_test_pass(0xee05);
565 #endif
566                                 corestatus[corenum] = 1;
567                                 for(i = 1; i < NUMCORES; ++i) {
568                                         corestatus[i] = 1;
569                                         transStatusConfirmMsg(i);
570                                 }
571                                 waitconfirm = true;
572                                 numconfirm = NUMCORES - 1;
573                         } else {
574                                 // all the core status info are the latest
575                           // check if the sum of send objs and receive obj are the same
576                           // yes->terminate; for profiling mode, yes->send request to all
577                           // other cores to pour out profiling data
578                           // no->go on executing
579 #ifdef RAWDEBUG
580           raw_test_pass(0xee06);
581 #endif
582                           sumsendobj = 0;
583                           for(i = 0; i < NUMCORES; ++i) {
584                         sumsendobj += numsendobjs[i];
585 #ifdef RAWDEBUG
586                         raw_test_pass(0xf000 + numsendobjs[i]);
587 #endif
588                           }
589                           for(i = 0; i < NUMCORES; ++i) {
590                         sumsendobj -= numreceiveobjs[i];
591 #ifdef RAWDEBUG
592                         raw_test_pass(0xf000 + numreceiveobjs[i]);
593 #endif
594                           }
595                           if(0 == sumsendobj) {
596                         // terminate
597 #ifdef RAWDEBUG
598                         raw_test_pass(0xee07);
599 #endif
600 #ifdef RAWUSEIO
601                         totalexetime = raw_get_cycle();
602 #else
603                         raw_test_pass(0xbbbbbbbb);
604                         raw_test_pass(raw_get_cycle());
605 #endif
606                         // profile mode, send msgs to other cores to request pouring
607                             // out progiling data
608 #ifdef RAWPROFILE
609 #ifdef INTERRUPT
610                             // reopen gdn_avail interrupts
611                         raw_user_interrupts_on();
612 #endif
613                         for(i = 1; i < NUMCORES; ++i) {
614                               transProfileRequestMsg(i);
615                         }
616                             // pour profiling data on startup core
617                         outputProfileData();
618                         while(true) {
619 #ifdef INTERRUPT
620                               raw_user_interrupts_off();
621 #endif
622                               profilestatus[corenum] = 0;
623                           // check the status of all cores
624                               allStall = true;
625 #ifdef RAWDEBUG
626                               raw_test_pass_reg(NUMCORES);
627 #endif  
628                           for(i = 0; i < NUMCORES; ++i) {
629 #ifdef RAWDEBUG
630                                         raw_test_pass(0xe000 + profilestatus[i]);
631 #endif
632                                         if(profilestatus[i] != 0) {
633                                           allStall = false;
634                                           break;
635                                         }
636                                   }
637                                   if(!allStall) {
638                                         int halt = 100;
639 #ifdef INTERRUPT
640                                         raw_user_interrupts_on();
641 #endif
642                                         while(halt--) {
643                                         }
644                                   } else {
645                                           break;
646                                   }
647                                 }
648 #endif
649                             raw_test_done(1);                                   // All done.
650                           } else {
651                                   // still some objects on the fly on the network
652                                   // reset the waitconfirm and numconfirm
653                                   waitconfirm = false;
654                                   numconfirm = 0;
655                           }
656                         }
657                 }
658 #ifdef INTERRUPT
659                 raw_user_interrupts_on();
660 #endif
661           }
662    } else {
663         if(!sendStall) {
664 #ifdef RAWDEBUG
665           raw_test_pass(0xee08);
666 #endif
667 #ifdef RAWPROFILE
668           if(!stall) {
669 #endif
670           if(isfirst) {
671             // wait for some time
672             int halt = 10000;
673 #ifdef RAWDEBUG
674             raw_test_pass(0xee09);
675 #endif
676             while(halt--) {
677             }
678             isfirst = false;
679           } else {
680             // send StallMsg to startup core
681 #ifdef RAWDEBUG
682             raw_test_pass(0xee0a);
683 #endif
684             sendStall = transStallMsg(STARTUPCORE);
685             isfirst = true;
686                 busystatus = false;
687           }
688 #ifdef RAWPROFILE
689         }
690 #endif
691         } else {
692           isfirst = true;
693           busystatus = false;
694 #ifdef RAWDEBUG
695           raw_test_pass(0xee0b);
696 #endif
697         }
698       }
699     }
700   }
701   } // right-bracket for if-else of line 380
702 #elif defined THREADSIMULATE
703   /* Start executing the tasks */
704   executetasks();
705
706   int i = 0;
707   // check if there are new objects coming
708   bool sendStall = false;
709
710   int numofcore = pthread_getspecific(key);
711   while(true) {
712     switch(receiveObject()) {
713     case 0: {
714       //printf("[run, %d] receive an object\n", numofcore);
715       sendStall = false;
716       // received an object
717       // check if there are new active tasks can be executed
718       executetasks();
719       break;
720     }
721
722     case 1: {
723       //printf("[run, %d] no msg\n", numofcore);
724       // no msg received
725       if(STARTUPCORE == numofcore) {
726         corestatus[numofcore] = 0;
727         // check the status of all cores
728         bool allStall = true;
729         for(i = 0; i < NUMCORES; ++i) {
730           if(corestatus[i] != 0) {
731             allStall = false;
732             break;
733           }
734         }
735         if(allStall) {
736           // check if the sum of send objs and receive obj are the same
737           // yes->terminate
738           // no->go on executing
739           int sumsendobj = 0;
740           for(i = 0; i < NUMCORES; ++i) {
741             sumsendobj += numsendobjs[i];
742           }
743           for(i = 0; i < NUMCORES; ++i) {
744             sumsendobj -= numreceiveobjs[i];
745           }
746           if(0 == sumsendobj) {
747             // terminate
748
749             // release all locks
750             int rc_tbl = pthread_rwlock_wrlock(&rwlock_tbl);
751             printf("[run, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc_tbl, strerror(rc_tbl));
752             struct RuntimeIterator* it_lock = RuntimeHashcreateiterator(locktbl);
753             while(0 != RunhasNext(it_lock)) {
754               int key = Runkey(it_lock);
755               pthread_rwlock_t* rwlock_obj = (pthread_rwlock_t*)Runnext(it_lock);
756               int rc_des = pthread_rwlock_destroy(rwlock_obj);
757               printf("[run, %d] destroy the rwlock for object: %d error: \n", numofcore, key, strerror(rc_des));
758               RUNFREE(rwlock_obj);
759             }
760             freeRuntimeHash(locktbl);
761             locktbl = NULL;
762             RUNFREE(it_lock);
763
764             // destroy all message queues
765             char * pathhead = "/msgqueue_";
766             int targetlen = strlen(pathhead);
767             for(i = 0; i < NUMCORES; ++i) {
768               char corenumstr[3];
769               int sourcelen = 0;
770               if(i < 10) {
771                 corenumstr[0] = i + '0';
772                 corenumstr[1] = '\0';
773                 sourcelen = 1;
774               } else if(i < 100) {
775                 corenumstr[1] = i %10 + '0';
776                 corenumstr[0] = (i / 10) + '0';
777                 corenumstr[2] = '\0';
778                 sourcelen = 2;
779               } else {
780                 printf("Error: i >= 100\n");
781                 fflush(stdout);
782                 exit(-1);
783               }
784               char path[targetlen + sourcelen + 1];
785               strcpy(path, pathhead);
786               strncat(path, corenumstr, sourcelen);
787               mq_unlink(path);
788             }
789
790             printf("[run, %d] terminate!\n", numofcore);
791             fflush(stdout);
792             exit(0);
793           }
794         }
795       } else {
796         if(!sendStall) {
797           // send StallMsg to startup core
798           sendStall = transStallMsg(STARTUPCORE);
799         }
800       }
801       break;
802     }
803
804     case 2: {
805       printf("[run, %d] receive a stall msg\n", numofcore);
806       // receive a Stall Msg, do nothing
807       assert(STARTUPCORE == numofcore);                                     // only startup core can receive such msg
808       sendStall = false;
809       break;
810     }
811
812     default: {
813       printf("[run, %d] Error: invalid message type.\n", numofcore);
814       fflush(stdout);
815       exit(-1);
816       break;
817     }
818     }
819   }
820 #endif
821 }
822
823 void createstartupobject(int argc, char ** argv) {
824   int i;
825
826   /* Allocate startup object     */
827 #ifdef PRECISE_GC
828   struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
829   struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
830 #else
831   struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
832   struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
833 #endif
834   /* Build array of strings */
835   startupobject->___parameters___=stringarray;
836   for(i=1; i<argc; i++) {
837     int length=strlen(argv[i]);
838 #ifdef PRECISE_GC
839     struct ___String___ *newstring=NewString(NULL, argv[i],length);
840 #else
841     struct ___String___ *newstring=NewString(argv[i],length);
842 #endif
843     ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=newstring;
844   }
845
846   startupobject->isolate = 1;
847   startupobject->version = 0;
848   startupobject->lock = NULL;
849
850   /* Set initialized flag for startup object */
851   flagorandinit(startupobject,1,0xFFFFFFFF);
852   enqueueObject(startupobject, NULL, 0);
853 #ifdef RAWCACHEFLUSH
854   raw_flush_entire_cache();
855 #endif
856 }
857
858 int hashCodetpd(struct taskparamdescriptor *ftd) {
859   int hash=(int)ftd->task;
860   int i;
861   for(i=0; i<ftd->numParameters; i++) {
862     hash^=(int)ftd->parameterArray[i];
863   }
864   return hash;
865 }
866
867 int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
868   int i;
869   if (ftd1->task!=ftd2->task)
870     return 0;
871   for(i=0; i<ftd1->numParameters; i++)
872     if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
873       return 0;
874   return 1;
875 }
876
877 /* This function sets a tag. */
878 #ifdef PRECISE_GC
879 void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
880 #else
881 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
882 #endif
883   struct ArrayObject * ao=NULL;
884   struct ___Object___ * tagptr=obj->___tags___;
885   if (tagptr==NULL) {
886     obj->___tags___=(struct ___Object___ *)tagd;
887   } else {
888     /* Have to check if it is already set */
889     if (tagptr->type==TAGTYPE) {
890       struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
891       if (td==tagd) {
892         return;
893       }
894 #ifdef PRECISE_GC
895       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
896       struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
897       obj=(struct ___Object___ *)ptrarray[2];
898       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
899       td=(struct ___TagDescriptor___ *) obj->___tags___;
900 #else
901       ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
902 #endif
903       ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
904       ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
905       obj->___tags___=(struct ___Object___ *) ao;
906       ao->___cachedCode___=2;
907     } else {
908       /* Array Case */
909       int i;
910       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
911       for(i=0; i<ao->___cachedCode___; i++) {
912         struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
913         if (td==tagd) {
914           return;
915         }
916       }
917       if (ao->___cachedCode___<ao->___length___) {
918         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
919         ao->___cachedCode___++;
920       } else {
921 #ifdef PRECISE_GC
922         int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
923         struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
924         obj=(struct ___Object___ *)ptrarray[2];
925         tagd=(struct ___TagDescriptor___ *) ptrarray[3];
926         ao=(struct ArrayObject *)obj->___tags___;
927 #else
928         struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
929 #endif
930         aonew->___cachedCode___=ao->___length___+1;
931         for(i=0; i<ao->___length___; i++) {
932           ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
933         }
934         ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
935       }
936     }
937   }
938
939   {
940     struct ___Object___ * tagset=tagd->flagptr;
941     if(tagset==NULL) {
942       tagd->flagptr=obj;
943     } else if (tagset->type!=OBJECTARRAYTYPE) {
944 #ifdef PRECISE_GC
945       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
946       struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
947       obj=(struct ___Object___ *)ptrarray[2];
948       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
949 #else
950       struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
951 #endif
952       ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
953       ARRAYSET(ao, struct ___Object___ *, 1, obj);
954       ao->___cachedCode___=2;
955       tagd->flagptr=(struct ___Object___ *)ao;
956     } else {
957       struct ArrayObject *ao=(struct ArrayObject *) tagset;
958       if (ao->___cachedCode___<ao->___length___) {
959         ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
960       } else {
961         int i;
962 #ifdef PRECISE_GC
963         int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
964         struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
965         obj=(struct ___Object___ *)ptrarray[2];
966         tagd=(struct ___TagDescriptor___ *)ptrarray[3];
967         ao=(struct ArrayObject *)tagd->flagptr;
968 #else
969         struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
970 #endif
971         aonew->___cachedCode___=ao->___cachedCode___+1;
972         for(i=0; i<ao->___length___; i++) {
973           ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
974         }
975         ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
976         tagd->flagptr=(struct ___Object___ *) aonew;
977       }
978     }
979   }
980 }
981
982 /* This function clears a tag. */
983 #ifdef PRECISE_GC
984 void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
985 #else
986 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
987 #endif
988   /* We'll assume that tag is alway there.
989      Need to statically check for this of course. */
990   struct ___Object___ * tagptr=obj->___tags___;
991
992   if (tagptr->type==TAGTYPE) {
993     if ((struct ___TagDescriptor___ *)tagptr==tagd)
994       obj->___tags___=NULL;
995     else
996 #ifndef RAW
997       printf("ERROR 1 in tagclear\n");
998 #endif
999       ;
1000   } else {
1001     struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1002     int i;
1003     for(i=0; i<ao->___cachedCode___; i++) {
1004       struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1005       if (td==tagd) {
1006         ao->___cachedCode___--;
1007         if (i<ao->___cachedCode___)
1008           ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1009         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1010         if (ao->___cachedCode___==0)
1011           obj->___tags___=NULL;
1012         goto PROCESSCLEAR;
1013       }
1014     }
1015 #ifndef RAW
1016     printf("ERROR 2 in tagclear\n");
1017 #endif
1018     ;
1019   }
1020 PROCESSCLEAR:
1021   {
1022     struct ___Object___ *tagset=tagd->flagptr;
1023     if (tagset->type!=OBJECTARRAYTYPE) {
1024       if (tagset==obj)
1025         tagd->flagptr=NULL;
1026       else
1027 #ifndef RAW
1028         printf("ERROR 3 in tagclear\n");
1029 #endif
1030         ;
1031     } else {
1032       struct ArrayObject *ao=(struct ArrayObject *) tagset;
1033       int i;
1034       for(i=0; i<ao->___cachedCode___; i++) {
1035         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1036         if (tobj==obj) {
1037           ao->___cachedCode___--;
1038           if (i<ao->___cachedCode___)
1039             ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1040           ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1041           if (ao->___cachedCode___==0)
1042             tagd->flagptr=NULL;
1043           goto ENDCLEAR;
1044         }
1045       }
1046 #ifndef RAW
1047       printf("ERROR 4 in tagclear\n");
1048 #endif
1049     }
1050   }
1051 ENDCLEAR:
1052   return;
1053 }
1054
1055 /* This function allocates a new tag. */
1056 #ifdef PRECISE_GC
1057 struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
1058   struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[TAGTYPE]);
1059 #else
1060 struct ___TagDescriptor___ * allocate_tag(int index) {
1061   struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1062 #endif
1063   v->type=TAGTYPE;
1064   v->flag=index;
1065   return v;
1066 }
1067
1068
1069
1070 /* This function updates the flag for object ptr.  It or's the flag
1071    with the or mask and and's it with the andmask. */
1072
1073 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** queues, int length, bool isnew);
1074
1075 int flagcomp(const int *val1, const int *val2) {
1076   return (*val1)-(*val2);
1077 }
1078
1079 void flagorand(void * ptr, int ormask, int andmask, struct parameterwrapper ** queues, int length) {
1080   {
1081     int oldflag=((int *)ptr)[1];
1082     int flag=ormask|oldflag;
1083     flag&=andmask;
1084     flagbody(ptr, flag, queues, length, false);
1085   }
1086 }
1087
1088 bool intflagorand(void * ptr, int ormask, int andmask) {
1089   {
1090     int oldflag=((int *)ptr)[1];
1091     int flag=ormask|oldflag;
1092     flag&=andmask;
1093     if (flag==oldflag)   /* Don't do anything */
1094       return false;
1095     else {
1096       flagbody(ptr, flag, NULL, 0, false);
1097       return true;
1098     }
1099   }
1100 }
1101
1102 void flagorandinit(void * ptr, int ormask, int andmask) {
1103   int oldflag=((int *)ptr)[1];
1104   int flag=ormask|oldflag;
1105   flag&=andmask;
1106   flagbody(ptr,flag,NULL,0,true);
1107 }
1108
1109 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqueues, int vlength, bool isnew) {
1110   struct parameterwrapper * flagptr = NULL;
1111   int i = 0;
1112   struct parameterwrapper ** queues = vqueues;
1113   int length = vlength;
1114   int next;
1115   int UNUSED, UNUSED2;
1116   int * enterflags = NULL;
1117   if((!isnew) && (queues == NULL)) {
1118 #ifdef THREADSIMULATE
1119     int numofcore = pthread_getspecific(key);
1120     queues = objectqueues[numofcore][ptr->type];
1121     length = numqueues[numofcore][ptr->type];
1122 #else
1123 #ifdef RAW
1124     if(corenum < NUMCORES) {
1125 #endif
1126     queues = objectqueues[corenum][ptr->type];
1127     length = numqueues[corenum][ptr->type];
1128 #ifdef RAW
1129   } else {
1130     return;
1131   }
1132 #endif
1133 #endif
1134   }
1135   ptr->flag=flag;
1136
1137   /*Remove object from all queues */
1138   for(i = 0; i < length; ++i) {
1139     flagptr = queues[i];
1140     ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
1141     ObjectHashremove(flagptr->objectset, (int)ptr);
1142     if (enterflags!=NULL)
1143       RUNFREE(enterflags);
1144   }
1145 }
1146
1147 void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
1148   struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1149
1150   {
1151     struct QueueItem *tmpptr;
1152     struct parameterwrapper * parameter=NULL;
1153     int j;
1154     int i;
1155     struct parameterwrapper * prevptr=NULL;
1156     struct ___Object___ *tagptr=NULL;
1157     struct parameterwrapper ** queues = vqueues;
1158     int length = vlength;
1159 #ifdef RAW
1160     if(corenum > NUMCORES - 1) {
1161       return;
1162     }
1163 #endif
1164     if(queues == NULL) {
1165 #ifdef THREADSIMULATE
1166       int numofcore = pthread_getspecific(key);
1167       queues = objectqueues[numofcore][ptr->type];
1168       length = numqueues[numofcore][ptr->type];
1169 #else
1170       queues = objectqueues[corenum][ptr->type];
1171       length = numqueues[corenum][ptr->type];
1172 #endif
1173     }
1174     tagptr=ptr->___tags___;
1175
1176     /* Outer loop iterates through all parameter queues an object of
1177        this type could be in.  */
1178     for(j = 0; j < length; ++j) {
1179       parameter = queues[j];
1180       /* Check tags */
1181       if (parameter->numbertags>0) {
1182         if (tagptr==NULL)
1183           goto nextloop; //that means the object has no tag but that param needs tag
1184         else if(tagptr->type==TAGTYPE) { //one tag
1185           struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1186           for(i=0; i<parameter->numbertags; i++) {
1187             //slotid is parameter->tagarray[2*i];
1188             int tagid=parameter->tagarray[2*i+1];
1189             if (tagid!=tagptr->flag)
1190               goto nextloop; /*We don't have this tag */
1191           }
1192         } else { //multiple tags
1193           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1194           for(i=0; i<parameter->numbertags; i++) {
1195             //slotid is parameter->tagarray[2*i];
1196             int tagid=parameter->tagarray[2*i+1];
1197             int j;
1198             for(j=0; j<ao->___cachedCode___; j++) {
1199               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1200                 goto foundtag;
1201             }
1202             goto nextloop;
1203 foundtag:
1204             ;
1205           }
1206         }
1207       }
1208
1209       /* Check flags */
1210       for(i=0; i<parameter->numberofterms; i++) {
1211         int andmask=parameter->intarray[i*2];
1212         int checkmask=parameter->intarray[i*2+1];
1213         if ((ptr->flag&andmask)==checkmask) {
1214           enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1215           prevptr=parameter;
1216           break;
1217         }
1218       }
1219 nextloop:
1220       ;
1221     }
1222   }
1223 }
1224
1225 #ifdef RAW
1226 void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
1227   struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1228
1229   {
1230     struct QueueItem *tmpptr;
1231     struct parameterwrapper * parameter=NULL;
1232     int j;
1233     int i;
1234     struct parameterwrapper * prevptr=NULL;
1235     struct ___Object___ *tagptr=NULL;
1236     struct parameterwrapper ** queues = vqueues;
1237     int length = vlength;
1238 #ifdef RAW
1239     if(corenum > NUMCORES - 1) {
1240       return;
1241     }
1242 #endif
1243     if(queues == NULL) {
1244 #ifdef THREADSIMULATE
1245       int numofcore = pthread_getspecific(key);
1246       queues = objectqueues[numofcore][ptr->type];
1247       length = numqueues[numofcore][ptr->type];
1248 #else
1249       queues = objectqueues[corenum][ptr->type];
1250       length = numqueues[corenum][ptr->type];
1251 #endif
1252     }
1253     tagptr=ptr->___tags___;
1254
1255     /* Outer loop iterates through all parameter queues an object of
1256        this type could be in.  */
1257     for(j = 0; j < length; ++j) {
1258       parameter = queues[j];
1259       /* Check tags */
1260       if (parameter->numbertags>0) {
1261         if (tagptr==NULL)
1262           goto nextloop; //that means the object has no tag but that param needs tag
1263         else if(tagptr->type==TAGTYPE) { //one tag
1264           struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1265           for(i=0; i<parameter->numbertags; i++) {
1266             //slotid is parameter->tagarray[2*i];
1267             int tagid=parameter->tagarray[2*i+1];
1268             if (tagid!=tagptr->flag) {
1269               goto nextloop; /*We don't have this tag */
1270             }
1271           }
1272         } else { //multiple tags
1273           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1274           for(i=0; i<parameter->numbertags; i++) {
1275             //slotid is parameter->tagarray[2*i];
1276             int tagid=parameter->tagarray[2*i+1];
1277             int j;
1278             for(j=0; j<ao->___cachedCode___; j++) {
1279               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag) {
1280                 goto foundtag;
1281               }
1282             }
1283             goto nextloop;
1284 foundtag:
1285             ;
1286           }
1287         }
1288       }
1289
1290       /* Check flags */
1291       for(i=0; i<parameter->numberofterms; i++) {
1292         int andmask=parameter->intarray[i*2];
1293         int checkmask=parameter->intarray[i*2+1];
1294         if ((ptr->flag&andmask)==checkmask) {
1295           enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1296           prevptr=parameter;
1297           break;
1298         }
1299       }
1300 nextloop:
1301       ;
1302     }
1303   }
1304 }
1305
1306 // helper function to compute the coordinates of a core from the core number
1307 void calCoords(int core_num, int* coordY, int* coordX) {
1308   *coordX = core_num % raw_get_array_size_x();
1309   *coordY = core_num / raw_get_array_size_x();
1310 }
1311 #endif
1312
1313 int * getAliasLock(void ** ptrs, int length, struct RuntimeHash * tbl) {
1314         if(length == 0) {
1315                 return (int*)(RUNMALLOC(sizeof(int)));
1316         } else {
1317                 int i = 0;
1318                 int locks[length];
1319                 int locklen = 0;
1320                 bool redirect = false;
1321                 int redirectlock = 0;
1322                 for(; i < length; i++) {
1323                         struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1324                         int lock = 0;
1325                         int j = 0;
1326                         if(ptr->lock == NULL) {
1327                                 lock = (int)(ptr);
1328                         } else {
1329                                 lock = (int)(ptr->lock);
1330                         }
1331                         if(redirect) {
1332                                 if(lock != redirectlock) {
1333                                         RuntimeHashadd(tbl, lock, redirectlock);
1334                                 }
1335                         } else {
1336                                 if(RuntimeHashcontainskey(tbl, lock)) {
1337                                         // already redirected
1338                                         redirect = true;
1339                                         RuntimeHashget(tbl, lock, &redirectlock);
1340                                         for(; j < locklen; j++) {
1341                                                 if(locks[j] != redirectlock) {
1342                                                         RuntimeHashadd(tbl, locks[j], redirectlock);
1343                                                 }
1344                                         }
1345                                 } else {
1346                                         bool insert = true;
1347                                         for(j = 0; j < locklen; j++) {
1348                                                 if(locks[j] == lock) {
1349                                                         insert = false;
1350                                                         break;
1351                                                 } else if(locks[j] > lock) {
1352                                                         break;
1353                                                 }
1354                                         }
1355                                         if(insert) {
1356                                                 int h = locklen;
1357                                                 for(; h > j; h--) {
1358                                                         locks[h] = locks[h-1];
1359                                                 }       
1360                                                 locks[j] = lock;
1361                                                 locklen++;
1362                                         }
1363                                 }
1364                         }
1365                 }
1366                 if(redirect) {
1367                         return (int *)redirectlock;
1368                 } else {
1369                         return (int *)(locks[0]);
1370                 }
1371         }
1372 }
1373
1374 void addAliasLock(void * ptr, int lock) {
1375   struct ___Object___ * obj = (struct ___Object___ *)ptr;
1376   if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1377     // originally no alias lock associated or have a different alias lock
1378     // flush it as the new one
1379     obj->lock = (int *)lock;
1380   }
1381 }
1382
1383 /* Message format for RAW version:
1384  *      type + Msgbody
1385  * type: 0 -- transfer object
1386  *       1 -- transfer stall msg
1387  *       2 -- lock request
1388  *       3 -- lock grount
1389  *       4 -- lock deny
1390  *       5 -- lock release
1391  *       // add for profile info
1392  *       6 -- transfer profile output msg
1393  *       7 -- transfer profile output finish msg
1394  *       // add for alias lock strategy
1395  *       8 -- redirect lock request
1396  *       9 -- lock grant with redirect info
1397  *       a -- lock deny with redirect info
1398  *       b -- lock release with redirect info
1399  *       c -- status confirm request
1400  *       d -- status report msg
1401  *
1402  * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
1403  * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
1404  * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
1405  *          3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
1406  *          8 + lock type + obj pointer +  redirect lock + root request core + request core (size is always 6 * sizeof(int))
1407  *          9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
1408  *          b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
1409  *          lock type: 0 -- read; 1 -- write
1410  * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
1411  *             7 + corenum (size is always 2 * sizeof(int))
1412  * StatusMsg: c (size is always 1 * sizeof(int))
1413  *            d + status + corenum (size is always 3 * sizeof(int))
1414  *            status: 0 -- stall; 1 -- busy
1415  */
1416
1417 // transfer an object to targetcore
1418 // format: object
1419 void transferObject(struct transObjInfo * transObj) {
1420   void * obj = transObj->objptr;
1421   int type=((int *)obj)[0];
1422   int size=classsize[type];
1423   int targetcore = transObj->targetcore;
1424
1425 #ifdef RAW
1426   unsigned msgHdr;
1427   int self_y, self_x, target_y, target_x;
1428   // for 32 bit machine, the size of fixed part is always 3 words
1429   int msgsize = 3 + transObj->length * 2;
1430   int i = 0;
1431
1432   struct ___Object___ * newobj = (struct ___Object___ *)obj;
1433
1434   calCoords(corenum, &self_y, &self_x);
1435   calCoords(targetcore, &target_y, &target_x);
1436   isMsgSending = true;
1437   // Build the message header
1438   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
1439                              self_y, self_x,
1440                              target_y, target_x);
1441   // start sending msg, set sand msg flag
1442   //isMsgSending = true;
1443   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
1444 #ifdef RAWDEBUG
1445   raw_test_pass(0xbbbb);
1446   raw_test_pass(0xb000 + targetcore);       // targetcore
1447 #endif
1448   gdn_send(0);
1449 #ifdef RAWDEBUG
1450   raw_test_pass(0);
1451 #endif
1452   gdn_send(msgsize);
1453 #ifdef RAWDEBUG
1454   raw_test_pass_reg(msgsize);
1455 #endif
1456   gdn_send((int)obj);
1457 #ifdef RAWDEBUG
1458   raw_test_pass_reg(obj);
1459 #endif
1460   for(i = 0; i < transObj->length; ++i) {
1461     int taskindex = transObj->queues[2*i];
1462     int paramindex = transObj->queues[2*i+1];
1463     gdn_send(taskindex);
1464 #ifdef RAWDEBUG
1465     raw_test_pass_reg(taskindex);
1466 #endif
1467     gdn_send(paramindex);
1468 #ifdef RAWDEBUG
1469     raw_test_pass_reg(paramindex);
1470 #endif
1471   }
1472 #ifdef RAWDEBUG
1473   raw_test_pass(0xffff);
1474 #endif
1475   ++(self_numsendobjs);
1476   // end of sending this msg, set sand msg flag false
1477   isMsgSending = false;
1478   // check if there are pending msgs
1479   while(isMsgHanging) {
1480     // get the msg from outmsgdata[]
1481     // length + target + msg
1482     outmsgleft = outmsgdata[outmsgindex++];
1483     targetcore = outmsgdata[outmsgindex++];
1484     calCoords(targetcore, &target_y, &target_x);
1485         isMsgSending = true;
1486     // Build the message header
1487     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
1488                                self_y, self_x,
1489                                target_y, target_x);
1490     //isMsgSending = true;
1491     gdn_send(msgHdr);                           
1492 #ifdef RAWDEBUG
1493     raw_test_pass(0xbbbb);
1494     raw_test_pass(0xb000 + targetcore);             // targetcore
1495 #endif
1496     while(outmsgleft-- > 0) {
1497       gdn_send(outmsgdata[outmsgindex++]);
1498 #ifdef RAWDEBUG
1499       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
1500 #endif
1501     }
1502 #ifdef RAWDEBUG
1503     raw_test_pass(0xffff);
1504 #endif
1505     isMsgSending = false;
1506 #ifdef INTERRUPT
1507     raw_user_interrupts_off();
1508 #endif
1509     // check if there are still msg hanging
1510     if(outmsgindex == outmsglast) {
1511       // no more msgs
1512       outmsgindex = outmsglast = 0;
1513       isMsgHanging = false;
1514     }
1515 #ifdef INTERRUPT
1516     raw_user_interrupts_on();
1517 #endif
1518   }
1519 #elif defined THREADSIMULATE
1520   int numofcore = pthread_getspecific(key);
1521
1522   // use POSIX message queue to transfer objects between cores
1523   mqd_t mqdnum;
1524   char corenumstr[3];
1525   int sourcelen = 0;
1526   if(targetcore < 10) {
1527     corenumstr[0] = targetcore + '0';
1528     corenumstr[1] = '\0';
1529     sourcelen = 1;
1530   } else if(targetcore < 100) {
1531     corenumstr[1] = targetcore % 10 + '0';
1532     corenumstr[0] = (targetcore / 10) + '0';
1533     corenumstr[2] = '\0';
1534     sourcelen = 2;
1535   } else {
1536     printf("Error: targetcore >= 100\n");
1537     fflush(stdout);
1538     exit(-1);
1539   }
1540   char * pathhead = "/msgqueue_";
1541   int targetlen = strlen(pathhead);
1542   char path[targetlen + sourcelen + 1];
1543   strcpy(path, pathhead);
1544   strncat(path, corenumstr, sourcelen);
1545   int oflags = O_WRONLY|O_NONBLOCK;
1546   int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
1547   mqdnum = mq_open(path, oflags, omodes, NULL);
1548   if(mqdnum==-1) {
1549     printf("[transferObject, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
1550     fflush(stdout);
1551     exit(-1);
1552   }
1553   struct transObjInfo * tmptransObj = RUNMALLOC(sizeof(struct transObjInfo));
1554   memcpy(tmptransObj, transObj, sizeof(struct transObjInfo));
1555   int * tmpqueue = RUNMALLOC(sizeof(int)*2*tmptransObj->length);
1556   memcpy(tmpqueue, tmptransObj->queues, sizeof(int)*2*tmptransObj->length);
1557   tmptransObj->queues = tmpqueue;
1558   struct ___Object___ * newobj = RUNMALLOC(sizeof(struct ___Object___));
1559   newobj->type = ((struct ___Object___ *)obj)->type;
1560   newobj->original = (struct ___Object___ *)tmptransObj;
1561   int ret;
1562   do {
1563     ret=mq_send(mqdnum, (void *)newobj, sizeof(struct ___Object___), 0);             // send the object into the queue
1564     if(ret != 0) {
1565       printf("[transferObject, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
1566     }
1567   } while(ret!=0);
1568   RUNFREE(newobj);
1569   if(numofcore == STARTUPCORE) {
1570     ++numsendobjs[numofcore];
1571   } else {
1572     ++(thread_data_array[numofcore].numsendobjs);
1573   }
1574   printf("[transferObject, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
1575 #endif
1576 }
1577
1578 // send terminate message to targetcore
1579 // format: -1
1580 bool transStallMsg(int targetcore) {
1581 #ifdef RAW
1582   unsigned msgHdr;
1583   int self_y, self_x, target_y, target_x;
1584   // for 32 bit machine, the size is always 4 words
1585   //int msgsize = sizeof(int) * 4;
1586   int msgsize = 4;
1587
1588   calCoords(corenum, &self_y, &self_x);
1589   calCoords(targetcore, &target_y, &target_x);
1590   isMsgSending = true;
1591   // Build the message header
1592   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
1593                              self_y, self_x,
1594                              target_y, target_x);
1595   // start sending msgs, set msg sending flag
1596   //isMsgSending = true;
1597   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
1598 #ifdef RAWDEBUG
1599   raw_test_pass(0xbbbb);
1600   raw_test_pass(0xb000 + targetcore);       // targetcore
1601 #endif
1602   gdn_send(1);
1603 #ifdef RAWDEBUG
1604   raw_test_pass(1);
1605 #endif
1606   gdn_send(corenum);
1607 #ifdef RAWDEBUG
1608   raw_test_pass_reg(corenum);
1609 #endif
1610   gdn_send(self_numsendobjs);
1611 #ifdef RAWDEBUG
1612   raw_test_pass_reg(self_numsendobjs);
1613 #endif
1614   gdn_send(self_numreceiveobjs);
1615 #ifdef RAWDEBUG
1616   raw_test_pass_reg(self_numreceiveobjs);
1617   raw_test_pass(0xffff);
1618 #endif
1619   // end of sending this msg, set sand msg flag false
1620   isMsgSending = false;
1621   // check if there are pending msgs
1622   while(isMsgHanging) {
1623     // get the msg from outmsgdata[]
1624     // length + target + msg
1625     outmsgleft = outmsgdata[outmsgindex++];
1626     targetcore = outmsgdata[outmsgindex++];
1627     calCoords(targetcore, &target_y, &target_x);
1628         isMsgSending = true;
1629     // Build the message header
1630     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
1631                                self_y, self_x,
1632                                target_y, target_x);
1633         //isMsgSending = true;
1634     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
1635 #ifdef RAWDEBUG
1636     raw_test_pass(0xbbbb);
1637     raw_test_pass(0xb000 + targetcore);             // targetcore
1638 #endif
1639     while(outmsgleft-- > 0) {
1640       gdn_send(outmsgdata[outmsgindex++]);
1641 #ifdef RAWDEBUG
1642       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
1643 #endif
1644     }
1645 #ifdef RAWDEBUG
1646     raw_test_pass(0xffff);
1647 #endif
1648     isMsgSending = false;
1649 #ifdef INTERRUPT
1650     raw_user_interrupts_off();
1651 #endif
1652     // check if there are still msg hanging
1653     if(outmsgindex == outmsglast) {
1654       // no more msgs
1655       outmsgindex = outmsglast = 0;
1656       isMsgHanging = false;
1657     }
1658 #ifdef INTERRUPT
1659     raw_user_interrupts_on();
1660 #endif
1661   }
1662   return true;
1663 #elif defined THREADSIMULATE
1664   struct ___Object___ *newobj = RUNMALLOC(sizeof(struct ___Object___));
1665   // use the first four int field to hold msgtype/corenum/sendobj/receiveobj
1666   newobj->type = -1;
1667   int numofcore = pthread_getspecific(key);
1668   newobj->flag = numofcore;
1669   newobj->___cachedHash___ = thread_data_array[numofcore].numsendobjs;
1670   newobj->___cachedCode___ = thread_data_array[numofcore].numreceiveobjs;
1671
1672   // use POSIX message queue to send stall msg to startup core
1673   assert(targetcore == STARTUPCORE);
1674   mqd_t mqdnum;
1675   char corenumstr[3];
1676   int sourcelen = 0;
1677   if(targetcore < 10) {
1678     corenumstr[0] = targetcore + '0';
1679     corenumstr[1] = '\0';
1680     sourcelen = 1;
1681   } else if(targetcore < 100) {
1682     corenumstr[1] = targetcore % 10 + '0';
1683     corenumstr[0] = (targetcore / 10) + '0';
1684     corenumstr[2] = '\0';
1685     sourcelen = 2;
1686   } else {
1687     printf("Error: targetcore >= 100\n");
1688     fflush(stdout);
1689     exit(-1);
1690   }
1691   char * pathhead = "/msgqueue_";
1692   int targetlen = strlen(pathhead);
1693   char path[targetlen + sourcelen + 1];
1694   strcpy(path, pathhead);
1695   strncat(path, corenumstr, sourcelen);
1696   int oflags = O_WRONLY|O_NONBLOCK;
1697   int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
1698   mqdnum = mq_open(path, oflags, omodes, NULL);
1699   if(mqdnum==-1) {
1700     printf("[transStallMsg, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
1701     fflush(stdout);
1702     exit(-1);
1703   }
1704   int ret;
1705   ret=mq_send(mqdnum, (void *)newobj, sizeof(struct ___Object___), 0);       // send the object into the queue
1706   if(ret != 0) {
1707     printf("[transStallMsg, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
1708     RUNFREE(newobj);
1709     return false;
1710   } else {
1711     printf("[transStallMsg, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
1712     printf("<transStallMsg> to %s index: %d, sendobjs: %d, receiveobjs: %d\n", path, newobj->flag, newobj->___cachedHash___, newobj->___cachedCode___);
1713     RUNFREE(newobj);
1714     return true;
1715   }
1716 #endif
1717 }
1718
1719 void transStatusConfirmMsg(int targetcore) {
1720 #ifdef RAW
1721   unsigned msgHdr;
1722   int self_y, self_x, target_y, target_x;
1723   // for 32 bit machine, the size is always 1 words
1724   //int msgsize = sizeof(int) * 1;
1725   int msgsize = 1;
1726
1727   calCoords(corenum, &self_y, &self_x);
1728   calCoords(targetcore, &target_y, &target_x);
1729   isMsgSending = true;
1730   // Build the message header
1731   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
1732                              self_y, self_x,
1733                              target_y, target_x);
1734   // start sending msgs, set msg sending flag
1735   //isMsgSending = true;
1736   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
1737 #ifdef RAWDEBUG
1738   raw_test_pass(0xbbbb);
1739   raw_test_pass(0xb000 + targetcore);       // targetcore
1740 #endif
1741   gdn_send(0xc);
1742 #ifdef RAWDEBUG
1743   raw_test_pass(0xc);
1744   raw_test_pass(0xffff);
1745 #endif
1746   // end of sending this msg, set sand msg flag false
1747   isMsgSending = false;
1748   // check if there are pending msgs
1749   while(isMsgHanging) {
1750     // get the msg from outmsgdata[]
1751     // length + target + msg
1752     outmsgleft = outmsgdata[outmsgindex++];
1753     targetcore = outmsgdata[outmsgindex++];
1754     calCoords(targetcore, &target_y, &target_x);
1755         isMsgSending = true;
1756     // Build the message header
1757     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
1758                                self_y, self_x,
1759                                target_y, target_x);
1760         //isMsgSending = true;
1761     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
1762 #ifdef RAWDEBUG
1763     raw_test_pass(0xbbbb);
1764     raw_test_pass(0xb000 + targetcore);             // targetcore
1765 #endif
1766     while(outmsgleft-- > 0) {
1767       gdn_send(outmsgdata[outmsgindex++]);
1768 #ifdef RAWDEBUG
1769       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
1770 #endif
1771     }
1772 #ifdef RAWDEBUG
1773     raw_test_pass(0xffff);
1774 #endif
1775     isMsgSending = false;
1776 #ifdef INTERRUPT
1777     raw_user_interrupts_off();
1778 #endif
1779     // check if there are still msg hanging
1780     if(outmsgindex == outmsglast) {
1781       // no more msgs
1782       outmsgindex = outmsglast = 0;
1783       isMsgHanging = false;
1784     }
1785 #ifdef INTERRUPT
1786     raw_user_interrupts_on();
1787 #endif
1788   }
1789 #elif defined THREADSIMULATE
1790 // TODO
1791 #endif
1792 }
1793
1794 #ifdef RAWPROFILE
1795 // send profile request message to targetcore
1796 // format: 6
1797 bool transProfileRequestMsg(int targetcore) {
1798   unsigned msgHdr;
1799   int self_y, self_x, target_y, target_x;
1800   // for 32 bit machine, the size is always 4 words
1801   int msgsize = 2;
1802
1803   calCoords(corenum, &self_y, &self_x);
1804   calCoords(targetcore, &target_y, &target_x);
1805   isMsgSending = true;
1806   // Build the message header
1807   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
1808                              self_y, self_x,
1809                              target_y, target_x);
1810   // start sending msgs, set msg sending flag
1811   //isMsgSending = true;
1812   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
1813 #ifdef RAWDEBUG
1814   raw_test_pass(0xbbbb);
1815   raw_test_pass(0xb000 + targetcore);       // targetcore
1816 #endif
1817   gdn_send(6);
1818 #ifdef RAWDEBUG
1819   raw_test_pass(6);
1820 #endif
1821   gdn_send(totalexetime);
1822 #ifdef RAWDEBUG
1823   raw_test_pass_reg(totalexetime);
1824   raw_test_pass(0xffff);
1825 #endif
1826   // end of sending this msg, set sand msg flag false
1827   isMsgSending = false;
1828   // check if there are pending msgs
1829   while(isMsgHanging) {
1830     // get the msg from outmsgdata[]
1831     // length + target + msg
1832     outmsgleft = outmsgdata[outmsgindex++];
1833     targetcore = outmsgdata[outmsgindex++];
1834     calCoords(targetcore, &target_y, &target_x);
1835         isMsgSending = true;
1836     // Build the message header
1837     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
1838                                self_y, self_x,
1839                                target_y, target_x);
1840         //isMsgSending = true;
1841     gdn_send(msgHdr);
1842 #ifdef RAWDEBUG
1843     raw_test_pass(0xbbbb);
1844     raw_test_pass(0xb000 + targetcore);             // targetcore
1845 #endif
1846     while(outmsgleft-- > 0) {
1847       gdn_send(outmsgdata[outmsgindex++]);
1848 #ifdef RAWDEBUG
1849       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
1850 #endif
1851     }
1852 #ifdef RAWDEBUG
1853     raw_test_pass(0xffff);
1854 #endif
1855     isMsgSending = false;
1856 #ifdef INTERRUPT
1857     raw_user_interrupts_off();
1858 #endif
1859     // check if there are still msg hanging
1860     if(outmsgindex == outmsglast) {
1861       // no more msgs
1862       outmsgindex = outmsglast = 0;
1863       isMsgHanging = false;
1864     }
1865 #ifdef INTERRUPT
1866     raw_user_interrupts_on();
1867 #endif
1868   }
1869   return true;
1870 }
1871
1872 // output the profiling data
1873 void outputProfileData() {
1874 #ifdef RAWUSEIO
1875   FILE * fp;
1876   char fn[50];
1877   int self_y, self_x;
1878   char c_y, c_x;
1879   int i;
1880   int totaltasktime = 0;
1881   int preprocessingtime = 0;
1882   int objqueuecheckingtime = 0;
1883   int postprocessingtime = 0;
1884   //int interruptiontime = 0;
1885   int other = 0;
1886   int averagetasktime = 0;
1887   int tasknum = 0;
1888
1889   for(i = 0; i < 50; i++) {
1890     fn[i] = 0;
1891   }
1892
1893   calCoords(corenum, &self_y, &self_x);
1894   c_y = (char)self_y + '0';
1895   c_x = (char)self_x + '0';
1896   strcat(fn, "profile_");
1897   strcat(fn, &c_x);
1898   strcat(fn, "_");
1899   strcat(fn, &c_y);
1900   strcat(fn, ".rst");
1901
1902   if((fp = fopen(fn, "w+")) == NULL) {
1903     fprintf(stderr, "fopen error\n");
1904     return;
1905   }
1906
1907   fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1908   // output task related info
1909   for(i = 0; i < taskInfoIndex; i++) {
1910     TaskInfo* tmpTInfo = taskInfoArray[i];
1911     int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1912     fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1913         // summarize new obj info
1914         if(tmpTInfo->newObjs != NULL) {
1915                 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1916                 struct RuntimeIterator * iter = NULL;
1917                 while(0 == isEmpty(tmpTInfo->newObjs)) {
1918                         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1919                         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1920                                 int num = 0;
1921                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1922                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1923                                 num++;
1924                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1925                         } else {
1926                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1927                         }
1928                         //fprintf(stderr, "new obj!\n");
1929                 }
1930
1931                 // output all new obj info
1932                 iter = RuntimeHashcreateiterator(nobjtbl);
1933                 while(RunhasNext(iter)) {
1934                         char * objtype = (char *)Runkey(iter);
1935                         int num = Runnext(iter);
1936                         fprintf(fp, ", %s, %d", objtype, num);
1937                 }
1938         }
1939         fprintf(fp, "\n");
1940     if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1941       preprocessingtime += duration;
1942     } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1943       postprocessingtime += duration;
1944     } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1945       objqueuecheckingtime += duration;
1946     } else {
1947       totaltasktime += duration;
1948       averagetasktime += duration;
1949       tasknum++;
1950     }
1951   }
1952
1953   if(taskInfoOverflow) {
1954     fprintf(stderr, "Caution: task info overflow!\n");
1955   }
1956
1957   other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1958   averagetasktime /= tasknum;
1959
1960   fprintf(fp, "\nTotal time: %d\n", totalexetime);
1961   fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1962   fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1963   fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1964   fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1965   fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1966
1967   fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1968
1969   fclose(fp);
1970 #else
1971   int i = 0;
1972   int j = 0;
1973
1974   raw_test_pass(0xdddd);
1975   // output task related info
1976   for(i= 0; i < taskInfoIndex; i++) {
1977     TaskInfo* tmpTInfo = taskInfoArray[i];
1978     char* tmpName = tmpTInfo->taskName;
1979     int nameLen = strlen(tmpName);
1980     raw_test_pass(0xddda);
1981     for(j = 0; j < nameLen; j++) {
1982       raw_test_pass_reg(tmpName[j]);
1983     }
1984     raw_test_pass(0xdddb);
1985     raw_test_pass_reg(tmpTInfo->startTime);
1986     raw_test_pass_reg(tmpTInfo->endTime);
1987         raw_test_pass_reg(tmpTInfo->exitIndex);
1988         if(tmpTInfo->newObjs != NULL) {
1989                 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1990                 struct RuntimeIterator * iter = NULL;
1991                 while(0 == isEmpty(tmpTInfo->newObjs)) {
1992                         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1993                         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1994                                 int num = 0;
1995                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1996                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1997                                 num++;
1998                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1999                         } else {
2000                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
2001                         }
2002                 }
2003
2004                 // ouput all new obj info
2005                 iter = RuntimeHashcreateiterator(nobjtbl);
2006                 while(RunhasNext(iter)) {
2007                         char * objtype = (char *)Runkey(iter);
2008                         int num = Runnext(iter);
2009                         int nameLen = strlen(objtype);
2010                         raw_test_pass(0xddda);
2011                         for(j = 0; j < nameLen; j++) {
2012                                 raw_test_pass_reg(objtype[j]);
2013                         }
2014                         raw_test_pass(0xdddb);
2015                         raw_test_pass_reg(num);
2016                 }
2017         }
2018     raw_test_pass(0xdddc);
2019   }
2020
2021   if(taskInfoOverflow) {
2022     raw_test_pass(0xefee);
2023   }
2024
2025   // output interrupt related info
2026   /*for(i = 0; i < interruptInfoIndex; i++) {
2027        InterruptInfo* tmpIInfo = interruptInfoArray[i];
2028        raw_test_pass(0xddde);
2029        raw_test_pass_reg(tmpIInfo->startTime);
2030        raw_test_pass_reg(tmpIInfo->endTime);
2031        raw_test_pass(0xdddf);
2032      }
2033
2034      if(interruptInfoOverflow) {
2035        raw_test_pass(0xefef);
2036      }*/
2037
2038   raw_test_pass(0xeeee);
2039 #endif
2040 }
2041
2042 inline void setTaskExitIndex(int index) {
2043         taskInfoArray[taskInfoIndex]->exitIndex = index;
2044 }
2045
2046 inline void addNewObjInfo(void * nobj) {
2047         if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
2048                 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
2049         }
2050         addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
2051 }
2052 #endif
2053
2054 // receive object transferred from other cores
2055 // or the terminate message from other cores
2056 // NOTICE: following format is for threadsimulate version only
2057 //         RAW version please see previous description
2058 // format: type + object
2059 // type: -1--stall msg
2060 //      !-1--object
2061 // return value: 0--received an object
2062 //               1--received nothing
2063 //               2--received a Stall Msg
2064 //               3--received a lock Msg
2065 //               RAW version: -1 -- received nothing
2066 //                            otherwise -- received msg type
2067 int receiveObject() {
2068 #ifdef RAW
2069   bool deny = false;
2070   unsigned msgHdr;
2071   int self_y, self_x, target_y, target_x;
2072   int targetcore = 0;
2073   if(gdn_input_avail() == 0) {
2074 #ifdef RAWDEBUG
2075     if(corenum < NUMCORES) {
2076       raw_test_pass(0xd001);
2077     }
2078 #endif
2079     return -1;
2080   }
2081 #ifdef RAWPROFILE
2082   /*if(isInterrupt && (!interruptInfoOverflow)) {
2083      // raw_test_pass(0xffff);
2084      interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
2085      interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
2086      interruptInfoArray[interruptInfoIndex]->endTime = -1;
2087      }*/
2088 #endif
2089 msg:
2090 #ifdef RAWDEBUG
2091   raw_test_pass(0xcccc);
2092 #endif
2093   while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
2094     msgdata[msgdataindex] = gdn_receive();
2095     if(msgdataindex == 0) {
2096                 if(msgdata[0] > 0xc) {
2097                         msglength = 3;
2098                 } else if (msgdata[0] == 0xc) {
2099                         msglength = 1;
2100                 } else if(msgdata[0] > 8) {
2101                         msglength = 4;
2102                 } else if(msgdata[0] == 8) {
2103                         msglength = 6;
2104                 } else if(msgdata[0] > 5) {
2105                         msglength = 2;
2106                 } else if (msgdata[0] > 2) {
2107                         msglength = 4;
2108                 } else if (msgdata[0] == 2) {
2109                         msglength = 5;
2110                 } else if (msgdata[0] > 0) {
2111                         msglength = 4;
2112                 }
2113     } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
2114       msglength = msgdata[msgdataindex];
2115     }
2116 #ifdef RAWDEBUG
2117     raw_test_pass_reg(msgdata[msgdataindex]);
2118 #endif
2119     msgdataindex++;
2120   }
2121 #ifdef RAWDEBUG
2122   raw_test_pass(0xffff);
2123 #endif
2124   if(msgdataindex == msglength) {
2125     // received a whole msg
2126     int type, data1;             // will receive at least 2 words including type
2127     type = msgdata[0];
2128     data1 = msgdata[1];
2129     switch(type) {
2130     case 0: {
2131       // receive a object transfer msg
2132       struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
2133       int k = 0;
2134 #ifdef RAWDEBUG
2135           raw_test_pass(0xe880);
2136 #endif
2137       if(corenum > NUMCORES - 1) {
2138                   raw_test_pass_reg(msgdata[2]);
2139         raw_test_done(0xa001);
2140       } else if((corenum == STARTUPCORE) && waitconfirm) {
2141                   waitconfirm = false;
2142                   numconfirm = 0;
2143           }
2144       // store the object and its corresponding queue info, enqueue it later
2145       transObj->objptr = (void *)msgdata[2];                                           // data1 is now size of the msg
2146       transObj->length = (msglength - 3) / 2;
2147       transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2148       for(k = 0; k < transObj->length; ++k) {
2149         transObj->queues[2*k] = msgdata[3+2*k];
2150 #ifdef RAWDEBUG
2151         raw_test_pass_reg(transObj->queues[2*k]);
2152 #endif
2153         transObj->queues[2*k+1] = msgdata[3+2*k+1];
2154 #ifdef RAWDEBUG
2155         raw_test_pass_reg(transObj->queues[2*k+1]);
2156 #endif
2157       }
2158       // check if there is an existing duplicate item
2159       {
2160         struct QueueItem * qitem = getTail(&objqueue);
2161         struct QueueItem * prev = NULL;
2162         while(qitem != NULL) {
2163           struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
2164           if(tmpinfo->objptr == transObj->objptr) {
2165             // the same object, remove outdate one
2166             removeItem(&objqueue, qitem);
2167           } else {
2168             prev = qitem;
2169           }
2170           if(prev == NULL) {
2171             qitem = getTail(&objqueue);
2172           } else {
2173             qitem = getNextQueueItem(prev);
2174           }
2175         }
2176         addNewItem_I(&objqueue, (void *)transObj);
2177       }
2178       ++(self_numreceiveobjs);
2179       break;
2180     }
2181
2182     case 1: {
2183       // receive a stall msg
2184       if(corenum != STARTUPCORE) {
2185         // non startup core can not receive stall msg
2186         // return -1
2187         raw_test_pass_reg(data1);
2188         raw_test_done(0xa002);
2189       } else if(waitconfirm) {
2190                   waitconfirm = false;
2191                   numconfirm = 0;
2192           }
2193       if(data1 < NUMCORES) {
2194 #ifdef RAWDEBUG
2195         raw_test_pass(0xe881);
2196 #endif
2197         corestatus[data1] = 0;
2198         numsendobjs[data1] = msgdata[2];
2199         numreceiveobjs[data1] = msgdata[3];
2200       }
2201       break;
2202     }
2203
2204     case 2: {
2205       // receive lock request msg
2206       // for 32 bit machine, the size is always 4 words
2207       //int msgsize = sizeof(int) * 4;
2208       int msgsize = 4;
2209       // lock request msg, handle it right now
2210       // check to see if there is a lock exist in locktbl for the required obj
2211           // data1 -> lock type
2212           int data2 = msgdata[2]; // obj pointer
2213       int data3 = msgdata[3]; // lock
2214           int data4 = msgdata[4]; // request core
2215       deny = false;
2216           if( ((data3 >> 5) % TOTALCORE) != corenum ) {
2217                   // the lock should not be on this core
2218                   raw_test_pass_reg(data4);
2219                   raw_test_done(0xa003);
2220           }
2221           if((corenum == STARTUPCORE) && waitconfirm) {
2222                   waitconfirm = false;
2223                   numconfirm = 0;
2224           }
2225       if(!RuntimeHashcontainskey(locktbl, data3)) {
2226         // no locks for this object
2227         // first time to operate on this shared object
2228         // create a lock for it
2229         // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
2230         struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
2231         lockvalue->redirectlock = 0;
2232 #ifdef RAWDEBUG
2233         raw_test_pass(0xe882);
2234 #endif
2235         if(data1 == 0) {
2236                 lockvalue->value = 1;
2237         } else {
2238                 lockvalue->value = -1;
2239         }
2240         RuntimeHashadd_I(locktbl, data3, (int)lockvalue);
2241       } else {
2242         int rwlock_obj = 0;
2243         struct LockValue * lockvalue = NULL;
2244 #ifdef RAWDEBUG
2245         raw_test_pass(0xe883);
2246 #endif
2247         RuntimeHashget(locktbl, data3, &rwlock_obj);
2248         lockvalue = (struct LockValue *)(rwlock_obj);
2249 #ifdef RAWDEBUG
2250         raw_test_pass_reg(lockvalue->redirectlock);
2251 #endif
2252         if(lockvalue->redirectlock != 0) {
2253                 // this lock is redirected
2254 #ifdef RAWDEBUG
2255                 raw_test_pass(0xe884);
2256 #endif
2257                 if(data1 == 0) {
2258                         getreadlock_I_r((void *)data2, (void *)lockvalue->redirectlock, data4, true);
2259                 } else {
2260                         getwritelock_I_r((void *)data2, (void *)lockvalue->redirectlock, data4, true);
2261                 }
2262                 break;
2263         } else {
2264 #ifdef RAWDEBUG
2265                 raw_test_pass_reg(lockvalue->value);
2266 #endif
2267                 if(0 == lockvalue->value) {
2268                         if(data1 == 0) {
2269                                 lockvalue->value = 1;
2270                         } else {
2271                                 lockvalue->value = -1;
2272                         }
2273                 } else if((lockvalue->value > 0) && (data1 == 0)) {
2274                   // read lock request and there are only read locks
2275                   lockvalue->value++;
2276                 } else {
2277                   deny = true;
2278                 }
2279 #ifdef RAWDEBUG
2280                 raw_test_pass_reg(lockvalue->value);
2281 #endif
2282         }
2283           }
2284         targetcore = data4;
2285         // check if there is still some msg on sending
2286         if(isMsgSending) {
2287 #ifdef RAWDEBUG
2288                         raw_test_pass(0xe885);
2289 #endif
2290                         isMsgHanging = true;
2291                         // cache the msg in outmsgdata and send it later
2292                         // msglength + target core + msg
2293                         outmsgdata[outmsglast++] = msgsize;
2294                         outmsgdata[outmsglast++] = targetcore;
2295                         if(deny == true) {
2296                                 outmsgdata[outmsglast++] = 4;
2297                         } else {
2298                                 outmsgdata[outmsglast++] = 3;
2299                         }
2300                         outmsgdata[outmsglast++] = data1;
2301                         outmsgdata[outmsglast++] = data2;
2302                         outmsgdata[outmsglast++] = data3;
2303                 } else {
2304 #ifdef RAWDEBUG
2305                         raw_test_pass(0xe886);
2306 #endif
2307                         // no msg on sending, send it out
2308                         calCoords(corenum, &self_y, &self_x);
2309                         calCoords(targetcore, &target_y, &target_x);
2310                         // Build the message header
2311                         msgHdr = construct_dyn_hdr(0, msgsize, 0,                                                               // msgsize word sent.
2312                                                    self_y, self_x,
2313                                                target_y, target_x);
2314                         gdn_send(msgHdr);                                                               // Send the message header to EAST to handle fab(n - 1).
2315 #ifdef RAWDEBUG
2316                         raw_test_pass(0xbbbb);
2317                         raw_test_pass(0xb000 + targetcore);                                                 // targetcore
2318 #endif
2319                         if(deny == true) {
2320                           // deny the lock request
2321                           gdn_send(4);                                                       // lock request
2322 #ifdef RAWDEBUG
2323                           raw_test_pass(4);
2324 #endif
2325                         } else {
2326                           // grount the lock request
2327                           gdn_send(3);                                                       // lock request
2328 #ifdef RAWDEBUG
2329                           raw_test_pass(3);
2330 #endif
2331                         }
2332                         gdn_send(data1);                                                 // lock type
2333 #ifdef RAWDEBUG
2334                         raw_test_pass_reg(data1);
2335 #endif
2336                         gdn_send(data2);                                                 // obj pointer
2337 #ifdef RAWDEBUG
2338                         raw_test_pass_reg(data2);
2339 #endif
2340                         gdn_send(data3);                                                 // lock
2341 #ifdef RAWDEBUG
2342                         raw_test_pass_reg(data3);
2343                         raw_test_pass(0xffff);
2344 #endif
2345                 }
2346       break;
2347     }
2348
2349     case 3: {
2350       // receive lock grount msg
2351       if(corenum > NUMCORES - 1) {
2352                   raw_test_pass_reg(msgdata[2]);
2353         raw_test_done(0xa004);
2354       } else if((corenum == STARTUPCORE) && waitconfirm) {
2355                   waitconfirm = false;
2356                   numconfirm = 0;
2357           }
2358       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
2359 #ifdef RAWDEBUG
2360                   raw_test_pass(0xe887);
2361 #endif
2362         lockresult = 1;
2363         lockflag = true;
2364 #ifndef INTERRUPT
2365         reside = false;
2366 #endif
2367       } else {
2368         // conflicts on lockresults
2369         raw_test_pass_reg(msgdata[2]);
2370         raw_test_done(0xa005);
2371       }
2372       break;
2373     }
2374
2375     case 4: {
2376       // receive lock grount/deny msg
2377       if(corenum > NUMCORES - 1) {
2378                   raw_test_pass_reg(msgdata[2]);
2379         raw_test_done(0xa006);
2380       } else if((corenum == STARTUPCORE) && waitconfirm) {
2381                   waitconfirm = false;
2382                   numconfirm = 0;
2383           }
2384       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
2385 #ifdef RAWDEBUG
2386                   raw_test_pass(0xe888);
2387 #endif
2388         lockresult = 0;
2389         lockflag = true;
2390 #ifndef INTERRUPT
2391         reside = false;
2392 #endif
2393       } else {
2394         // conflicts on lockresults
2395         raw_test_pass_reg(msgdata[2]);
2396         raw_test_done(0xa007);
2397       }
2398       break;
2399     }
2400
2401     case 5: {
2402       // receive lock release msg
2403           if((corenum == STARTUPCORE) && waitconfirm) {
2404                   waitconfirm = false;
2405                   numconfirm = 0;
2406           }
2407       if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
2408         // no locks for this object, something is wrong
2409         raw_test_pass_reg(msgdata[3]);
2410         raw_test_done(0xa008);
2411       } else {
2412         int rwlock_obj = 0;
2413         struct LockValue * lockvalue = NULL;
2414         RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
2415         lockvalue = (struct LockValue*)(rwlock_obj);
2416 #ifdef RAWDEBUG
2417         raw_test_pass(0xe889);
2418         raw_test_pass_reg(lockvalue->value);
2419 #endif
2420         if(data1 == 0) {
2421           lockvalue->value--;
2422         } else {
2423           lockvalue->value++;
2424         }
2425 #ifdef RAWDEBUG
2426         raw_test_pass_reg(lockvalue->value);
2427 #endif
2428       }
2429       break;
2430     }
2431
2432 #ifdef RAWPROFILE
2433     case 6: {
2434       // receive an output request msg
2435       if(corenum == STARTUPCORE) {
2436         // startup core can not receive profile output finish msg
2437         raw_test_done(0xa009);
2438       }
2439 #ifdef RAWDEBUG
2440           raw_test_pass(0xe88a);
2441 #endif
2442       {
2443         int msgsize = 2;
2444         stall = true;
2445         totalexetime = data1;
2446         outputProfileData();
2447         /*if(data1 >= NUMCORES) {
2448            raw_test_pass_reg(taskInfoIndex);
2449            raw_test_pass_reg(taskInfoOverflow);
2450                 if(!taskInfoOverflow) {
2451                         taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
2452                         taskInfoIndex++;
2453                         if(taskInfoIndex == TASKINFOLENGTH) {
2454                                 taskInfoOverflow = true;
2455                         }
2456                 }
2457            }*/
2458         // no msg on sending, send it out
2459         targetcore = STARTUPCORE;
2460         calCoords(corenum, &self_y, &self_x);
2461         calCoords(targetcore, &target_y, &target_x);
2462         // Build the message header
2463         msgHdr = construct_dyn_hdr(0, msgsize, 0,                                                               // msgsize word sent.
2464                                    self_y, self_x,
2465                                    target_y, target_x);
2466         gdn_send(msgHdr);
2467 #ifdef RAWDEBUG
2468         raw_test_pass(0xbbbb);
2469         raw_test_pass(0xb000 + targetcore);                                                 // targetcore
2470 #endif
2471         gdn_send(7);
2472 #ifdef RAWDEBUG
2473         raw_test_pass(7);
2474 #endif
2475         gdn_send(corenum);
2476 #ifdef RAWDEBUG
2477         raw_test_pass_reg(corenum);
2478         raw_test_pass(0xffff);
2479 #endif
2480       }
2481       break;
2482     }
2483
2484     case 7: {
2485       // receive a profile output finish msg
2486       if(corenum != STARTUPCORE) {
2487         // non startup core can not receive profile output finish msg
2488         raw_test_pass_reg(data1);
2489         raw_test_done(0xa00a);
2490       }
2491 #ifdef RAWDEBUG
2492           raw_test_pass(0xe88b);
2493 #endif
2494       profilestatus[data1] = 0;
2495       break;
2496     }
2497 #endif
2498
2499         case 8: {
2500                 // receive a redirect lock request msg
2501                 // for 32 bit machine, the size is always 4 words
2502       //int msgsize = sizeof(int) * 4;
2503       int msgsize = 4;
2504       // lock request msg, handle it right now
2505       // check to see if there is a lock exist in locktbl for the required obj
2506           // data1 -> lock type
2507           int data2 = msgdata[2]; // obj pointer
2508       int data3 = msgdata[3]; // redirect lock
2509           int data4 = msgdata[4]; // root request core
2510           int data5 = msgdata[5]; // request core
2511           if( ((data3 >> 5) % TOTALCORE) != corenum ) {
2512                   // the lock should not be on this core
2513                   raw_test_pass_reg(data5);
2514                   raw_test_done(0xa00b);
2515           } if((corenum == STARTUPCORE) && waitconfirm) {
2516                   waitconfirm = false;
2517                   numconfirm = 0;
2518           }
2519       deny = false;
2520       if(!RuntimeHashcontainskey(locktbl, data3)) {
2521         // no locks for this object
2522         // first time to operate on this shared object
2523         // create a lock for it
2524         // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
2525         struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
2526         lockvalue->redirectlock = 0;
2527 #ifdef RAWDEBUG
2528         raw_test_pass(0xe88c);
2529 #endif
2530         if(data1 == 0) {
2531                 lockvalue->value = 1;
2532         } else {
2533                 lockvalue->value = -1;
2534         }
2535         RuntimeHashadd_I(locktbl, data3, (int)lockvalue);
2536       } else {
2537         int rwlock_obj = 0;
2538         struct LockValue * lockvalue = NULL;
2539 #ifdef RAWDEBUG
2540         raw_test_pass(0xe88d);
2541 #endif
2542         RuntimeHashget(locktbl, data3, &rwlock_obj);
2543         lockvalue = (struct LockValue *)(rwlock_obj);
2544 #ifdef RAWDEBUG
2545         raw_test_pass_reg(lockvalue->redirectlock);
2546 #endif
2547         if(lockvalue->redirectlock != 0) {
2548                 // this lock is redirected
2549 #ifdef RAWDEBUG
2550                 raw_test_pass(0xe88e);
2551 #endif
2552                 if(data1 == 0) {
2553                         getreadlock_I_r((void *)data2, (void *)lockvalue->redirectlock, data4, true);
2554                 } else {
2555                         getwritelock_I_r((void *)data2, (void *)lockvalue->redirectlock, data4, true);
2556                 }
2557                 break;
2558         } else {
2559 #ifdef RAWDEBUG
2560                 raw_test_pass_reg(lockvalue->value);
2561 #endif
2562                 if(0 == lockvalue->value) {
2563                         if(data1 == 0) {
2564                                 lockvalue->value = 1;
2565                         } else {
2566                                 lockvalue->value = -1;
2567                         }
2568                 } else if((lockvalue->value > 0) && (data1 == 0)) {
2569                   // read lock request and there are only read locks
2570                   lockvalue->value++;
2571                 } else {
2572                   deny = true;
2573                 }
2574 #ifdef RAWDEBUG
2575                 raw_test_pass_reg(lockvalue->value);
2576 #endif
2577         }
2578           }
2579         targetcore = data4;
2580         // check if there is still some msg on sending
2581         if(isMsgSending) {
2582 #ifdef RAWDEBUG
2583                         raw_test_pass(0xe88f);
2584 #endif
2585                         isMsgHanging = true;
2586                         // cache the msg in outmsgdata and send it later
2587                         // msglength + target core + msg
2588                         outmsgdata[outmsglast++] = msgsize;
2589                         outmsgdata[outmsglast++] = targetcore;
2590                         if(deny == true) {
2591                                 outmsgdata[outmsglast++] = 0xa;
2592                         } else {
2593                                 outmsgdata[outmsglast++] = 9;
2594                         }
2595                         outmsgdata[outmsglast++] = data1;
2596                         outmsgdata[outmsglast++] = data2;
2597                         outmsgdata[outmsglast++] = data3; 
2598                 } else {
2599 #ifdef RAWDEBUG
2600                         raw_test_pass(0xe890);
2601 #endif
2602                         // no msg on sending, send it out
2603                         calCoords(corenum, &self_y, &self_x);
2604                         calCoords(targetcore, &target_y, &target_x);
2605                         // Build the message header
2606                         msgHdr = construct_dyn_hdr(0, msgsize, 0,                                                               // msgsize word sent.
2607                                                    self_y, self_x,
2608                                                target_y, target_x);
2609                         gdn_send(msgHdr);                                                               // Send the message header to EAST to handle fab(n - 1).
2610 #ifdef RAWDEBUG
2611                         raw_test_pass(0xbbbb);
2612                         raw_test_pass(0xb000 + targetcore);                                                 // targetcore
2613 #endif
2614                         if(deny == true) {
2615                           // deny the lock request
2616                           gdn_send(0xa);                                                       // lock request
2617 #ifdef RAWDEBUG
2618                           raw_test_pass(0xa);
2619 #endif
2620                         } else {
2621                           // grount the lock request
2622                           gdn_send(9);                                                       // lock request
2623 #ifdef RAWDEBUG
2624                           raw_test_pass(9);
2625 #endif
2626                         }
2627                         gdn_send(data1);                                                 // lock type
2628 #ifdef RAWDEBUG
2629                         raw_test_pass_reg(data1);
2630 #endif
2631                         gdn_send(data2);                                                 // obj pointer
2632 #ifdef RAWDEBUG
2633                         raw_test_pass_reg(data2);
2634 #endif
2635                         gdn_send(data3);                                                 // lock
2636 #ifdef RAWDEBUG
2637                         raw_test_pass_reg(data3);
2638                         raw_test_pass(0xffff);
2639 #endif
2640                 }
2641                 break;
2642         }
2643
2644         case 9: {
2645                 // receive a lock grant msg with redirect info
2646                 if(corenum > NUMCORES - 1) {
2647         raw_test_pass_reg(msgdata[2]);
2648         raw_test_done(0xa00c);
2649       } if((corenum == STARTUPCORE) && waitconfirm) {
2650                   waitconfirm = false;
2651                   numconfirm = 0;
2652           }
2653       if(lockobj == msgdata[2]) {
2654 #ifdef RAWDEBUG
2655                   raw_test_pass(0xe891);
2656 #endif
2657         lockresult = 1;
2658         lockflag = true;
2659         RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
2660 #ifndef INTERRUPT
2661         reside = false;
2662 #endif
2663       } else {
2664         // conflicts on lockresults
2665         raw_test_pass_reg(msgdata[2]);
2666         raw_test_done(0xa00d);
2667       }
2668                 break;
2669         }
2670         
2671         case 0xa: {
2672                 // receive a lock deny msg with redirect info
2673                 if(corenum > NUMCORES - 1) {
2674                         raw_test_pass_reg(msgdata[2]);
2675         raw_test_done(0xa00e);
2676       } if((corenum == STARTUPCORE) && waitconfirm) {
2677                   waitconfirm = false;
2678                   numconfirm = 0;
2679           }
2680       if(lockobj == msgdata[2]) {
2681 #ifdef RAWDEBUG
2682                   raw_test_pass(0xe892);
2683 #endif
2684         lockresult = 0;
2685         lockflag = true;
2686         //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
2687 #ifndef INTERRUPT
2688         reside = false;
2689 #endif
2690       } else {
2691         // conflicts on lockresults
2692         raw_test_pass_reg(msgdata[2]);
2693         raw_test_done(0xa00f);
2694       }
2695                 break;
2696         }
2697
2698         case 0xb: {
2699                 // receive a lock release msg with redirect info
2700                 if((corenum == STARTUPCORE) && waitconfirm) {
2701                   waitconfirm = false;
2702                   numconfirm = 0;
2703           }
2704                 if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
2705         // no locks for this object, something is wrong
2706         raw_test_pass_reg(msgdata[2]);
2707         raw_test_done(0xa010);
2708       } else {
2709         int rwlock_obj = 0;
2710         struct LockValue * lockvalue = NULL;
2711         RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
2712         lockvalue = (struct LockValue*)(rwlock_obj);
2713 #ifdef RAWDEBUG
2714         raw_test_pass(0xe893);
2715         raw_test_pass_reg(lockvalue->value);
2716 #endif
2717         if(data1 == 0) {
2718           lockvalue->value--;
2719         } else {
2720           lockvalue->value++;
2721         }
2722 #ifdef RAWDEBUG
2723         raw_test_pass_reg(lockvalue->value);
2724 #endif
2725         lockvalue->redirectlock = msgdata[3];
2726       }
2727                 break;
2728         }
2729         
2730         case 0xc: {
2731                 // receive a status confirm info
2732                 if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
2733         // wrong core to receive such msg
2734         raw_test_done(0xa011);
2735       } else {
2736                   int msgsize = 3;
2737                   int targetcore = STARTUPCORE;
2738 #ifdef RAWDEBUG
2739           raw_test_pass(0xe888);
2740 #endif
2741                   // check if there is still some msg on sending
2742         if(isMsgSending) {
2743 #ifdef RAWDEBUG
2744           raw_test_pass(0xe888);
2745 #endif
2746                         isMsgHanging = true;
2747                         // cache the msg in outmsgdata and send it later
2748                         // msglength + target core + msg
2749                         outmsgdata[outmsglast++] = msgsize;
2750                         outmsgdata[outmsglast++] = targetcore;
2751                         outmsgdata[outmsglast++] = 0xd;
2752                         if(busystatus) {
2753                                 outmsgdata[outmsglast++] = 1;
2754                         } else {
2755                                 outmsgdata[outmsglast++] = 0;
2756                         }
2757                         outmsgdata[outmsglast++] = corenum;
2758                 } else {
2759 #ifdef RAWDEBUG
2760           raw_test_pass(0xe888);
2761 #endif
2762                         // no msg on sending, send it out
2763                         calCoords(corenum, &self_y, &self_x);
2764                         calCoords(targetcore, &target_y, &target_x);
2765                         // Build the message header
2766                         msgHdr = construct_dyn_hdr(0, msgsize, 0,                                                               // msgsize word sent.
2767                                                    self_y, self_x,
2768                                                target_y, target_x);
2769                         gdn_send(msgHdr);   
2770 #ifdef RAWDEBUG
2771                         raw_test_pass(0xbbbb);
2772                         raw_test_pass(0xb000 + targetcore);                                            
2773 #endif
2774                         gdn_send(0xd);                                                       // status report
2775 #ifdef RAWDEBUG
2776                         raw_test_pass(0xd);
2777 #endif
2778                         if(busystatus == true) {
2779                           // busy
2780                           gdn_send(1);   
2781 #ifdef RAWDEBUG
2782                           raw_test_pass(1);
2783 #endif
2784                         } else {
2785                           // stall
2786                           gdn_send(0);
2787 #ifdef RAWDEBUG
2788                           raw_test_pass(0);
2789 #endif
2790                         }
2791                         gdn_send(corenum);                                                 // corenum
2792 #ifdef RAWDEBUG
2793                         raw_test_pass_reg(corenum);
2794                         raw_test_pass(0xffff);
2795 #endif
2796                 }
2797       }
2798                 break;
2799         }
2800
2801         case 0xd: {
2802                 // receive a status confirm info
2803                 if(corenum != STARTUPCORE) {
2804         // wrong core to receive such msg
2805         raw_test_pass_reg(msgdata[2]);
2806         raw_test_done(0xa012);
2807       } else {
2808 #ifdef RAWDEBUG
2809           raw_test_pass(0xe888);
2810 #endif
2811                   if(waitconfirm) {
2812                           numconfirm--;
2813                   }
2814                   corestatus[msgdata[2]] = msgdata[1];
2815       }
2816                 break;
2817         }
2818         
2819     default:
2820       break;
2821     }
2822     for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
2823       msgdata[msgdataindex] = -1;
2824     }
2825     msgtype = -1;
2826     msglength = 30;
2827 #ifdef RAWDEBUG
2828     raw_test_pass(0xe894);
2829 #endif
2830     if(gdn_input_avail() != 0) {
2831       goto msg;
2832     }
2833 #ifdef RAWPROFILE
2834 /*    if(isInterrupt && (!interruptInfoOverflow)) {
2835       interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
2836       interruptInfoIndex++;
2837       if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2838         interruptInfoOverflow = true;
2839       }
2840     }*/
2841 #endif
2842     return type;
2843   } else {
2844     // not a whole msg
2845 #ifdef RAWDEBUG
2846     raw_test_pass(0xe895);
2847 #endif
2848 #ifdef RAWPROFILE
2849 /*    if(isInterrupt && (!interruptInfoOverflow)) {
2850       interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
2851       interruptInfoIndex++;
2852       if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2853         interruptInfoOverflow = true;
2854       }
2855     }*/
2856 #endif
2857     return -2;
2858   }
2859 #elif defined THREADSIMULATE
2860   int numofcore = pthread_getspecific(key);
2861   // use POSIX message queue to transfer object
2862   int msglen = 0;
2863   struct mq_attr mqattr;
2864   mq_getattr(mqd[numofcore], &mqattr);
2865   void * msgptr =RUNMALLOC(mqattr.mq_msgsize);
2866   msglen=mq_receive(mqd[numofcore], msgptr, mqattr.mq_msgsize, NULL);       // receive the object into the queue
2867   if(-1 == msglen) {
2868     // no msg
2869     free(msgptr);
2870     return 1;
2871   }
2872   //printf("msg: %s\n",msgptr);
2873   if(((int*)msgptr)[0] == -1) {
2874     // StallMsg
2875     struct ___Object___ * tmpptr = (struct ___Object___ *)msgptr;
2876     int index = tmpptr->flag;
2877     corestatus[index] = 0;
2878     numsendobjs[index] = tmpptr->___cachedHash___;
2879     numreceiveobjs[index] = tmpptr->___cachedCode___;
2880     printf("<receiveObject> index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
2881     free(msgptr);
2882     return 2;
2883   } else {
2884     // an object
2885     if(numofcore == STARTUPCORE) {
2886       ++(numreceiveobjs[numofcore]);
2887     } else {
2888       ++(thread_data_array[numofcore].numreceiveobjs);
2889     }
2890     struct ___Object___ * tmpptr = (struct ___Object___ *)msgptr;
2891     struct transObjInfo * transObj = (struct transObjInfo *)tmpptr->original;
2892     tmpptr = (struct ___Object___ *)(transObj->objptr);
2893     int type = tmpptr->type;
2894     int size=classsize[type];
2895     struct ___Object___ * newobj=RUNMALLOC(size);
2896     memcpy(newobj, tmpptr, size);
2897     if(0 == newobj->isolate) {
2898       newobj->original=tmpptr;
2899     }
2900     RUNFREE(msgptr);
2901     tmpptr = NULL;
2902     int k = 0;
2903     for(k = 0; k < transObj->length; ++k) {
2904       int taskindex = transObj->queues[2 * k];
2905       int paramindex = transObj->queues[2 * k + 1];
2906       struct parameterwrapper ** queues = &(paramqueues[numofcore][taskindex][paramindex]);
2907       enqueueObject(newobj, queues, 1);
2908     }
2909     RUNFREE(transObj->queues);
2910     RUNFREE(transObj);
2911     return 0;
2912   }
2913 #endif
2914 }
2915
2916 bool getreadlock(void * ptr) {
2917 #ifdef RAW
2918   unsigned msgHdr;
2919   int self_y, self_x, target_y, target_x;
2920   int targetcore = 0;
2921   // for 32 bit machine, the size is always 5 words
2922   int msgsize = 5;
2923
2924   lockobj = (int)ptr;
2925   if(((struct ___Object___ *)ptr)->lock == NULL) {
2926         lock2require = lockobj;
2927   } else {
2928         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2929   }
2930   targetcore = (lock2require >> 5) % TOTALCORE;
2931   lockflag = false;
2932 #ifndef INTERRUPT
2933   reside = false;
2934 #endif
2935   lockresult = 0;
2936
2937   if(targetcore == corenum) {
2938     // reside on this core
2939     bool deny = false;
2940 #ifdef INTERRUPT
2941     raw_user_interrupts_off();
2942 #endif
2943     if(!RuntimeHashcontainskey(locktbl, lock2require)) {
2944       // no locks for this object
2945       // first time to operate on this shared object
2946       // create a lock for it
2947       // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
2948           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
2949           lockvalue->redirectlock = 0;
2950           lockvalue->value = 1;
2951       RuntimeHashadd_I(locktbl, lock2require, (int)lockvalue);
2952     } else {
2953       int rwlock_obj = 0;
2954           struct LockValue* lockvalue;
2955       RuntimeHashget(locktbl, lock2require, &rwlock_obj);
2956           lockvalue = (struct LockValue*)rwlock_obj;
2957           if(lockvalue->redirectlock != 0) {
2958                   // the lock is redirected
2959                   getreadlock_I_r(ptr, (void *)lockvalue->redirectlock, corenum, false);
2960                   return true;
2961           } else {
2962               if(-1 != lockvalue->value) {
2963                           lockvalue->value++;
2964                   } else {
2965                           deny = true;
2966                   }
2967           }
2968     }
2969 #ifdef INTERRUPT
2970     raw_user_interrupts_on();
2971 #endif
2972     if(lockobj == (int)ptr) {
2973       if(deny) {
2974         lockresult = 0;
2975       } else {
2976         lockresult = 1;
2977       }
2978       lockflag = true;
2979 #ifndef INTERRUPT
2980       reside = true;
2981 #endif
2982     } else {
2983       // conflicts on lockresults
2984       raw_test_done(0xa013);
2985     }
2986     return true;
2987   }
2988
2989   calCoords(corenum, &self_y, &self_x);
2990   calCoords(targetcore, &target_y, &target_x);
2991   isMsgSending = true;
2992   // Build the message header
2993   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
2994                              self_y, self_x,
2995                              target_y, target_x);
2996   // start sending the msg, set send msg flag
2997   //isMsgSending = true;
2998   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
2999 #ifdef RAWDEBUG
3000   raw_test_pass(0xbbbb);
3001   raw_test_pass(0xb000 + targetcore);       // targetcore
3002 #endif
3003   gdn_send(2);   // lock request
3004 #ifdef RAWDEBUG
3005   raw_test_pass(2);
3006 #endif
3007   gdn_send(0);       // read lock
3008 #ifdef RAWDEBUG
3009   raw_test_pass(0);
3010 #endif
3011   gdn_send((int)ptr);  // obj pointer
3012 #ifdef RAWDEBUG
3013   raw_test_pass_reg(ptr);
3014 #endif
3015   gdn_send(lock2require); // lock
3016 #ifdef RAWDEBUG
3017   raw_test_pass_reg(lock2require);
3018 #endif
3019   gdn_send(corenum);  // request core
3020 #ifdef RAWDEBUG
3021   raw_test_pass_reg(corenum);
3022   raw_test_pass(0xffff);
3023 #endif
3024   // end of sending this msg, set sand msg flag false
3025   isMsgSending = false;
3026   // check if there are pending msgs
3027   while(isMsgHanging) {
3028     // get the msg from outmsgdata[]
3029     // length + target + msg
3030     outmsgleft = outmsgdata[outmsgindex++];
3031     targetcore = outmsgdata[outmsgindex++];
3032     calCoords(targetcore, &target_y, &target_x);
3033         isMsgSending = true;
3034     // Build the message header
3035     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
3036                                self_y, self_x,
3037                                target_y, target_x);
3038         //isMsgSending = true;
3039     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
3040 #ifdef RAWDEBUG
3041     raw_test_pass(0xbbbb);
3042     raw_test_pass(0xb000 + targetcore);             // targetcore
3043 #endif
3044     while(outmsgleft-- > 0) {
3045       gdn_send(outmsgdata[outmsgindex++]);
3046 #ifdef RAWDEBUG
3047       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
3048 #endif
3049     }
3050 #ifdef RAWDEBUG
3051     raw_test_pass(0xffff);
3052 #endif
3053     isMsgSending = false;
3054 #ifdef INTERRUPT
3055     raw_user_interrupts_off();
3056 #endif
3057     // check if there are still msg hanging
3058     if(outmsgindex == outmsglast) {
3059       // no more msgs
3060       outmsgindex = outmsglast = 0;
3061       isMsgHanging = false;
3062     }
3063 #ifdef INTERRUPT
3064     raw_user_interrupts_on();
3065 #endif
3066   }
3067   return true;
3068 #elif defined THREADSIMULATE
3069   // TODO : need modification for alias lock
3070   int numofcore = pthread_getspecific(key);
3071
3072   int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
3073   printf("[getreadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3074   if(0 != rc) {
3075     return false;
3076   }
3077   if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3078     // no locks for this object
3079     // first time to operate on this shared object
3080     // create a lock for it
3081     rc = pthread_rwlock_unlock(&rwlock_tbl);
3082     printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3083     pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
3084     memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
3085     rc = pthread_rwlock_init(rwlock, NULL);
3086     printf("[getreadlock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
3087     rc = pthread_rwlock_trywrlock(&rwlock_tbl);
3088     printf("[getreadlock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3089     if(0 != rc) {
3090       RUNFREE(rwlock);
3091       return false;
3092     } else {
3093       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3094         // check again
3095         RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
3096       } else {
3097         RUNFREE(rwlock);
3098         RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock);
3099       }
3100       rc = pthread_rwlock_unlock(&rwlock_tbl);
3101       printf("[getreadlock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3102     }
3103     rc = pthread_rwlock_tryrdlock(rwlock);
3104     printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
3105     if(0 != rc) {
3106       return false;
3107     } else {
3108       return true;
3109     }
3110   } else {
3111     pthread_rwlock_t* rwlock_obj = NULL;
3112     RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
3113     rc = pthread_rwlock_unlock(&rwlock_tbl);
3114     printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3115     int rc_obj = pthread_rwlock_tryrdlock(rwlock_obj);
3116     printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
3117     if(0 != rc_obj) {
3118       return false;
3119     } else {
3120       return true;
3121     }
3122   }
3123 #endif
3124 }
3125
3126 void releasereadlock(void * ptr) {
3127 #ifdef RAW
3128   unsigned msgHdr;
3129   int self_y, self_x, target_y, target_x;
3130   int targetcore = 0;
3131   // for 32 bit machine, the size is always 4 words
3132   int msgsize = 4;
3133
3134   int reallock = 0;
3135   if(((struct ___Object___ *)ptr)->lock == NULL) {
3136         reallock = (int)ptr;
3137   } else {
3138         reallock = (int)(((struct ___Object___ *)ptr)->lock);
3139   }
3140   targetcore = (reallock >> 5) % TOTALCORE;
3141
3142   if(targetcore == corenum) {
3143 #ifdef INTERRUPT
3144     raw_user_interrupts_off();
3145 #endif
3146     // reside on this core
3147     if(!RuntimeHashcontainskey(locktbl, reallock)) {
3148       // no locks for this object, something is wrong
3149       raw_test_done(0xa014);
3150     } else {
3151       int rwlock_obj = 0;
3152           struct LockValue * lockvalue = NULL;
3153       RuntimeHashget(locktbl, reallock, &rwlock_obj);
3154           lockvalue = (struct LockValue *)rwlock_obj;
3155       lockvalue->value--;
3156     }
3157 #ifdef INTERRUPT
3158     raw_user_interrupts_on();
3159 #endif
3160     return;
3161   }
3162
3163   calCoords(corenum, &self_y, &self_x);
3164   calCoords(targetcore, &target_y, &target_x);
3165   isMsgSending = true;
3166   // Build the message header
3167   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
3168                              self_y, self_x,
3169                              target_y, target_x);
3170   // start sending the msg, set send msg flag
3171   //isMsgSending = true;
3172   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
3173 #ifdef RAWDEBUG
3174   raw_test_pass(0xbbbb);
3175   raw_test_pass(0xb000 + targetcore);       // targetcore
3176 #endif
3177   gdn_send(5);   // lock release
3178 #ifdef RAWDEBUG
3179   raw_test_pass(5);
3180 #endif
3181   gdn_send(0);       // read lock
3182 #ifdef RAWDEBUG
3183   raw_test_pass(0);
3184 #endif
3185   gdn_send((int)ptr);       // obj pointer
3186 #ifdef RAWDEBUG
3187   raw_test_pass_reg(ptr);
3188 #endif
3189   gdn_send(reallock);  // lock
3190 #ifdef RAWDEBUG
3191   raw_test_pass_reg(reallock);
3192   raw_test_pass(0xffff);
3193 #endif
3194   // end of sending this msg, set sand msg flag false
3195   isMsgSending = false;
3196   // check if there are pending msgs
3197   while(isMsgHanging) {
3198     // get the msg from outmsgdata[]
3199     // length + target + msg
3200     outmsgleft = outmsgdata[outmsgindex++];
3201     targetcore = outmsgdata[outmsgindex++];
3202     calCoords(targetcore, &target_y, &target_x);
3203         isMsgSending = true;
3204     // Build the message header
3205     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
3206                                self_y, self_x,
3207                                target_y, target_x);
3208         //isMsgSending = true;
3209     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
3210 #ifdef RAWDEBUG
3211     raw_test_pass(0xbbbb);
3212     raw_test_pass(0xb000 + targetcore);             // targetcore
3213 #endif
3214     while(outmsgleft-- > 0) {
3215       gdn_send(outmsgdata[outmsgindex++]);
3216 #ifdef RAWDEBUG
3217       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
3218 #endif
3219     }
3220 #ifdef RAWDEBUG
3221     raw_test_pass(0xffff);
3222 #endif
3223     isMsgSending = false;
3224 #ifdef INTERRUPT
3225     raw_user_interrupts_off();
3226 #endif
3227     // check if there are still msg hanging
3228     if(outmsgindex == outmsglast) {
3229       // no more msgs
3230       outmsgindex = outmsglast = 0;
3231       isMsgHanging = false;
3232     }
3233 #ifdef INTERRUPT
3234     raw_user_interrupts_on();
3235 #endif
3236   }
3237 #elif defined THREADSIMULATE
3238   int numofcore = pthread_getspecific(key);
3239   int rc = pthread_rwlock_rdlock(&rwlock_tbl);
3240   printf("[releasereadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3241   if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3242     printf("[releasereadlock, %d] Error: try to release a lock without previously grab it\n", numofcore);
3243     exit(-1);
3244   }
3245   pthread_rwlock_t* rwlock_obj = NULL;
3246   RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
3247   int rc_obj = pthread_rwlock_unlock(rwlock_obj);
3248   printf("[releasereadlock, %d] unlocked object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
3249   rc = pthread_rwlock_unlock(&rwlock_tbl);
3250   printf("[releasereadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3251 #endif
3252 }
3253
3254 #ifdef RAW
3255 // redirected lock request
3256 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
3257   unsigned msgHdr;
3258   int self_y, self_x, target_y, target_x;
3259   int targetcore = 0;
3260   // for 32 bit machine, the size is always 6 words
3261   int msgsize = 6;
3262
3263   if(core == corenum) {
3264           lockobj = (int)ptr;
3265           lock2require = (int)redirectlock;
3266           lockflag = false;
3267 #ifndef INTERRUPT
3268           reside = false;
3269 #endif
3270           lockresult = 0;
3271   }  
3272   targetcore = ((int)redirectlock >> 5) % TOTALCORE;
3273   
3274   if(targetcore == corenum) {
3275     // reside on this core
3276     bool deny = false;
3277     if(!RuntimeHashcontainskey(locktbl, (int)redirectlock)) {
3278       // no locks for this object
3279       // first time to operate on this shared object
3280       // create a lock for it
3281       // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
3282           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
3283           lockvalue->redirectlock = 0;
3284           lockvalue->value = 1;
3285       RuntimeHashadd_I(locktbl, (int)redirectlock, (int)lockvalue);
3286     } else {
3287       int rwlock_obj = 0;
3288           struct LockValue* lockvalue;
3289       RuntimeHashget(locktbl, (int)redirectlock, &rwlock_obj);
3290           lockvalue = (struct LockValue*)rwlock_obj;
3291           if(lockvalue->redirectlock != 0) {
3292                   // the lock is redirected
3293                   getreadlock_I_r(ptr, (void *)lockvalue->redirectlock, core, cache);
3294                   return true;
3295           } else {
3296                   if(-1 != lockvalue->value) {
3297                           lockvalue->value++;
3298                   } else {
3299                           deny = true;
3300                   }
3301           }
3302     }
3303         if(core == corenum) {
3304         if(lockobj == (int)ptr) {
3305               if(deny) {
3306                 lockresult = 0;
3307               } else {
3308                 lockresult = 1;
3309                 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
3310               }
3311           lockflag = true;
3312 #ifndef INTERRUPT
3313               reside = true;
3314 #endif
3315         } else {
3316               // conflicts on lockresults
3317           raw_test_done(0xa015);
3318         }
3319             return true;
3320         } else {
3321                 // send lock grant/deny request to the root requiring core
3322                 // check if there is still some msg on sending
3323                 int msgsize1 = 4;
3324                 if((!cache) || (cache && !isMsgSending)) {
3325                         calCoords(corenum, &self_y, &self_x);
3326                         calCoords(core, &target_y, &target_x);
3327                         // Build the message header
3328                         msgHdr = construct_dyn_hdr(0, msgsize1, 0,             // msgsize word sent.
3329                                                            self_y, self_x,
3330                                                                            target_y, target_x);
3331                         gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
3332 #ifdef RAWDEBUG
3333                         raw_test_pass(0xbbbb);
3334                         raw_test_pass(0xb000 + core);       // targetcore
3335 #endif
3336                         if(deny) {
3337                                 // deny
3338                                 gdn_send(0xa);   // lock deny with redirected info
3339 #ifdef RAWDEBUG
3340                                 raw_test_pass(0xa);
3341 #endif
3342                         } else {
3343                                 // grant
3344                                 gdn_send(9);   // lock grant with redirected info
3345 #ifdef RAWDEBUG
3346                                 raw_test_pass(9);
3347 #endif
3348                         }
3349                         gdn_send(0);       // read lock
3350 #ifdef RAWDEBUG
3351                         raw_test_pass(0);
3352 #endif
3353                         gdn_send((int)ptr);  // obj pointer
3354 #ifdef RAWDEBUG
3355                         raw_test_pass_reg(ptr);
3356 #endif
3357                         gdn_send((int)redirectlock); // redirected lock
3358 #ifdef RAWDEBUG
3359                         raw_test_pass_reg((int)redirectlock);
3360                         raw_test_pass(0xffff);
3361 #endif
3362                 } else if(cache && isMsgSending) {
3363                         isMsgHanging = true;
3364                         // cache the msg in outmsgdata and send it later
3365                         // msglength + target core + msg
3366                         outmsgdata[outmsglast++] = msgsize1;
3367                         outmsgdata[outmsglast++] = core;
3368                         if(deny) {
3369                                 outmsgdata[outmsglast++] = 0xa; // deny
3370                         } else {
3371                                 outmsgdata[outmsglast++] = 9; // grant
3372                         }
3373                         outmsgdata[outmsglast++] = 0;
3374                         outmsgdata[outmsglast++] = (int)ptr;
3375                         outmsgdata[outmsglast++] = (int)redirectlock;
3376                 }
3377         }
3378   }
3379
3380   // check if there is still some msg on sending
3381   if((!cache) || (cache && !isMsgSending)) {
3382           calCoords(corenum, &self_y, &self_x);
3383           calCoords(targetcore, &target_y, &target_x);
3384           // Build the message header
3385           msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
3386                                  self_y, self_x,
3387                                      target_y, target_x);
3388           gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
3389 #ifdef RAWDEBUG
3390           raw_test_pass(0xbbbb);
3391           raw_test_pass(0xb000 + targetcore);       // targetcore
3392 #endif
3393           gdn_send(8);   // redirected lock request
3394 #ifdef RAWDEBUG
3395           raw_test_pass(8);
3396 #endif
3397           gdn_send(0);       // read lock
3398 #ifdef RAWDEBUG
3399           raw_test_pass(0);
3400 #endif
3401           gdn_send((int)ptr);  // obj pointer
3402 #ifdef RAWDEBUG
3403           raw_test_pass_reg(ptr);
3404 #endif
3405           gdn_send(lock2require); // redirected lock
3406 #ifdef RAWDEBUG
3407           raw_test_pass_reg(lock2require);
3408 #endif
3409           gdn_send(core);  // root request core
3410 #ifdef RAWDEBUG
3411           raw_test_pass_reg(core);
3412 #endif
3413           gdn_send(corenum);  // request core
3414 #ifdef RAWDEBUG
3415           raw_test_pass_reg(corenum);
3416           raw_test_pass(0xffff);
3417 #endif
3418   } else if(cache && isMsgSending) {
3419           isMsgHanging = true;
3420           // cache the msg in outmsgdata and send it later
3421           // msglength + target core + msg
3422           outmsgdata[outmsglast++] = msgsize;
3423           outmsgdata[outmsglast++] = targetcore;
3424           outmsgdata[outmsglast++] = 8;
3425           outmsgdata[outmsglast++] = 0;
3426           outmsgdata[outmsglast++] = (int)ptr;
3427           outmsgdata[outmsglast++] = lock2require;
3428           outmsgdata[outmsglast++] = core;
3429           outmsgdata[outmsglast++] = corenum;
3430   }
3431   return true;
3432 }
3433 #endif
3434
3435 // not reentrant
3436 bool getwritelock(void * ptr) {
3437 #ifdef RAW
3438   unsigned msgHdr;
3439   int self_y, self_x, target_y, target_x;
3440   int targetcore = 0;
3441   // for 32 bit machine, the size is always 5 words
3442   int msgsize = 5;
3443
3444   lockobj = (int)ptr;
3445   if(((struct ___Object___ *)ptr)->lock == NULL) {
3446         lock2require = lockobj;
3447   } else {
3448         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
3449   }
3450   targetcore = (lock2require >> 5) % TOTALCORE;
3451   lockflag = false;
3452 #ifndef INTERRUPT
3453   reside = false;
3454 #endif
3455   lockresult = 0;
3456
3457 #ifdef RAWDEBUG
3458   raw_test_pass(0xe551);
3459   raw_test_pass_reg(lockobj);
3460   raw_test_pass_reg(lock2require);
3461   raw_test_pass_reg(targetcore);
3462 #endif
3463
3464   if(targetcore == corenum) {
3465     // reside on this core
3466     bool deny = false;
3467 #ifdef INTERRUPT
3468     raw_user_interrupts_off();
3469 #endif
3470     if(!RuntimeHashcontainskey(locktbl, lock2require)) {
3471       // no locks for this object
3472       // first time to operate on this shared object
3473       // create a lock for it
3474       // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
3475 #ifdef RAWDEBUG
3476       raw_test_pass(0xe552);
3477 #endif
3478           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
3479           lockvalue->redirectlock = 0;
3480           lockvalue->value = -1;
3481       RuntimeHashadd_I(locktbl, lock2require, (int)lockvalue);
3482     } else {
3483       int rwlock_obj = 0;
3484           struct LockValue* lockvalue;
3485       RuntimeHashget(locktbl, (int)ptr, &rwlock_obj);
3486           lockvalue = (struct LockValue*)rwlock_obj;
3487 #ifdef RAWDEBUG
3488       raw_test_pass(0xe553);
3489       raw_test_pass_reg(lockvalue->value);
3490 #endif
3491           if(lockvalue->redirectlock != 0) {
3492                   // the lock is redirected
3493 #ifdef  RAWDEBUG
3494                   raw_test_pass(0xe554);
3495 #endif
3496                   getwritelock_I_r(ptr, (void *)lockvalue->redirectlock, corenum, false);
3497                   return true;
3498           } else {
3499               if(0 == lockvalue->value) {
3500                           lockvalue->value = -1;
3501                   } else {
3502                           deny = true;
3503                   }
3504           }
3505     }
3506 #ifdef INTERRUPT
3507     raw_user_interrupts_on();
3508 #endif
3509 #ifdef RAWDEBUG
3510     raw_test_pass(0xe555);
3511     raw_test_pass_reg(lockresult);
3512 #endif
3513     if(lockobj == (int)ptr) {
3514       if(deny) {
3515         lockresult = 0;
3516 #ifdef RAWDEBUG
3517         raw_test_pass(0);
3518 #endif
3519       } else {
3520         lockresult = 1;
3521 #ifdef RAWDEBUG
3522         raw_test_pass(1);
3523 #endif
3524       }
3525       lockflag = true;
3526 #ifndef INTERRUPT
3527       reside = true;
3528 #endif
3529     } else {
3530       // conflicts on lockresults
3531       raw_test_done(0xa016);
3532     }
3533     return true;
3534   }
3535
3536 #ifdef RAWDEBUG
3537   raw_test_pass(0xe556);
3538 #endif
3539   calCoords(corenum, &self_y, &self_x);
3540   calCoords(targetcore, &target_y, &target_x);
3541 #ifdef RAWDEBUG
3542   raw_test_pass_reg(self_y);
3543   raw_test_pass_reg(self_x);
3544   raw_test_pass_reg(target_y);
3545   raw_test_pass_reg(target_x);
3546 #endif
3547   isMsgSending = true;
3548   // Build the message header
3549   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
3550                              self_y, self_x,
3551                              target_y, target_x);
3552   // start sending the msg, set send msg flag
3553   //isMsgSending = true;
3554   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
3555 #ifdef RAWDEBUG
3556   raw_test_pass(0xbbbb);
3557   raw_test_pass(0xb000 + targetcore);       // targetcore
3558 #endif
3559   gdn_send(2);   // lock request
3560 #ifdef RAWDEBUG
3561   raw_test_pass(2);
3562 #endif
3563   gdn_send(1);       // write lock
3564 #ifdef RAWDEBUG
3565   raw_test_pass(1);
3566 #endif
3567   gdn_send((int)ptr);  // obj pointer
3568 #ifdef RAWDEBUG
3569   raw_test_pass_reg(ptr);
3570 #endif
3571   gdn_send(lock2require); // lock
3572 #ifdef RAWDEBUG
3573   raw_test_pass_reg(lock2require);
3574 #endif
3575   gdn_send(corenum);  // request core
3576 #ifdef RAWDEBUG
3577   raw_test_pass_reg(corenum);
3578   raw_test_pass(0xffff);
3579 #endif
3580   // end of sending this msg, set sand msg flag false
3581   isMsgSending = false;
3582   // check if there are pending msgs
3583   while(isMsgHanging) {
3584     // get the msg from outmsgdata[]
3585     // length + target + msg
3586     outmsgleft = outmsgdata[outmsgindex++];
3587     targetcore = outmsgdata[outmsgindex++];
3588     calCoords(targetcore, &target_y, &target_x);
3589         isMsgSending = true;
3590     // Build the message header
3591     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
3592                                self_y, self_x,
3593                                target_y, target_x);
3594         //isMsgSending = true;
3595     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
3596 #ifdef RAWDEBUG
3597         raw_test_pass(0xe557);
3598     raw_test_pass(0xbbbb);
3599     raw_test_pass(0xb000 + targetcore);             // targetcore
3600 #endif
3601     while(outmsgleft-- > 0) {
3602       gdn_send(outmsgdata[outmsgindex++]);
3603 #ifdef RAWDEBUG
3604       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
3605 #endif
3606     }
3607 #ifdef RAWDEBUG
3608     raw_test_pass(0xffff);
3609 #endif
3610     isMsgSending = false;
3611 #ifdef INTERRUPT
3612     raw_user_interrupts_off();
3613 #endif
3614     // check if there are still msg hanging
3615     if(outmsgindex == outmsglast) {
3616       // no more msgs
3617       outmsgindex = outmsglast = 0;
3618       isMsgHanging = false;
3619     }
3620 #ifdef INTERRUPT
3621     raw_user_interrupts_on();
3622 #endif
3623   }
3624   return true;
3625 #elif defined THREADSIMULATE
3626   int numofcore = pthread_getspecific(key);
3627
3628   int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
3629   printf("[getwritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3630   if(0 != rc) {
3631     return false;
3632   }
3633   if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3634     // no locks for this object
3635     // first time to operate on this shared object
3636     // create a lock for it
3637     rc = pthread_rwlock_unlock(&rwlock_tbl);
3638     printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3639     pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
3640     memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
3641     rc = pthread_rwlock_init(rwlock, NULL);
3642     printf("[getwritelock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
3643     rc = pthread_rwlock_trywrlock(&rwlock_tbl);
3644     printf("[getwritelock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3645     if(0 != rc) {
3646       pthread_rwlock_destroy(rwlock);
3647       RUNFREE(rwlock);
3648       return false;
3649     } else {
3650       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3651         // check again
3652         RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
3653       } else {
3654         pthread_rwlock_destroy(rwlock);
3655         RUNFREE(rwlock);
3656         RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock);
3657       }
3658       rc = pthread_rwlock_unlock(&rwlock_tbl);
3659       printf("[getwritelock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3660     }
3661     rc = pthread_rwlock_trywrlock(rwlock);
3662     printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
3663     if(0 != rc) {
3664       return false;
3665     } else {
3666       return true;
3667     }
3668   } else {
3669     pthread_rwlock_t* rwlock_obj = NULL;
3670     RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
3671     rc = pthread_rwlock_unlock(&rwlock_tbl);
3672     printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3673     int rc_obj = pthread_rwlock_trywrlock(rwlock_obj);
3674     printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
3675     if(0 != rc_obj) {
3676       return false;
3677     } else {
3678       return true;
3679     }
3680   }
3681 #endif
3682 }
3683
3684 void releasewritelock(void * ptr) {
3685 #ifdef RAW
3686   unsigned msgHdr;
3687   int self_y, self_x, target_y, target_x;
3688   int targetcore = 0;
3689   // for 32 bit machine, the size is always 4 words
3690   int msgsize = 4;
3691
3692   int reallock = 0;
3693   if(((struct ___Object___ *)ptr)->lock == NULL) {
3694         reallock = (int)ptr;
3695   } else {
3696         reallock = (int)(((struct ___Object___ *)ptr)->lock);
3697   }
3698   targetcore = (reallock >> 5) % TOTALCORE;
3699
3700 #ifdef RAWDEBUG
3701   raw_test_pass(0xe661);
3702   raw_test_pass_reg((int)ptr);
3703   raw_test_pass_reg(reallock);
3704   raw_test_pass_reg(targetcore);
3705 #endif
3706
3707   if(targetcore == corenum) {
3708 #ifdef INTERRUPT
3709     raw_user_interrupts_off();
3710 #endif
3711     // reside on this core
3712     if(!RuntimeHashcontainskey(locktbl, reallock)) {
3713       // no locks for this object, something is wrong
3714       raw_test_done(0xa017);
3715     } else {
3716       int rwlock_obj = 0;
3717           struct LockValue * lockvalue = NULL;
3718 #ifdef RAWDEBUG
3719       raw_test_pass(0xe662);
3720 #endif
3721       RuntimeHashget(locktbl, reallock, &rwlock_obj);
3722           lockvalue = (struct LockValue *)rwlock_obj;
3723 #ifdef RAWDEBUG
3724       raw_test_pass_reg(lockvalue->value);
3725 #endif
3726       lockvalue->value++;
3727 #ifdef RAWDEBUG
3728       raw_test_pass_reg(lockvalue->value);
3729 #endif
3730     }
3731 #ifdef INTERRUPT
3732     raw_user_interrupts_on();
3733 #endif
3734     return;
3735   }
3736
3737 #ifdef RAWDEBUG
3738   raw_test_pass(0xe663);
3739 #endif
3740   calCoords(corenum, &self_y, &self_x);
3741   calCoords(targetcore, &target_y, &target_x);
3742   isMsgSending = true;
3743   // Build the message header
3744   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
3745                              self_y, self_x,
3746                              target_y, target_x);
3747   // start sending the msg, set send msg flag
3748   //isMsgSending = true;
3749   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
3750 #ifdef RAWDEBUG
3751   raw_test_pass(0xbbbb);
3752   raw_test_pass(0xb000 + targetcore);
3753 #endif
3754   gdn_send(5);   // lock release
3755  #ifdef RAWDEBUG
3756   raw_test_pass(5);
3757 #endif
3758   gdn_send(1);       // write lock
3759 #ifdef RAWDEBUG
3760   raw_test_pass(1);
3761 #endif
3762   gdn_send((int)ptr);  // obj pointer
3763 #ifdef RAWDEBUG
3764   raw_test_pass_reg(ptr);
3765 #endif
3766   gdn_send(reallock);  // lock
3767 #ifdef RAWDEBUG
3768   raw_test_pass_reg(reallock);
3769   raw_test_pass(0xffff);
3770 #endif
3771   // end of sending this msg, set sand msg flag false
3772   isMsgSending = false;
3773   // check if there are pending msgs
3774   while(isMsgHanging) {
3775     // get the msg from outmsgdata[]
3776     // length + target + msg
3777     outmsgleft = outmsgdata[outmsgindex++];
3778     targetcore = outmsgdata[outmsgindex++];
3779     calCoords(targetcore, &target_y, &target_x);
3780         isMsgSending = true;
3781     // Build the message header
3782     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
3783                                self_y, self_x,
3784                                target_y, target_x);
3785         //isMsgSending = true;
3786     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
3787 #ifdef RAWDEBUG
3788     raw_test_pass(0xbbbb);
3789     raw_test_pass(0xb000 + targetcore);             // targetcore
3790 #endif
3791     while(outmsgleft-- > 0) {
3792       gdn_send(outmsgdata[outmsgindex++]);
3793 #ifdef RAWDEBUG
3794       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
3795 #endif
3796     }
3797 #ifdef RAWDEBUG
3798     raw_test_pass(0xffff);
3799 #endif
3800     isMsgSending = false;
3801 #ifdef INTERRUPT
3802     raw_user_interrupts_off();
3803 #endif
3804     // check if there are still msg hanging
3805     if(outmsgindex == outmsglast) {
3806       // no more msgs
3807       outmsgindex = outmsglast = 0;
3808       isMsgHanging = false;
3809     }
3810 #ifdef INTERRUPT
3811     raw_user_interrupts_on();
3812 #endif
3813   }
3814 #elif defined THREADSIMULATE
3815   int numofcore = pthread_getspecific(key);
3816   int rc = pthread_rwlock_rdlock(&rwlock_tbl);
3817   printf("[releasewritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3818   if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3819     printf("[releasewritelock, %d] Error: try to release a lock without previously grab it\n", numofcore);
3820     exit(-1);
3821   }
3822   pthread_rwlock_t* rwlock_obj = NULL;
3823   RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
3824   int rc_obj = pthread_rwlock_unlock(rwlock_obj);
3825   printf("[releasewritelock, %d] unlocked object %d: %d error:\n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
3826   rc = pthread_rwlock_unlock(&rwlock_tbl);
3827   printf("[releasewritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3828 #endif
3829 }
3830
3831 void releasewritelock_r(void * lock, void * redirectlock) {
3832 #ifdef RAW
3833   unsigned msgHdr;
3834   int self_y, self_x, target_y, target_x;
3835   int targetcore = 0;
3836   // for 32 bit machine, the size is always 4 words
3837   int msgsize = 4;
3838
3839   int reallock = (int)lock;
3840   targetcore = (reallock >> 5) % TOTALCORE;
3841
3842 #ifdef RAWDEBUG
3843   raw_test_pass(0xe671);
3844   raw_test_pass_reg((int)lock);
3845   raw_test_pass_reg(reallock);
3846   raw_test_pass_reg(targetcore);
3847 #endif
3848
3849   if(targetcore == corenum) {
3850 #ifdef INTERRUPT
3851     raw_user_interrupts_off();
3852 #endif
3853     // reside on this core
3854     if(!RuntimeHashcontainskey(locktbl, reallock)) {
3855       // no locks for this object, something is wrong
3856       raw_test_done(0xa018);
3857     } else {
3858       int rwlock_obj = 0;
3859           struct LockValue * lockvalue = NULL;
3860 #ifdef RAWDEBUG
3861       raw_test_pass(0xe672);
3862 #endif
3863       RuntimeHashget(locktbl, reallock, &rwlock_obj);
3864           lockvalue = (struct LockValue *)rwlock_obj;
3865 #ifdef RAWDEBUG
3866       raw_test_pass_reg(lockvalue->value);
3867 #endif
3868       lockvalue->value++;
3869           lockvalue->redirectlock = (int)redirectlock;
3870 #ifdef RAWDEBUG
3871       raw_test_pass_reg(lockvalue->value);
3872 #endif
3873     }
3874 #ifdef INTERRUPT
3875     raw_user_interrupts_on();
3876 #endif
3877     return;
3878   }
3879
3880 #ifdef RAWDEBUG
3881   raw_test_pass(0xe673);
3882 #endif
3883   calCoords(corenum, &self_y, &self_x);
3884   calCoords(targetcore, &target_y, &target_x);
3885   isMsgSending = true;
3886   // Build the message header
3887   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
3888                              self_y, self_x,
3889                              target_y, target_x);
3890   // start sending the msg, set send msg flag
3891   //isMsgSending = true;
3892   gdn_send(msgHdr);                     
3893 #ifdef RAWDEBUG
3894   raw_test_pass(0xbbbb);
3895   raw_test_pass(0xb000 + targetcore);
3896 #endif
3897   gdn_send(0xb);   // lock release with redirect info
3898 #ifdef RAWDEBUG
3899   raw_test_pass(0xb);
3900 #endif
3901   gdn_send(1);       // write lock
3902 #ifdef RAWDEBUG
3903   raw_test_pass(1);
3904 #endif
3905   gdn_send((int)lock); // lock
3906 #ifdef RAWDEBUG
3907   raw_test_pass_reg(lock);
3908 #endif
3909   gdn_send((int)redirectlock); // redirect lock
3910 #ifdef RAWDEBUG
3911   raw_test_pass_reg(redirectlock);
3912   raw_test_pass(0xffff);
3913 #endif
3914   // end of sending this msg, set sand msg flag false
3915   isMsgSending = false;
3916   // check if there are pending msgs
3917   while(isMsgHanging) {
3918     // get the msg from outmsgdata[]
3919     // length + target + msg
3920     outmsgleft = outmsgdata[outmsgindex++];
3921     targetcore = outmsgdata[outmsgindex++];
3922     calCoords(targetcore, &target_y, &target_x);
3923         isMsgSending = true;
3924     // Build the message header
3925     msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
3926                                self_y, self_x,
3927                                target_y, target_x);
3928         //isMsgSending = true;
3929     gdn_send(msgHdr);                           // Send the message header to EAST to handle fab(n - 1).
3930 #ifdef RAWDEBUG
3931     raw_test_pass(0xbbbb);
3932     raw_test_pass(0xb000 + targetcore);             // targetcore
3933 #endif
3934     while(outmsgleft-- > 0) {
3935       gdn_send(outmsgdata[outmsgindex++]);
3936 #ifdef RAWDEBUG
3937       raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
3938 #endif
3939     }
3940 #ifdef RAWDEBUG
3941     raw_test_pass(0xffff);
3942 #endif
3943     isMsgSending = false;
3944 #ifdef INTERRUPT
3945     raw_user_interrupts_off();
3946 #endif
3947     // check if there are still msg hanging
3948     if(outmsgindex == outmsglast) {
3949       // no more msgs
3950       outmsgindex = outmsglast = 0;
3951       isMsgHanging = false;
3952     }
3953 #ifdef INTERRUPT
3954     raw_user_interrupts_on();
3955 #endif
3956   }
3957 #elif defined THREADSIMULATE
3958   // TODO, need modification according to alias lock
3959   int numofcore = pthread_getspecific(key);
3960   int rc = pthread_rwlock_rdlock(&rwlock_tbl);
3961   printf("[releasewritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3962   if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
3963     printf("[releasewritelock, %d] Error: try to release a lock without previously grab it\n", numofcore);
3964     exit(-1);
3965   }
3966   pthread_rwlock_t* rwlock_obj = NULL;
3967   RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
3968   int rc_obj = pthread_rwlock_unlock(rwlock_obj);
3969   printf("[releasewritelock, %d] unlocked object %d: %d error:\n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
3970   rc = pthread_rwlock_unlock(&rwlock_tbl);
3971   printf("[releasewritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
3972 #endif
3973 }
3974
3975 #ifdef RAW
3976 bool getwritelock_I(void * ptr) {
3977   unsigned msgHdr;
3978   int self_y, self_x, target_y, target_x;
3979   int targetcore = 0;
3980   // for 32 bit machine, the size is always 5 words
3981   int msgsize = 5;
3982
3983   lockobj = (int)ptr;
3984   if(((struct ___Object___ *)ptr)->lock == NULL) {
3985         lock2require = lockobj;
3986   } else {
3987         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
3988   }
3989   targetcore = (lock2require >> 5) % TOTALCORE;
3990   lockflag = false;
3991 #ifndef INTERRUPT
3992   reside = false;
3993 #endif
3994   lockresult = 0;
3995
3996 #ifdef RAWDEBUG
3997   raw_test_pass(0xe561);
3998   raw_test_pass_reg(lockobj);
3999   raw_test_pass_reg(lock2require);
4000   raw_test_pass_reg(targetcore);
4001 #endif
4002
4003   if(targetcore == corenum) {
4004     // reside on this core
4005     bool deny = false;
4006     if(!RuntimeHashcontainskey(locktbl, lock2require)) {
4007       // no locks for this object
4008       // first time to operate on this shared object
4009       // create a lock for it
4010       // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
4011 #ifdef RAWDEBUG
4012       raw_test_pass(0xe562);
4013 #endif
4014           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
4015           lockvalue->redirectlock = 0;
4016           lockvalue->value = -1;
4017       RuntimeHashadd_I(locktbl, lock2require, (int)lockvalue);
4018     } else {
4019       int rwlock_obj = 0;
4020           struct LockValue* lockvalue;
4021       RuntimeHashget(locktbl, (int)ptr, &rwlock_obj);
4022           lockvalue = (struct LockValue*)rwlock_obj;
4023 #ifdef RAWDEBUG
4024       raw_test_pass(0xe563);
4025       raw_test_pass_reg(lockvalue->value);
4026 #endif
4027           if(lockvalue->redirectlock != 0) {
4028                   // the lock is redirected
4029 #ifdef RAWDEBUG
4030                   raw_test_pass(0xe564);
4031 #endif
4032                   getwritelock_I_r(ptr, (void *)lockvalue->redirectlock, corenum, false);
4033                   return true;
4034           } else {
4035               if(0 == lockvalue->value) {
4036                           lockvalue->value = -1;
4037                   } else {
4038                           deny = true;
4039                   }
4040           }
4041     }
4042 #ifdef RAWDEBUG
4043     raw_test_pass(0xe565);
4044     raw_test_pass_reg(lockresult);
4045 #endif
4046     if(lockobj == (int)ptr) {
4047       if(deny) {
4048         lockresult = 0;
4049 #ifdef RAWDEBUG
4050         raw_test_pass(0);
4051 #endif
4052       } else {
4053         lockresult = 1;
4054 #ifdef RAWDEBUG
4055         raw_test_pass(1);
4056 #endif
4057       }
4058       lockflag = true;
4059 #ifndef INTERRUPT
4060       reside = true;
4061 #endif
4062     } else {
4063       // conflicts on lockresults
4064       raw_test_done(0xa019);
4065     }
4066     return true;
4067   }
4068
4069 #ifdef RAWDEBUG
4070   raw_test_pass(0xe566);
4071 #endif
4072   calCoords(corenum, &self_y, &self_x);
4073   calCoords(targetcore, &target_y, &target_x);
4074   // Build the message header
4075   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
4076                              self_y, self_x,
4077                              target_y, target_x);
4078   // start sending the msg, set send msg flag
4079   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
4080 #ifdef RAWDEBUG
4081   raw_test_pass(0xbbbb);
4082   raw_test_pass(0xb000 + targetcore);       // targetcore
4083 #endif
4084   gdn_send(2);   // lock request
4085 #ifdef RAWDEBUG
4086   raw_test_pass(2);
4087 #endif
4088   gdn_send(1);       // write lock
4089 #ifdef RAWDEBUG
4090   raw_test_pass(1);
4091 #endif
4092   gdn_send((int)ptr);  // obj pointer
4093 #ifdef RAWDEBUG
4094   raw_test_pass_reg(ptr);
4095 #endif
4096   gdn_send(lock2require); // lock
4097 #ifdef RAWDEBUG
4098   raw_test_pass_reg(lock2require);
4099 #endif
4100   gdn_send(corenum);  // request core
4101 #ifdef RAWDEBUG
4102   raw_test_pass_reg(corenum);
4103   raw_test_pass(0xffff);
4104 #endif
4105   return true;
4106 }
4107
4108 // redirected lock request
4109 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
4110   unsigned msgHdr;
4111   int self_y, self_x, target_y, target_x;
4112   int targetcore = 0;
4113   // for 32 bit machine, the size is always 6 words
4114   int msgsize = 6;
4115
4116   if(core == corenum) {
4117           lockobj = (int)ptr;
4118           lock2require = (int)redirectlock;
4119           lockflag = false;
4120 #ifndef INTERRUPT
4121           reside = false;
4122 #endif
4123           lockresult = 0;
4124   }
4125   targetcore = ((int)redirectlock >> 5) % TOTALCORE;
4126
4127 #ifdef RAWDEBUG
4128   raw_test_pass(0xe571);
4129   raw_test_pass_reg((int)ptr);
4130   raw_test_pass_reg((int)redirectlock);
4131   raw_test_pass_reg(core);
4132   raw_test_pass_reg((int)cache);
4133   raw_test_pass_reg(targetcore);
4134 #endif
4135
4136
4137   if(targetcore == corenum) {
4138     // reside on this core
4139     bool deny = false;
4140     if(!RuntimeHashcontainskey(locktbl, (int)redirectlock)) {
4141       // no locks for this object
4142       // first time to operate on this shared object
4143       // create a lock for it
4144       // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
4145           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
4146           lockvalue->redirectlock = 0;
4147           lockvalue->value = -1;
4148       RuntimeHashadd_I(locktbl, (int)redirectlock, (int)lockvalue);
4149     } else {
4150       int rwlock_obj = 0;
4151           struct LockValue* lockvalue;
4152       RuntimeHashget(locktbl, (int)redirectlock, &rwlock_obj);
4153           lockvalue = (struct LockValue*)rwlock_obj;
4154           if(lockvalue->redirectlock != 0) {
4155                   // the lock is redirected
4156 #ifdef RAWDEBUG
4157                   raw_test_pass(0xe572);
4158 #endif
4159                   getwritelock_I_r(ptr, (void *)lockvalue->redirectlock, core, cache);
4160                   return true;
4161           } else {
4162                   if(0 == lockvalue->value) {
4163                           lockvalue->value = -1;
4164                   } else {
4165                           deny = true;
4166                   }
4167           }
4168     }
4169         if(core == corenum) {
4170         if(lockobj == (int)ptr) {
4171               if(deny) {
4172                 lockresult = 0;
4173               } else {
4174                 lockresult = 1;
4175                 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
4176               }
4177           lockflag = true;
4178 #ifndef INTERRUPT
4179               reside = true;
4180 #endif
4181         } else {
4182               // conflicts on lockresults
4183           raw_test_done(0xa01a);
4184         }
4185             return true;
4186         } else {
4187                 // send lock grant/deny request to the root requiring core
4188                 // check if there is still some msg on sending
4189                 int msgsize1 = 4;
4190                 if((!cache) || (cache && !isMsgSending)) {
4191                         calCoords(corenum, &self_y, &self_x);
4192                         calCoords(core, &target_y, &target_x);
4193                         // Build the message header
4194                         msgHdr = construct_dyn_hdr(0, msgsize1, 0,             // msgsize word sent.
4195                                                            self_y, self_x,
4196                                                                            target_y, target_x);
4197                         gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
4198 #ifdef RAWDEBUG
4199                         raw_test_pass(0xbbbb);
4200                         raw_test_pass(0xb000 + core);       // targetcore
4201 #endif
4202                         if(deny) {
4203                                 // deny
4204                                 gdn_send(0xa);   // lock deny with redirected info
4205 #ifdef RAWDEBUG
4206                                 raw_test_pass(0xa);
4207 #endif
4208                         } else {
4209                                 // grant
4210                                 gdn_send(9);   // lock grant with redirected info
4211 #ifdef RAWDEBUG
4212                                 raw_test_pass(9);
4213 #endif
4214                         }
4215                         gdn_send(1);       // write lock
4216 #ifdef RAWDEBUG
4217                         raw_test_pass(1);
4218 #endif
4219                         gdn_send((int)ptr);  // obj pointer
4220 #ifdef RAWDEBUG
4221                         raw_test_pass_reg(ptr);
4222 #endif
4223                         gdn_send((int)redirectlock); // redirected lock
4224 #ifdef RAWDEBUG
4225                         raw_test_pass_reg((int)redirectlock);
4226                         raw_test_pass(0xffff);
4227 #endif
4228                 } else if(cache && isMsgSending) {
4229                         isMsgHanging = true;
4230                         // cache the msg in outmsgdata and send it later
4231                         // msglength + target core + msg
4232                         outmsgdata[outmsglast++] = msgsize1;
4233                         outmsgdata[outmsglast++] = core;
4234                         if(deny) {
4235                                 outmsgdata[outmsglast++] = 0xa; // deny
4236                         } else {
4237                                 outmsgdata[outmsglast++] = 9; // grant
4238                         }
4239                         outmsgdata[outmsglast++] = 1;
4240                         outmsgdata[outmsglast++] = (int)ptr;
4241                         outmsgdata[outmsglast++] = (int)redirectlock;
4242                 }
4243         }
4244   }
4245
4246   // check if there is still some msg on sending
4247   if((!cache) || (cache && !isMsgSending)) {
4248           calCoords(corenum, &self_y, &self_x);
4249           calCoords(targetcore, &target_y, &target_x);
4250           // Build the message header
4251           msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
4252                                  self_y, self_x,
4253                                      target_y, target_x);
4254           gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
4255 #ifdef RAWDEBUG
4256           raw_test_pass(0xbbbb);
4257           raw_test_pass(0xb000 + targetcore);       // targetcore
4258 #endif
4259           gdn_send(8);   // redirected lock request
4260 #ifdef RAWDEBUG
4261           raw_test_pass(8);
4262 #endif
4263           gdn_send(1);       // write lock
4264 #ifdef RAWDEBUG
4265           raw_test_pass(1);
4266 #endif
4267           gdn_send((int)ptr);  // obj pointer
4268 #ifdef RAWDEBUG
4269           raw_test_pass_reg(ptr);
4270 #endif
4271           gdn_send((int)redirectlock); // redirected lock
4272 #ifdef RAWDEBUG
4273           raw_test_pass_reg((int)redirectlock);
4274 #endif
4275           gdn_send(core);  // root request core
4276 #ifdef RAWDEBUG
4277           raw_test_pass_reg(core);
4278 #endif
4279           gdn_send(corenum);  // request core
4280 #ifdef RAWDEBUG
4281           raw_test_pass_reg(corenum);
4282           raw_test_pass(0xffff);
4283 #endif
4284   } else if(cache && isMsgSending) {
4285           isMsgHanging = true;
4286           // cache the msg in outmsgdata and send it later
4287           // msglength + target core + msg
4288           outmsgdata[outmsglast++] = msgsize;
4289           outmsgdata[outmsglast++] = targetcore;
4290           outmsgdata[outmsglast++] = 8;
4291           outmsgdata[outmsglast++] = 1;
4292           outmsgdata[outmsglast++] = (int)ptr;
4293           outmsgdata[outmsglast++] = (int)redirectlock;
4294           outmsgdata[outmsglast++] = core;
4295           outmsgdata[outmsglast++] = corenum;
4296   }
4297   return true;
4298 }
4299
4300 void releasewritelock_I(void * ptr) {
4301   unsigned msgHdr;
4302   int self_y, self_x, target_y, target_x;
4303   int targetcore = 0;
4304   // for 32 bit machine, the size is always 4 words
4305   int msgsize = 4;
4306
4307   int reallock = 0;
4308   if(((struct ___Object___ *)ptr)->lock == NULL) {
4309         reallock = (int)ptr;
4310   } else {
4311         reallock = (int)(((struct ___Object___ *)ptr)->lock);
4312   }
4313   targetcore = (reallock >> 5) % TOTALCORE;
4314
4315 #ifdef RAWDEBUG
4316   raw_test_pass(0xe681);
4317   raw_test_pass_reg((int)ptr);
4318   raw_test_pass_reg(reallock);
4319   raw_test_pass_reg(targetcore);
4320 #endif
4321
4322   if(targetcore == corenum) {
4323     // reside on this core
4324     if(!RuntimeHashcontainskey(locktbl, reallock)) {
4325       // no locks for this object, something is wrong
4326       raw_test_done(0xa01b);
4327     } else {
4328       int rwlock_obj = 0;
4329           struct LockValue * lockvalue = NULL;
4330       RuntimeHashget(locktbl, reallock, &rwlock_obj);
4331           lockvalue = (struct LockValue *)rwlock_obj;
4332       lockvalue->value++;
4333     }
4334     return;
4335   }
4336
4337   calCoords(corenum, &self_y, &self_x);
4338   calCoords(targetcore, &target_y, &target_x);
4339   // Build the message header
4340   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
4341                              self_y, self_x,
4342                              target_y, target_x);
4343   gdn_send(msgHdr);                     // Send the message header to EAST to handle fab(n - 1).
4344 #ifdef RAWDEBUG
4345   raw_test_pass(0xbbbb);
4346   raw_test_pass(0xb000 + targetcore);       // targetcore
4347 #endif
4348   gdn_send(5);   // lock release
4349 #ifdef RAWDEBUG
4350   raw_test_pass(5);
4351 #endif
4352   gdn_send(1);       // write lock
4353 #ifdef RAWDEBUG
4354   raw_test_pass(1);
4355 #endif
4356   gdn_send((int)ptr);  // obj pointer
4357 #ifdef RAWDEBUG
4358   raw_test_pass_reg(ptr);
4359 #endif
4360   gdn_send(reallock);  // lock
4361 #ifdef RAWDEBUG
4362   raw_test_pass_reg(reallock);
4363   raw_test_pass(0xffff);
4364 #endif
4365 }
4366
4367 void releasewritelock_I_r(void * lock, void * redirectlock) {
4368   unsigned msgHdr;
4369   int self_y, self_x, target_y, target_x;
4370   int targetcore = 0;
4371   // for 32 bit machine, the size is always 4 words
4372   int msgsize = 4;
4373
4374   int reallock = (int)lock;
4375   targetcore = (reallock >> 5) % TOTALCORE;
4376
4377 #ifdef RAWDEBUG
4378   raw_test_pass(0xe691);
4379   raw_test_pass_reg((int)lock);
4380   raw_test_pass_reg(reallock);
4381   raw_test_pass_reg(targetcore);
4382 #endif
4383
4384   if(targetcore == corenum) {
4385     // reside on this core
4386     if(!RuntimeHashcontainskey(locktbl, reallock)) {
4387       // no locks for this object, something is wrong
4388       raw_test_done(0xa01c);
4389     } else {
4390       int rwlock_obj = 0;
4391           struct LockValue * lockvalue = NULL;
4392 #ifdef RAWDEBUG
4393       raw_test_pass(0xe692);
4394 #endif
4395       RuntimeHashget(locktbl, reallock, &rwlock_obj);
4396           lockvalue = (struct LockValue *)rwlock_obj;
4397 #ifdef RAWDEBUG
4398       raw_test_pass_reg(lockvalue->value);
4399 #endif
4400       lockvalue->value++;
4401           lockvalue->redirectlock = (int)redirectlock;
4402 #ifdef RAWDEBUG
4403       raw_test_pass_reg(lockvalue->value);
4404 #endif
4405     }
4406     return;
4407   }
4408
4409 #ifdef RAWDEBUG
4410   raw_test_pass(0xe693);
4411 #endif
4412           calCoords(corenum, &self_y, &self_x);
4413           calCoords(targetcore, &target_y, &target_x);
4414           // Build the message header
4415           msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
4416                                  self_y, self_x,
4417                                      target_y, target_x);
4418           // start sending the msg, set send msg flag
4419           gdn_send(msgHdr);                     
4420 #ifdef RAWDEBUG
4421           raw_test_pass(0xbbbb);
4422           raw_test_pass(0xb000 + targetcore);
4423 #endif
4424           gdn_send(0xb);   // lock release with redirect info
4425 #ifdef RAWDEBUG
4426           raw_test_pass(0xb);
4427 #endif
4428           gdn_send(1);       // write lock
4429 #ifdef RAWDEBUG
4430           raw_test_pass(1);
4431 #endif
4432           gdn_send((int)lock); // lock
4433 #ifdef RAWDEBUG
4434           raw_test_pass_reg(lock);
4435 #endif
4436           gdn_send((int)redirectlock); // redirect lock
4437 #ifdef RAWDEBUG
4438           raw_test_pass_reg(redirectlock);
4439           raw_test_pass(0xffff);
4440 #endif
4441 }
4442 #endif
4443
4444 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
4445   void * taskpointerarray[MAXTASKPARAMS];
4446   int j;
4447   int numparams=parameter->task->numParameters;
4448   int numiterators=parameter->task->numTotal-1;
4449   int retval=1;
4450   int addnormal=1;
4451   int adderror=1;
4452
4453   struct taskdescriptor * task=parameter->task;
4454
4455   ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);      //this add the object to parameterwrapper
4456
4457   /* Add enqueued object to parameter vector */
4458   taskpointerarray[parameter->slot]=ptr;
4459
4460   /* Reset iterators */
4461   for(j=0; j<numiterators; j++) {
4462     toiReset(&parameter->iterators[j]);
4463   }
4464
4465   /* Find initial state */
4466   for(j=0; j<numiterators; j++) {
4467 backtrackinit:
4468     if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
4469       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
4470     else if (j>0) {
4471       /* Need to backtrack */
4472       toiReset(&parameter->iterators[j]);
4473       j--;
4474       goto backtrackinit;
4475     } else {
4476       /* Nothing to enqueue */
4477       return retval;
4478     }
4479   }
4480
4481
4482   while(1) {
4483     /* Enqueue current state */
4484     int launch = 0;
4485     struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
4486     tpd->task=task;
4487     tpd->numParameters=numiterators+1;
4488     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
4489     for(j=0; j<=numiterators; j++) {
4490       tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
4491     }
4492     /* Enqueue task */
4493     if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
4494       genputtable(activetasks, tpd, tpd);
4495     } else {
4496       RUNFREE(tpd->parameterArray);
4497       RUNFREE(tpd);
4498     }
4499
4500     /* This loop iterates to the next parameter combination */
4501     if (numiterators==0)
4502       return retval;
4503
4504     for(j=numiterators-1; j<numiterators; j++) {
4505 backtrackinc:
4506       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
4507         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
4508       else if (j>0) {
4509         /* Need to backtrack */
4510         toiReset(&parameter->iterators[j]);
4511         j--;
4512         goto backtrackinc;
4513       } else {
4514         /* Nothing more to enqueue */
4515         return retval;
4516       }
4517     }
4518   }
4519   return retval;
4520 }
4521
4522 #ifdef RAW
4523 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
4524   void * taskpointerarray[MAXTASKPARAMS];
4525   int j;
4526   int numparams=parameter->task->numParameters;
4527   int numiterators=parameter->task->numTotal-1;
4528   int retval=1;
4529   int addnormal=1;
4530   int adderror=1;
4531
4532   struct taskdescriptor * task=parameter->task;
4533
4534   ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);      //this add the object to parameterwrapper
4535
4536   /* Add enqueued object to parameter vector */
4537   taskpointerarray[parameter->slot]=ptr;
4538
4539   /* Reset iterators */
4540   for(j=0; j<numiterators; j++) {
4541     toiReset(&parameter->iterators[j]);
4542   }
4543
4544   /* Find initial state */
4545   for(j=0; j<numiterators; j++) {
4546 backtrackinit:
4547     if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
4548       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
4549     else if (j>0) {
4550       /* Need to backtrack */
4551       toiReset(&parameter->iterators[j]);
4552       j--;
4553       goto backtrackinit;
4554     } else {
4555       /* Nothing to enqueue */
4556       return retval;
4557     }
4558   }
4559
4560   while(1) {
4561     /* Enqueue current state */
4562     int launch = 0;
4563     struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
4564     tpd->task=task;
4565     tpd->numParameters=numiterators+1;
4566     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
4567     for(j=0; j<=numiterators; j++) {
4568       tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
4569     }
4570     /* Enqueue task */
4571     if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
4572       genputtable_I(activetasks, tpd, tpd);
4573     } else {
4574       RUNFREE(tpd->parameterArray);
4575       RUNFREE(tpd);
4576     }
4577
4578     /* This loop iterates to the next parameter combination */
4579     if (numiterators==0)
4580       return retval;
4581
4582     for(j=numiterators-1; j<numiterators; j++) {
4583 backtrackinc:
4584       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
4585         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
4586       else if (j>0) {
4587         /* Need to backtrack */
4588         toiReset(&parameter->iterators[j]);
4589         j--;
4590         goto backtrackinc;
4591       } else {
4592         /* Nothing more to enqueue */
4593         return retval;
4594       }
4595     }
4596   }
4597   return retval;
4598 }
4599 #endif
4600
4601 /* Handler for signals. The signals catch null pointer errors and
4602    arithmatic errors. */
4603 #ifndef RAW
4604 void myhandler(int sig, siginfo_t *info, void *uap) {
4605   sigset_t toclear;
4606 #ifdef DEBUG
4607   printf("sig=%d\n",sig);
4608   printf("signal\n");
4609 #endif
4610   sigemptyset(&toclear);
4611   sigaddset(&toclear, sig);
4612   sigprocmask(SIG_UNBLOCK, &toclear,NULL);
4613   longjmp(error_handler,1);
4614 }
4615 #endif
4616
4617 fd_set readfds;
4618 int maxreadfd;
4619 struct RuntimeHash *fdtoobject;
4620
4621 void addreadfd(int fd) {
4622   if (fd>=maxreadfd)
4623     maxreadfd=fd+1;
4624   FD_SET(fd, &readfds);
4625 }
4626
4627 void removereadfd(int fd) {
4628   FD_CLR(fd, &readfds);
4629   if (maxreadfd==(fd+1)) {
4630     maxreadfd--;
4631     while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
4632       maxreadfd--;
4633   }
4634 }
4635
4636 #ifdef PRECISE_GC
4637 #define OFFSET 2
4638 #else
4639 #define OFFSET 0
4640 #endif
4641
4642 void executetasks() {
4643   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
4644   int numparams=0;
4645   int numtotal=0;
4646   struct ___Object___ * tmpparam = NULL;
4647   struct parameterdescriptor * pd=NULL;
4648   struct parameterwrapper *pw=NULL;
4649   int j = 0;
4650   int x = 0;
4651   bool islock = true;
4652
4653 #ifdef RAW
4654   struct LockValue * locks[MAXTASKPARAMS];
4655   int locklen;
4656   int grount = 0;
4657   int andmask=0;
4658   int checkmask=0;
4659
4660   for(j = 0; j < MAXTASKPARAMS; j++) {
4661           locks[j] = (struct LockValue *)(RUNMALLOC(sizeof(struct LockValue)));
4662           locks[j]->redirectlock = 0;
4663           locks[j]->value = 0;
4664   }
4665 #endif
4666
4667 #ifndef RAW
4668   /* Set up signal handlers */
4669   struct sigaction sig;
4670   sig.sa_sigaction=&myhandler;
4671   sig.sa_flags=SA_SIGINFO;
4672   sigemptyset(&sig.sa_mask);
4673
4674   /* Catch bus errors, segmentation faults, and floating point exceptions*/
4675   sigaction(SIGBUS,&sig,0);
4676   sigaction(SIGSEGV,&sig,0);
4677   sigaction(SIGFPE,&sig,0);
4678   sigaction(SIGPIPE,&sig,0);
4679 #endif
4680
4681 #ifndef RAW
4682   /* Zero fd set */
4683   FD_ZERO(&readfds);
4684 #endif
4685   maxreadfd=0;
4686 #ifndef RAW
4687   fdtoobject=allocateRuntimeHash(100);
4688 #endif
4689
4690 #ifndef RAW
4691   /* Map first block of memory to protected, anonymous page */
4692   mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
4693 #endif
4694
4695 newtask:
4696   while((hashsize(activetasks)>0)||(maxreadfd>0)) {
4697
4698 #ifdef RAW
4699 #ifdef RAWDEBUG
4700     raw_test_pass(0xe990);
4701 #endif
4702 #else
4703     /* Check if any filedescriptors have IO pending */
4704     if (maxreadfd>0) {
4705       int i;
4706       struct timeval timeout={0,0};
4707       fd_set tmpreadfds;
4708       int numselect;
4709       tmpreadfds=readfds;
4710       numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
4711       if (numselect>0) {
4712         /* Process ready fd's */
4713         int fd;
4714         for(fd=0; fd<maxreadfd; fd++) {
4715           if (FD_ISSET(fd, &tmpreadfds)) {
4716             /* Set ready flag on object */
4717             void * objptr;
4718             //      printf("Setting fd %d\n",fd);
4719             if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
4720               if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
4721                 enqueueObject(objptr, NULL, 0);
4722               }
4723             }
4724           }
4725         }
4726       }
4727     }
4728 #endif
4729
4730     /* See if there are any active tasks */
4731     if (hashsize(activetasks)>0) {
4732       int i;
4733 #ifdef RAWPROFILE
4734       if(!taskInfoOverflow) {
4735         TaskInfo* checkTaskInfo = RUNMALLOC(sizeof(struct task_info));
4736         taskInfoArray[taskInfoIndex] = checkTaskInfo;
4737         checkTaskInfo->taskName = "tpd checking";
4738         checkTaskInfo->startTime = raw_get_cycle();
4739         checkTaskInfo->endTime = -1;
4740         checkTaskInfo->exitIndex = -1;
4741         checkTaskInfo->newObjs = NULL;
4742       }
4743 #endif
4744           busystatus = true;
4745       currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
4746       genfreekey(activetasks, currtpd);
4747
4748       numparams=currtpd->task->numParameters;
4749       numtotal=currtpd->task->numTotal;
4750
4751 #ifdef THREADSIMULATE
4752       int isolateflags[numparams];
4753 #endif
4754
4755          // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
4756 #ifdef RAW
4757           // get all required locks
4758           locklen = 0;
4759           // check which locks are needed
4760           for(i = 0; i < numparams; i++) {
4761                   void * param = currtpd->parameterArray[i];
4762                   int tmplock = 0;
4763                   int j = 0;
4764                   bool insert = true;
4765                   if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
4766                           islock = false;
4767                           taskpointerarray[i+OFFSET]=param;
4768                           goto execute;
4769                   }
4770                   if(((struct ___Object___ *)param)->lock == NULL) {
4771                           tmplock = (int)param;
4772                   } else {
4773                           tmplock = (int)(((struct ___Object___ *)param)->lock);
4774                   }
4775                   // insert into the locks array
4776                   for(j = 0; j < locklen; j++) {
4777                           if(locks[j]->value == tmplock) {
4778                                   insert = false;
4779                                   break;
4780                           } else if(locks[j]->value > tmplock) {
4781                                   break;
4782                           }
4783                   }
4784                   if(insert) {
4785                           int h = locklen;
4786                           for(; h > j; h--) {
4787                                   locks[h]->redirectlock = locks[h-1]->redirectlock;
4788                                   locks[h]->value = locks[h-1]->value;
4789                           }
4790                           locks[j]->value = tmplock;
4791                           locks[j]->redirectlock = (int)param;
4792                           locklen++;
4793                   }               
4794           }
4795           // grab these required locks
4796 #ifdef RAWDEBUG
4797           raw_test_pass(0xe991);
4798 #endif
4799           for(i = 0; i < locklen; i++) {
4800                   int * lock = (int *)(locks[i]->redirectlock);
4801                   islock = true;
4802                   // require locks for this parameter if it is not a startup object
4803 #ifdef RAWDEBUG
4804                   raw_test_pass_reg((int)lock);
4805                   raw_test_pass_reg((int)(locks[i]->value));
4806 #endif
4807                   getwritelock(lock);
4808
4809 #ifdef INTERRUPT
4810                   raw_user_interrupts_off();
4811 #endif
4812 #ifdef RAWPROFILE
4813                   //isInterrupt = false;
4814 #endif 
4815                   while(!lockflag) { 
4816                           receiveObject();
4817                   }
4818 #ifndef INTERRUPT
4819                   if(reside) {
4820                           while(receiveObject() != -1) {
4821                           }
4822                   }
4823 #endif
4824                   grount = lockresult;
4825
4826                   lockresult = 0;
4827                   lockobj = 0;
4828                   lock2require = 0;
4829                   lockflag = false;
4830 #ifndef INTERRUPT
4831                   reside = false;
4832 #endif
4833 #ifdef RAWPROFILE
4834                   //isInterrupt = true;
4835 #endif
4836 #ifdef INTERRUPT
4837                   raw_user_interrupts_on();
4838 #endif
4839
4840                   if(grount == 0) {
4841                           int j = 0;
4842 #ifdef RAWDEBUG
4843                           raw_test_pass(0xe992);
4844 #endif
4845                           // can not get the lock, try later
4846                           // releas all grabbed locks for previous parameters
4847                           for(j = 0; j < i; ++j) {
4848                                   lock = (int*)(locks[j]->redirectlock);
4849                                   releasewritelock(lock);
4850                           }
4851                           genputtable(activetasks, currtpd, currtpd);
4852                           if(hashsize(activetasks) == 1) {
4853                                   // only one task right now, wait a little while before next try
4854                                   int halt = 10000;
4855                                   while(halt--) {
4856                                   }
4857                           }
4858 #ifdef RAWPROFILE
4859                           // fail, set the end of the checkTaskInfo
4860                           if(!taskInfoOverflow) {
4861                                   taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
4862                                   taskInfoIndex++;
4863                                   if(taskInfoIndex == TASKINFOLENGTH) {
4864                                           taskInfoOverflow = true;
4865                                   }
4866                           }
4867 #endif
4868                           goto newtask;
4869                   }
4870           }
4871 #elif defined THREADSIMULATE
4872           // TODO: need modification according to added alias locks
4873 #endif
4874
4875 #ifdef RAWDEBUG
4876         raw_test_pass(0xe993);
4877 #endif
4878       /* Make sure that the parameters are still in the queues */
4879       for(i=0; i<numparams; i++) {
4880         void * parameter=currtpd->parameterArray[i];
4881 #ifdef RAW
4882
4883         // flush the object
4884 #ifdef RAWCACHEFLUSH
4885         {
4886           raw_invalidate_cache_range((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
4887         }
4888 #ifdef INTERRUPT
4889                   raw_user_interrupts_off();
4890 #endif
4891         /*if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
4892                 int redirectlock_r = 0;
4893                 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
4894                 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
4895                 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
4896         }*/
4897 #ifdef INTERRUPT
4898                   raw_user_interrupts_on();
4899 #endif
4900 #endif
4901 #endif
4902         tmpparam = (struct ___Object___ *)parameter;
4903 #ifdef THREADSIMULATE
4904         if(0 == tmpparam->isolate) {
4905           isolateflags[i] = 0;
4906           // shared object, need to flush with current value
4907           // TODO: need modification according to added alias locks
4908           if(!getwritelock(tmpparam->original)) {
4909             // fail to get write lock, release all obtained locks and try this task later
4910             int j = 0;
4911             for(j = 0; j < i; ++j) {
4912               if(0 == isolateflags[j]) {
4913                 releasewritelock(((struct ___Object___ *)taskpointerarray[j+OFFSET])->original);
4914               }
4915             }
4916             genputtable(activetasks, currtpd, currtpd);
4917             goto newtask;
4918           }
4919           if(tmpparam->version != tmpparam->original->version) {
4920             // release all obtained locks
4921             int j = 0;
4922             for(j = 0; j < i; ++j) {
4923               if(0 == isolateflags[j]) {
4924                 releasewritelock(((struct ___Object___ *)taskpointerarray[j+OFFSET])->original);
4925               }
4926             }
4927             releasewritelock(tmpparam->original);
4928
4929             // dequeue this object
4930             int numofcore = pthread_getspecific(key);
4931             struct parameterwrapper ** queues = objectqueues[numofcore][tmpparam->type];
4932             int length = numqueues[numofcore][tmpparam->type];
4933             for(j = 0; j < length; ++j) {
4934               struct parameterwrapper * pw = queues[j];
4935               if(ObjectHashcontainskey(pw->objectset, (int)tmpparam)) {
4936                 int next;
4937                 int UNUSED, UNUSED2;
4938                 int * enterflags;
4939                 ObjectHashget(pw->objectset, (int) tmpparam, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
4940                 ObjectHashremove(pw->objectset, (int)tmpparam);
4941                 if (enterflags!=NULL)
4942                   free(enterflags);
4943               }
4944             }
4945             // Free up task parameter descriptor
4946             RUNFREE(currtpd->parameterArray);
4947             RUNFREE(currtpd);
4948             goto newtask;
4949           }
4950         } else {
4951           isolateflags[i] = 1;
4952         }
4953 #endif
4954         pd=currtpd->task->descriptorarray[i];
4955         pw=(struct parameterwrapper *) pd->queue;
4956         /* Check that object is still in queue */
4957         {
4958           if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
4959 #ifdef RAWDEBUG
4960             raw_test_pass(0xe994);
4961 #endif
4962             // release grabbed locks
4963 #ifdef RAW
4964             for(j = 0; j < locklen; ++j) {
4965                 int * lock = (int *)(locks[j]->redirectlock);
4966                 releasewritelock(lock);
4967             }
4968 #elif defined THREADSIMULATE
4969 #endif
4970             RUNFREE(currtpd->parameterArray);
4971             RUNFREE(currtpd);
4972             goto newtask;
4973           }
4974         }
4975 #ifdef RAW
4976         /* Check if the object's flags still meets requirements */
4977         {
4978           int tmpi = 0;
4979           bool ismet = false;
4980           for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
4981             andmask=pw->intarray[tmpi*2];
4982             checkmask=pw->intarray[tmpi*2+1];
4983             if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
4984               ismet = true;
4985               break;
4986             }
4987           }
4988           if (!ismet) {
4989             // flags are never suitable
4990             // remove this obj from the queue
4991             int next;
4992             int UNUSED, UNUSED2;
4993             int * enterflags;
4994 #ifdef RAWDEBUG
4995             raw_test_pass(0xe995);
4996 #endif
4997             ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
4998             ObjectHashremove(pw->objectset, (int)parameter);
4999             if (enterflags!=NULL)
5000               free(enterflags);
5001             // release grabbed locks
5002             for(j = 0; j < locklen; ++j) {
5003                  int * lock = (int *)(locks[j]->redirectlock);
5004                 releasewritelock(lock);
5005             }
5006             RUNFREE(currtpd->parameterArray);
5007             RUNFREE(currtpd);
5008 #ifdef RAWPROFILE
5009             // fail, set the end of the checkTaskInfo
5010             if(!taskInfoOverflow) {
5011               taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
5012               taskInfoIndex++;
5013               if(taskInfoIndex == TASKINFOLENGTH) {
5014                 taskInfoOverflow = true;
5015               }
5016             }
5017 #endif
5018             goto newtask;
5019           }
5020         }
5021 #endif
5022 parameterpresent:
5023         ;
5024         /* Check that object still has necessary tags */
5025         for(j=0; j<pd->numbertags; j++) {
5026           int slotid=pd->tagarray[2*j]+numparams;
5027           struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
5028           if (!containstag(parameter, tagd)) {
5029 #ifdef RAWDEBUG
5030             raw_test_pass(0xe996);
5031 #endif
5032                 {
5033                 // release grabbed locks
5034                 int tmpj = 0;
5035             for(tmpj = 0; tmpj < locklen; ++tmpj) {
5036                  int * lock = (int *)(locks[tmpj]->redirectlock);
5037                 releasewritelock(lock);
5038             }
5039                 }
5040             RUNFREE(currtpd->parameterArray);
5041             RUNFREE(currtpd);
5042             goto newtask;
5043           }
5044         }
5045
5046         taskpointerarray[i+OFFSET]=parameter;
5047       }
5048       /* Copy the tags */
5049       for(; i<numtotal; i++) {
5050         taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
5051       }
5052
5053 #ifdef THREADSIMULATE
5054       for(i = 0; i < numparams; ++i) {
5055         if(0 == isolateflags[i]) {
5056           struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
5057           if(tmpparam != tmpparam->original) {
5058             taskpointerarray[i+OFFSET] = tmpparam->original;
5059           }
5060         }
5061       }
5062 #endif
5063
5064       {
5065 #if 0
5066 #ifndef RAW
5067         /* Checkpoint the state */
5068         forward=allocateRuntimeHash(100);
5069         reverse=allocateRuntimeHash(100);
5070         //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
5071 #endif
5072 #endif
5073         if (x=setjmp(error_handler)) {
5074           int counter;
5075           /* Recover */
5076 #ifndef RAW
5077 #ifdef DEBUG
5078           printf("Fatal Error=%d, Recovering!\n",x);
5079 #endif
5080 #endif
5081           /*
5082              genputtable(failedtasks,currtpd,currtpd);
5083              //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
5084
5085              freeRuntimeHash(forward);
5086              freeRuntimeHash(reverse);
5087              freemalloc();
5088              forward=NULL;
5089              reverse=NULL;
5090            */
5091           //fflush(stdout);
5092 #ifdef RAW
5093           raw_test_pass_reg(x);
5094           raw_test_done(0xa01d);
5095 #else
5096           exit(-1);
5097 #endif
5098         } else {
5099           /*if (injectfailures) {
5100              if ((((double)random())/RAND_MAX)<failurechance) {
5101               printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
5102               longjmp(error_handler,10);
5103              }
5104              }*/
5105           /* Actually call task */
5106 #ifdef PRECISE_GC
5107           ((int *)taskpointerarray)[0]=currtpd->numParameters;
5108           taskpointerarray[1]=NULL;
5109 #endif
5110 execute:
5111 #ifdef RAWPROFILE
5112           {
5113             // check finish, set the end of the checkTaskInfo
5114             if(!taskInfoOverflow) {
5115               taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
5116               taskInfoIndex++;
5117               if(taskInfoIndex == TASKINFOLENGTH) {
5118                 taskInfoOverflow = true;
5119               }
5120             }
5121           }
5122           if(!taskInfoOverflow) {
5123             // new a taskInfo for the task execution
5124             TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
5125             taskInfoArray[taskInfoIndex] = taskInfo;
5126             taskInfo->taskName = currtpd->task->name;
5127             taskInfo->startTime = raw_get_cycle();
5128             taskInfo->endTime = -1;
5129                 taskInfo->exitIndex = -1;
5130                 taskInfo->newObjs = NULL;
5131           }
5132 #endif
5133
5134           if(debugtask) {
5135 #ifndef RAW
5136             printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
5137 #endif
5138             ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
5139 #ifndef RAW
5140             printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
5141 #endif
5142           } else {
5143 #ifdef RAWDEBUG
5144                   raw_test_pass(0xe997);
5145 #endif
5146             ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
5147           }
5148 #ifdef RAWPROFILE
5149           // task finish, set the end of the checkTaskInfo
5150           if(!taskInfoOverflow) {
5151             taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
5152             taskInfoIndex++;
5153             if(taskInfoIndex == TASKINFOLENGTH) {
5154               taskInfoOverflow = true;
5155             }
5156           }
5157           // new a PostTaskInfo for the post-task execution
5158           if(!taskInfoOverflow) {
5159             TaskInfo* postTaskInfo = RUNMALLOC(sizeof(struct task_info));
5160             taskInfoArray[taskInfoIndex] = postTaskInfo;
5161             postTaskInfo->taskName = "post task execution";
5162             postTaskInfo->startTime = raw_get_cycle();
5163             postTaskInfo->endTime = -1;
5164                 postTaskInfo->exitIndex = -1;
5165                 postTaskInfo->newObjs = NULL;
5166           }
5167 #endif
5168 #ifdef RAWDEBUG
5169           raw_test_pass(0xe998);
5170           raw_test_pass_reg(islock);
5171 #endif
5172
5173           if(islock) {
5174 #ifdef RAW
5175 #ifdef RAWDEBUG
5176                   raw_test_pass(0xe999);
5177 #endif
5178             for(i = 0; i < locklen; ++i) {
5179                   void * ptr = (void *)(locks[i]->redirectlock);
5180               int * lock = (int *)(locks[i]->value);
5181 #ifdef RAWDEBUG
5182                   raw_test_pass_reg((int)ptr);
5183                   raw_test_pass_reg((int)lock);
5184 #endif
5185                   if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
5186                           int redirectlock;
5187                           RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
5188                           RuntimeHashremovekey(lockRedirectTbl, (int)lock);
5189                           releasewritelock_r(lock, (int *)redirectlock);
5190                   } else {
5191                 releasewritelock(ptr);
5192                   }
5193             }
5194 #elif defined THREADSIMULATE
5195                 // TODO : need modification for alias lock
5196             for(i = 0; i < numparams; ++i) {
5197               int * lock;
5198               if(0 == isolateflags[i]) {
5199                 struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
5200                 if(tmpparam->lock == NULL) {
5201                   lock = (int*)tmpparam;
5202                 } else {
5203                   lock = tmpparam->lock;
5204                 }
5205                   releasewritelock(lock);
5206               }
5207             }
5208 #endif
5209           }
5210
5211 #ifdef RAWPROFILE
5212           // post task execution finish, set the end of the postTaskInfo
5213           if(!taskInfoOverflow) {
5214             taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
5215             taskInfoIndex++;
5216             if(taskInfoIndex == TASKINFOLENGTH) {
5217               taskInfoOverflow = true;
5218             }
5219           }
5220 #endif
5221
5222 #if 0
5223 #ifndef RAW
5224           freeRuntimeHash(forward);
5225           freeRuntimeHash(reverse);
5226           freemalloc();
5227 #endif
5228 #endif
5229           // Free up task parameter descriptor
5230           RUNFREE(currtpd->parameterArray);
5231           RUNFREE(currtpd);
5232 #if 0
5233 #ifndef RAW
5234           forward=NULL;
5235           reverse=NULL;
5236 #endif
5237 #endif
5238 #ifdef RAWDEBUG
5239           raw_test_pass(0xe99a);
5240 #endif
5241         }
5242       }
5243     }
5244   }
5245 #ifdef RAWDEBUG
5246   raw_test_pass(0xe99b);
5247 #endif
5248 }
5249
5250 /* This function processes an objects tags */
5251 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
5252   int i;
5253
5254   for(i=0; i<pd->numbertags; i++) {
5255     int slotid=pd->tagarray[2*i];
5256     int tagid=pd->tagarray[2*i+1];
5257
5258     if (statusarray[slotid+numparams]==0) {
5259       parameter->iterators[*iteratorcount].istag=1;
5260       parameter->iterators[*iteratorcount].tagid=tagid;
5261       parameter->iterators[*iteratorcount].slot=slotid+numparams;
5262       parameter->iterators[*iteratorcount].tagobjectslot=index;
5263       statusarray[slotid+numparams]=1;
5264       (*iteratorcount)++;
5265     }
5266   }
5267 }
5268
5269
5270 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
5271   int i;
5272   int tagcount=0;
5273   struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
5274
5275   parameter->iterators[*iteratorcount].istag=0;
5276   parameter->iterators[*iteratorcount].slot=index;
5277   parameter->iterators[*iteratorcount].objectset=objectset;
5278   statusarray[index]=1;
5279
5280   for(i=0; i<pd->numbertags; i++) {
5281     int slotid=pd->tagarray[2*i];
5282     int tagid=pd->tagarray[2*i+1];
5283     if (statusarray[slotid+numparams]!=0) {
5284       /* This tag has already been enqueued, use it to narrow search */
5285       parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
5286       tagcount++;
5287     }
5288   }
5289   parameter->iterators[*iteratorcount].numtags=tagcount;
5290
5291   (*iteratorcount)++;
5292 }
5293
5294 /* This function builds the iterators for a task & parameter */
5295
5296 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
5297   int statusarray[MAXTASKPARAMS];
5298   int i;
5299   int numparams=task->numParameters;
5300   int iteratorcount=0;
5301   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
5302
5303   statusarray[index]=1; /* Initial parameter */
5304   /* Process tags for initial iterator */
5305
5306   processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
5307
5308   while(1) {
5309 loopstart:
5310     /* Check for objects with existing tags */
5311     for(i=0; i<numparams; i++) {
5312       if (statusarray[i]==0) {
5313         struct parameterdescriptor *pd=task->descriptorarray[i];
5314         int j;
5315         for(j=0; j<pd->numbertags; j++) {
5316           int slotid=pd->tagarray[2*j];
5317           if(statusarray[slotid+numparams]!=0) {
5318             processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
5319             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
5320             goto loopstart;
5321           }
5322         }
5323       }
5324     }
5325
5326     /* Next do objects w/ unbound tags*/
5327
5328     for(i=0; i<numparams; i++) {
5329       if (statusarray[i]==0) {
5330         struct parameterdescriptor *pd=task->descriptorarray[i];
5331         if (pd->numbertags>0) {
5332           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
5333           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
5334           goto loopstart;
5335         }
5336       }
5337     }
5338
5339     /* Nothing with a tag enqueued */
5340
5341     for(i=0; i<numparams; i++) {
5342       if (statusarray[i]==0) {
5343         struct parameterdescriptor *pd=task->descriptorarray[i];
5344         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
5345         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
5346         goto loopstart;
5347       }
5348     }
5349
5350     /* Nothing left */
5351     return;
5352   }
5353 }
5354
5355 void printdebug() {
5356   int i;
5357   int j;
5358 #ifdef THREADSIMULATE
5359   int numofcore = pthread_getspecific(key);
5360   for(i=0; i<numtasks[numofcore]; i++) {
5361     struct taskdescriptor * task=taskarray[numofcore][i];
5362 #else
5363 #ifdef RAW
5364   if(corenum > NUMCORES - 1) {
5365     return;
5366   }
5367 #endif
5368   for(i=0; i<numtasks[corenum]; i++) {
5369     struct taskdescriptor * task=taskarray[corenum][i];
5370 #endif
5371 #ifndef RAW
5372     printf("%s\n", task->name);
5373 #endif
5374     for(j=0; j<task->numParameters; j++) {
5375       struct parameterdescriptor *param=task->descriptorarray[j];
5376       struct parameterwrapper *parameter=param->queue;
5377       struct ObjectHash * set=parameter->objectset;
5378       struct ObjectIterator objit;
5379 #ifndef RAW
5380       printf("  Parameter %d\n", j);
5381 #endif
5382       ObjectHashiterator(set, &objit);
5383       while(ObjhasNext(&objit)) {
5384         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
5385         struct ___Object___ * tagptr=obj->___tags___;
5386         int nonfailed=Objdata4(&objit);
5387         int numflags=Objdata3(&objit);
5388         int flags=Objdata2(&objit);
5389         Objnext(&objit);
5390 #ifndef RAW
5391         printf("    Contains %lx\n", obj);
5392         printf("      flag=%d\n", obj->flag);
5393 #endif
5394         if (tagptr==NULL) {
5395         } else if (tagptr->type==TAGTYPE) {
5396 #ifndef RAW
5397           printf("      tag=%lx\n",tagptr);
5398 #endif
5399           ;
5400         } else {
5401           int tagindex=0;
5402           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
5403           for(; tagindex<ao->___cachedCode___; tagindex++) {
5404 #ifndef RAW
5405             printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
5406 #endif
5407           }
5408         }
5409       }
5410     }
5411   }
5412 }
5413
5414
5415 /* This function processes the task information to create queues for
5416    each parameter type. */
5417
5418 void processtasks() {
5419   int i;
5420 #ifdef RAW
5421   if(corenum > NUMCORES - 1) {
5422     return;
5423   }
5424 #endif
5425 #ifdef THREADSIMULATE
5426   int numofcore = pthread_getspecific(key);
5427   for(i=0; i<numtasks[numofcore]; i++) {
5428     struct taskdescriptor *task=taskarray[numofcore][i];
5429 #else
5430   for(i=0; i<numtasks[corenum]; i++) {
5431     struct taskdescriptor * task=taskarray[corenum][i];
5432 #endif
5433     int j;
5434
5435     /* Build objectsets */
5436     for(j=0; j<task->numParameters; j++) {
5437       struct parameterdescriptor *param=task->descriptorarray[j];
5438       struct parameterwrapper *parameter=param->queue;
5439       parameter->objectset=allocateObjectHash(10);
5440       parameter->task=task;
5441     }
5442
5443     /* Build iterators for parameters */
5444     for(j=0; j<task->numParameters; j++) {
5445       struct parameterdescriptor *param=task->descriptorarray[j];
5446       struct parameterwrapper *parameter=param->queue;
5447       builditerators(task, j, parameter);
5448     }
5449   }
5450 }
5451
5452 void toiReset(struct tagobjectiterator * it) {
5453   if (it->istag) {
5454     it->tagobjindex=0;
5455   } else if (it->numtags>0) {
5456     it->tagobjindex=0;
5457   } else {
5458     ObjectHashiterator(it->objectset, &it->it);
5459   }
5460 }
5461
5462 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
5463   if (it->istag) {
5464     /* Iterate tag */
5465     /* Get object with tags */
5466     struct ___Object___ *obj=objectarray[it->tagobjectslot];
5467     struct ___Object___ *tagptr=obj->___tags___;
5468     if (tagptr->type==TAGTYPE) {
5469       if ((it->tagobjindex==0)&& /* First object */
5470           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
5471         return 1;
5472       else
5473         return 0;
5474     } else {
5475       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
5476       int tagindex=it->tagobjindex;
5477       for(; tagindex<ao->___cachedCode___; tagindex++) {
5478         struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
5479         if (td->flag==it->tagid) {
5480           it->tagobjindex=tagindex; /* Found right type of tag */
5481           return 1;
5482         }
5483       }
5484       return 0;
5485     }
5486   } else if (it->numtags>0) {
5487     /* Use tags to locate appropriate objects */
5488     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
5489     struct ___Object___ *objptr=tag->flagptr;
5490     int i;
5491     if (objptr->type!=OBJECTARRAYTYPE) {
5492       if (it->tagobjindex>0)
5493         return 0;
5494       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
5495         return 0;
5496       for(i=1; i<it->numtags; i++) {
5497         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
5498         if (!containstag(objptr,tag2))
5499           return 0;
5500       }
5501       return 1;
5502     } else {
5503       struct ArrayObject *ao=(struct ArrayObject *) objptr;
5504       int tagindex;
5505       int i;
5506       for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
5507         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
5508         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
5509           continue;
5510         for(i=1; i<it->numtags; i++) {
5511           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
5512           if (!containstag(objptr,tag2))
5513             goto nexttag;
5514         }
5515         it->tagobjindex=tagindex;
5516         return 1;
5517 nexttag:
5518         ;
5519       }
5520       it->tagobjindex=tagindex;
5521       return 0;
5522     }
5523   } else {
5524     return ObjhasNext(&it->it);
5525   }
5526 }
5527
5528 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
5529   int j;
5530   struct ___Object___ * objptr=tag->flagptr;
5531   if (objptr->type==OBJECTARRAYTYPE) {
5532     struct ArrayObject *ao=(struct ArrayObject *)objptr;
5533     for(j=0; j<ao->___cachedCode___; j++) {
5534       if (ptr==ARRAYGET(ao, struct ___Object___*, j))
5535         return 1;
5536     }
5537     return 0;
5538   } else
5539     return objptr==ptr;
5540 }
5541
5542 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
5543   /* hasNext has all of the intelligence */
5544   if(it->istag) {
5545     /* Iterate tag */
5546     /* Get object with tags */
5547     struct ___Object___ *obj=objectarray[it->tagobjectslot];
5548     struct ___Object___ *tagptr=obj->___tags___;
5549     if (tagptr->type==TAGTYPE) {
5550       it->tagobjindex++;
5551       objectarray[it->slot]=tagptr;
5552     } else {
5553       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
5554       objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
5555     }
5556   } else if (it->numtags>0) {
5557     /* Use tags to locate appropriate objects */
5558     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
5559     struct ___Object___ *objptr=tag->flagptr;
5560     if (objptr->type!=OBJECTARRAYTYPE) {
5561       it->tagobjindex++;
5562       objectarray[it->slot]=objptr;
5563     } else {
5564       struct ArrayObject *ao=(struct ArrayObject *) objptr;
5565       objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
5566     }
5567   } else {
5568     /* Iterate object */
5569     objectarray[it->slot]=(void *)Objkey(&it->it);
5570     Objnext(&it->it);
5571   }
5572 }
5573 #endif