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