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