+ raw_test_pass(0xffff);
+ if(msgdataindex == msglength) {
+ // received a whole msg
+ int type, data1, data2; // will receive at least 3 words including type
+ type = msgdata[0];
+ data1 = msgdata[1];
+ data2 = msgdata[2];
+ switch(type) {
+ case 0: {
+ // receive a object transfer msg
+ struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
+ int k = 0;
+ if(corenum > NUMCORES - 1) {
+ raw_test_done(0xa00a);
+ }
+ // store the object and its corresponding queue info, enqueue it later
+ transObj->objptr = (void *)data2; // data1 is now size of the msg
+ transObj->length = (msglength - 3) / 2;
+ transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
+ for(k = 0; k < transObj->length; ++k) {
+ transObj->queues[2*k] = msgdata[3+2*k];
+ raw_test_pass_reg(transObj->queues[2*k]);
+ transObj->queues[2*k+1] = msgdata[3+2*k+1];
+ raw_test_pass_reg(transObj->queues[2*k+1]);
+ }
+ //memcpy(transObj->queues, msgdata[3], sizeof(int)*(msglength - 3));
+ addNewItem_I(&objqueue, (void *)transObj);
+ ++(self_numreceiveobjs);
+ raw_test_pass(0xe881);
+ /*
+ addNewItem_I(&objqueue, (void *)data2);
+ ++(self_numreceiveobjs);
+ raw_test_pass(0xe881);*/
+ break;
+ }
+ case 1: {
+ // receive a stall msg
+ if(corenum != STARTUPCORE) {
+ // non startup core can not receive stall msg
+ // return -1
+ raw_test_done(0xa001);
+ }
+ if(data1 < NUMCORES) {
+ raw_test_pass(0xe882);
+ corestatus[data1] = 0;
+ numsendobjs[data1] = data2;
+ numreceiveobjs[data1] = msgdata[3];
+ }
+ break;
+ }
+ case 2: {
+ // receive lock request msg
+ // for 32 bit machine, the size is always 3 words
+ //int msgsize = sizeof(int) * 3;
+ int msgsize = 3;
+ // lock request msg, handle it right now
+ // check to see if there is a lock exist in locktbl for the required obj
+ int data3 = msgdata[3];
+ deny = false;
+ if(!RuntimeHashcontainskey(locktbl, data2)) {
+ // no locks for this object
+ // first time to operate on this shared object
+ // create a lock for it
+ // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
+ raw_test_pass(0xe883);
+ if(data1 == 0) {
+ RuntimeHashadd_I(locktbl, data2, 1);
+ } else {
+ RuntimeHashadd_I(locktbl, data2, -1);
+ }
+ } else {
+ int rwlock_obj = 0;
+ raw_test_pass(0xe884);
+ RuntimeHashget(locktbl, data2, &rwlock_obj);
+ raw_test_pass_reg(rwlock_obj);
+ if(0 == rwlock_obj) {
+ if(data1 == 0) {
+ rwlock_obj = 1;
+ } else {
+ rwlock_obj = -1;
+ }
+ RuntimeHashremovekey(locktbl, data2);
+ RuntimeHashadd_I(locktbl, data2, rwlock_obj);
+ } else if((rwlock_obj > 0) && (data1 == 0)) {
+ // read lock request and there are only read locks
+ rwlock_obj++;
+ RuntimeHashremovekey(locktbl, data2);
+ RuntimeHashadd_I(locktbl, data2, rwlock_obj);
+ } else {
+ deny = true;
+ }
+ raw_test_pass_reg(rwlock_obj);
+ }
+ targetcore = data3;
+ calCoords(corenum, &self_y, &self_x);
+ calCoords(targetcore, &target_y, &target_x);
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msgsize, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header to EAST to handle fab(n - 1).
+ raw_test_pass(0xbbbb);
+ raw_test_pass(0xb000 + targetcore); // targetcore
+ if(deny == true) {
+ // deny the lock request
+ gdn_send(4); // lock request
+ raw_test_pass(4);
+ } else {
+ // grount the lock request
+ gdn_send(3); // lock request
+ raw_test_pass(3);
+ }
+ gdn_send(data1); // lock type
+ raw_test_pass_reg(data1);
+ gdn_send(data2); // lock target
+ raw_test_pass_reg(data2);
+ raw_test_pass(0xffff);
+ break;
+ }
+ case 3: {
+ // receive lock grount msg
+ if(corenum > NUMCORES - 1) {
+ raw_test_done(0xa00b);
+ }
+ if(lockobj == data2) {
+ lockresult = 1;
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ } else {
+ // conflicts on lockresults
+ raw_test_done(0xa002);
+ }
+ break;
+ }
+ case 4: {
+ // receive lock grount/deny msg
+ if(corenum > NUMCORES - 1) {
+ raw_test_done(0xa00c);
+ }
+ if(lockobj == data2) {
+ lockresult = 0;
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = false;