+#ifdef RAWPROFILE
+// send profile request message to targetcore
+// format: 6
+bool transProfileRequestMsg(int targetcore) {
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ // for 32 bit machine, the size is always 4 words
+ int msgsize = 2;
+
+ 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);
+ // start sending msgs, set msg sending flag
+ isMsgSending = true;
+ gdn_send(msgHdr); // Send the message header to EAST to handle fab(n - 1).
+#ifdef RAWDEBUG
+ raw_test_pass(0xbbbb);
+ raw_test_pass(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(6);
+#ifdef RAWDEBUG
+ raw_test_pass(6);
+#endif
+ gdn_send(totalexetime);
+#ifdef RAWDEBUG
+ raw_test_pass_reg(totalexetime);
+ raw_test_pass(0xffff);
+#endif
+ // end of sending this msg, set sand msg flag false
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ targetcore = outmsgdata[outmsgindex++];
+ calCoords(targetcore, &target_y, &target_x);
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ isMsgSending = true;
+ gdn_send(msgHdr);
+#ifdef RAWDEBUG
+ raw_test_pass(0xbbbb);
+ raw_test_pass(0xb000 + targetcore); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef RAWDEBUG
+ raw_test_pass_reg(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef RAWDEBUG
+ raw_test_pass(0xffff);
+#endif
+ isMsgSending = false;
+#ifdef INTERRUPT
+ raw_user_interrupts_off();
+#endif
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+#ifdef INTERRUPT
+ raw_user_interrupts_on();
+#endif
+ }
+ return true;
+}
+
+// output the profiling data
+void outputProfileData() {
+#ifdef RAWUSEIO
+ FILE * fp;
+ char fn[50];
+ int self_y, self_x;
+ char c_y, c_x;
+ int i;
+ int totaltasktime = 0;
+ int preprocessingtime = 0;
+ int objqueuecheckingtime = 0;
+ int postprocessingtime = 0;
+ //int interruptiontime = 0;
+ int other = 0;
+ int averagetasktime = 0;
+ int tasknum = 0;
+
+ for(i = 0; i < 50; i++) {
+ fn[i] = 0;
+ }
+
+ calCoords(corenum, &self_y, &self_x);
+ c_y = (char)self_y + '0';
+ c_x = (char)self_x + '0';
+ strcat(fn, "profile_");
+ strcat(fn, &c_x);
+ strcat(fn, "_");
+ strcat(fn, &c_y);
+ strcat(fn, ".rst");
+
+ if((fp = fopen(fn, "w+")) == NULL) {
+ fprintf(stderr, "fopen error\n");
+ return;
+ }
+
+ fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
+ // output task related info
+ for(i = 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ int duration = tmpTInfo->endTime - tmpTInfo->startTime;
+ fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
+ // summarize new obj info
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ //fprintf(stderr, "new obj!\n");
+ }
+
+ // output all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ fprintf(fp, ", %s, %d", objtype, num);
+ }
+ }
+ fprintf(fp, "\n");
+ if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
+ preprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
+ postprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
+ objqueuecheckingtime += duration;
+ } else {
+ totaltasktime += duration;
+ averagetasktime += duration;
+ tasknum++;
+ }
+ }
+
+ if(taskInfoOverflow) {
+ fprintf(stderr, "Caution: task info overflow!\n");
+ }
+
+ other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
+ averagetasktime /= tasknum;
+
+ fprintf(fp, "\nTotal time: %d\n", totalexetime);
+ fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
+ fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
+ fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
+ fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
+ fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
+
+ fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
+
+ fclose(fp);
+#else
+ int i = 0;
+ int j = 0;
+
+ raw_test_pass(0xdddd);
+ // output task related info
+ for(i= 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ char* tmpName = tmpTInfo->taskName;
+ int nameLen = strlen(tmpName);
+ raw_test_pass(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ raw_test_pass_reg(tmpName[j]);
+ }
+ raw_test_pass(0xdddb);
+ raw_test_pass_reg(tmpTInfo->startTime);
+ raw_test_pass_reg(tmpTInfo->endTime);
+ raw_test_pass_reg(tmpTInfo->exitIndex);
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ }
+
+ // ouput all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ int nameLen = strlen(objtype);
+ raw_test_pass(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ raw_test_pass_reg(objtype[j]);
+ }
+ raw_test_pass(0xdddb);
+ raw_test_pass_reg(num);
+ }
+ }
+ raw_test_pass(0xdddc);
+ }
+
+ if(taskInfoOverflow) {
+ raw_test_pass(0xefee);
+ }
+
+ // output interrupt related info
+ /*for(i = 0; i < interruptInfoIndex; i++) {
+ InterruptInfo* tmpIInfo = interruptInfoArray[i];
+ raw_test_pass(0xddde);
+ raw_test_pass_reg(tmpIInfo->startTime);
+ raw_test_pass_reg(tmpIInfo->endTime);
+ raw_test_pass(0xdddf);
+ }
+
+ if(interruptInfoOverflow) {
+ raw_test_pass(0xefef);
+ }*/
+
+ raw_test_pass(0xeeee);
+#endif
+}
+
+inline void setTaskExitIndex(int index) {
+ taskInfoArray[taskInfoIndex]->exitIndex = index;
+}
+
+inline void addNewObjInfo(void * nobj) {
+ if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
+ taskInfoArray[taskInfoIndex]->newObjs = createQueue();
+ }
+ addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
+}
+#endif
+