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