-/* Message format:
- * type + Msgbody
- * type:11 -- GC start
- * 12 -- compact phase start
- * 13 -- flush phase start
- * 14 -- mark phase finish
- * 15 -- compact phase finish
- * 16 -- flush phase finish
- * 17 -- GC finish
- * 18 -- marked phase finish confirm request
- * 19 -- marked phase finish confirm response
- * 1a -- markedObj msg
- * 1b -- start moving objs msg
- * 1c -- ask for mapping info of a markedObj
- * 1d -- mapping info of a markedObj
- * 1e -- large objs info request
- * 1f -- large objs info response
- *
- * GCMsg: 11 (size is always 1 * sizeof(int))
- * 12 + size of msg + (num of objs to move + (start address + end address + dst core + start dst)+)? + (num of incoming objs + (start dst + orig core)+)? + (num of large obj lists + (start address + lenght + start dst)+)?
- * 13 (size is always 1 * sizeof(int))
- * 14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
- * 15/16 + corenum (size is always 2 * sizeof(int))
- * 17 (size is always 1 * sizeof(int))
- * 18 (size if always 1 * sizeof(int))
- * 19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
- * 1a + obj's address (size is always 2 * sizeof(int))
- * 1b + corenum ( size is always 2 * sizeof(int))
- * 1c + obj's address + corenum (size is always 3 * sizeof(int))
- * 1d + obj's address + dst address (size if always 3 * sizeof(int))
- * 1e (size is always 1 * sizeof(int))
- * 1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
- *
- * NOTE: for Tilera, all GCMsgs except the GC start msg should be processed with a different net/port with other msgs
- */
-
-
-int gc_msghandler() {
- int deny = 0;
- int i = 0;
-
-gcmsg:
- if(receiveGCMsg() == -1) {
- return -1;
- }
-
- if(gcmsgdataindex == gcmsglength) {
- // received a whole msg
- int type, data1; // will receive at least 2 words including type
- type = gcmsgdata[0];
- data1 = gcmsgdata[1];
- switch(gctype) {
- case 0x12: {
- // a compact phase start msg
- if(cinstruction == NULL) {
- cinstruction = (struct compactInstr *)RUNMALLOC(sizeof(struct compactInstr));
- } else {
- // clean up out of data info
- if(cinstruction->tomoveobjs != NULL) {
- RUNFREE(cinstruction->tomoveobjs->starts);
- RUNFREE(cinstruction->tomoveobjs->ends);
- RUNFREE(cinstruction->tomoveobjs->dststarts);
- RUNFREE(cinstruction->tomoveobjs->dsts);
- RUNFREE(cinstruction->tomoveobjs);
- cinstruction->tomoveobjs = NULL;
- }
- if(cinstruction->incomingobjs != NULL) {
- RUNFREE();
- RUNFREE(cinstruction->incomingobjs->starts);
- RUNFREE(cinstruction->incomingobjs->dsts);
- RUNFREE(cinstruction->incomingobjs);
- cinstruction->incomingobjs = NULL;
- }
- // largeobj items should have been freed when processed
- if(cinstruction->largeobjs != NULL) {
- BAMBOO_EXIT(0xb005);
- }
- }
- if(data1 > 2) {
- // have objs to move etc.
- int startindex = 2;
- // process objs to move
- int num = gcmsgdata[startindex++];
- if(num > 0) {
- cinstruction->tomoveobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
- cinstruction->tomoveobjs->length = num;
- cinstruction->tomoveobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- cinstruction->tomoveobjs->ends = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- cinstruction->tomoveobjs->dststarts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- cinstruction->tomoveobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- for(i = 0; i < num; i++) {
- cinstruction->tomoveobjs->starts[i] = gcmsgdata[startindex++];
- cinstruction->tomoveobjs->ends[i] = gcmsgdata[startindex++];
- cinstruction->tomoveobjs->dsts[i] = gcmsgdata[startindex++];
- cinstruction->tomoveobjs->dststarts[i] = gcmsgdata[startindex++];
- }
- }
- // process incoming objs
- num = gcmsgdata[startindex++];
- if(num > 0) {
- cinstruction->incomingobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
- cinstruction->incomingobjs->length = num;
- cinstruction->incomingobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- cinstruction->incomingobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
- for(i = 0; i < num; i++) {
- cinstruction->incomingobjs->starts[i] = gcmsgdata[startindex++];
- cinstruction->incomingobjs->dsts[i] = gcmsgdata[startindex++];
- }
- }
- // process large objs
- num = gcmsgdata[startindex++];
- for(i = 0; i < num; i++) {
- struct largeObjItem * loi = (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem ));
- loi->orig = gcmsgdata[startindex++];
- loi->length = gcmsgdata[startindex++];
- loi->dst = gcmsgdata[startindex++];
- loi->next = NULL;
- if(i > 0) {
- cinstruction->largeobjs->next = loi;
- }
- cinstruction->largeobjs = loi;
- }
- }
- gcphase = 1;
- break;
- }
-
- case 0x13: {
- // received a flush phase start msg
- gcphase = 2;
- break;
- }
-
- case 0x14: {
- // received a mark phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
- // return -1
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb006);
- }
- if(data1 < NUMCORES) {
- gccorestatus[data1] = 0;
- gcnumsendobjs[data1] = gcmsgdata[2];
- gcnumreceiveobjs[data1] = gcmsgdata[3];
- }
- break;
- }
-
- case 0x15: {
- // received a compact phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
- // return -1
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb006);
- }
- if(data1 < NUMCORES) {
- gccorestatus[data1] = 0;
- }
- break;
- }
-
- case 0x16: {
- // received a flush phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
- // return -1
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb006);
- }
- if(data1 < NUMCORES) {
- gccorestatus[data1] = 0;
- }
- break;
- }
-
- case 0x17: {
- // received a GC finish msg
- gcphase = 3;
- break;
- }
-
- case 0x18: {
- // received a marked phase finish confirm request msg
- if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
- // wrong core to receive such msg
- BAMBOO_EXIT(0xa013);
- } else {
- // send response msg
- if(gcisMsgSending) {
- cache_msg_5(STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
- } else {
- send_msg_5(STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
- }
- }
- break;
- }
-
- case 0x19: {
- // received a marked phase finish confirm response msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // wrong core to receive such msg
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(gcmsgdata[2]);
-#endif
- BAMBOO_EXIT(0xb014);
- } else {
- if(gcwaitconfirm) {
- gcnumconfirm--;
- }
- gccorestatus[data1] = gcmsgdata[2];
- gcnumsendobjs[data1] = gcmsgdata[3];
- gcnumreceiveobjs[data1] = gcmsgdata[4];
- }
- break;
- }
-
- case 0x1a: {
- // received a markedObj msg
- addNewItem(gctomark, data1);
- gcself_numreceiveobjs++;
- gcbusystatus = true;
- break;
- }
-
- case 0x1b: {
- // received a start moving objs msg
- addNewItem_I(gcdsts, data1);
- tomove = true;
- break;
- }
-
- case 0x1c: {
- // received a mapping info request msg
- void * dstptr = gengettable(pointertbl, data1);
- if(NULL == dstptr) {
- // no such pointer in this core, something is wrong
- BAMBOO_EXIT(0xb008);
- } else {
- // send back the mapping info
- if(gcisMsgSending) {
- cache_msg_3(gcmsgdata[2], 0x1d, data1, dstptr);
- } else {
- send_msg_3(gcmsgdata[2], 0x1d, data1, dstptr);
- }
- }
- break;
- }
-
- case 0x1d: {
- // received a mapping info response msg
- if(data1 != obj2map) {
- // obj not matched, something is wrong
- BAMBOO_EXIT(0xb009);
- } else {
- mappedobj = gcmsgdata[2];
- genputtable(pointertbl, obj2map, mappedobj);
- }
- ismapped = true;
- break;
- }
-
- case 0x1e: {
- // received a large objs info request msg
- transferMarkResults();
- break;
- }
-
- case 0x1f: {
- // received a large objs info response msg
- // TODO
- gcwaitconfirm--;
- break;
- }
-
- default:
- break;
- }
- for(gcmsgdataindex--; gcmsgdataindex > 0; --gcmsgdataindex) {
- gcmsgdata[gcmsgdataindex] = -1;
- }
- gcmsgtype = -1;
- gcmsglength = 30;
-
- if(BAMBOO_GCMSG_AVAIL() != 0) {
- goto gcmsg;
- }
-#ifdef PROFILE
- /*if(isInterrupt) {
- profileTaskEnd();
- }*/
-#endif
- return type;
- } else {
- // not a whole msg
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe88d);
-#endif
-#endif
- return -2;
- }
-}