00001
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <errno.h>
00005 #include <string.h>
00006 #include <assert.h>
00007
00008 #include "converse.h"
00009 #include "traceCore.h"
00010 #include "traceCoreCommon.h"
00011
00012 #include "converseEvents.h"
00013 #include "charmEvents.h"
00014 #include "machineEvents.h"
00015
00016 CpvExtern(double, _traceCoreInitTime);
00017 CpvExtern(char*, _traceCoreRoot);
00018 CpvExtern(int, _traceCoreBufferSize);
00019 CpvExtern(TraceCore*, _traceCore);
00020
00021
00022
00023 #define TRACE_CORE_TIMER CmiWallTimer
00024 inline double TraceCoreTimer() { return TRACE_CORE_TIMER() - CpvAccess(_traceCoreInitTime); }
00025 inline double TraceCoreTimer(double t) { return t - CpvAccess(_traceCoreInitTime); }
00026
00027
00028 TraceCore::TraceCore(char** argv)
00029 {
00030 int binary = CmiGetArgFlag(argv,"+binary-trace");
00031
00032
00033 if(CpvAccess(_traceCoreOn) == 0){
00034 traceCoreOn=0;
00035 return;
00036 }
00037 traceCoreOn=1;
00038 traceLogger = new TraceLogger(CpvAccess(_traceCoreRoot), binary);
00039
00040 startPtc();
00041 REGISTER_CONVERSE
00042 REGISTER_CHARM
00043 REGISTER_MACHINE
00044
00045
00046 }
00047
00048 TraceCore::~TraceCore()
00049 {
00050 closePtc();
00051 if(traceLogger) delete traceLogger;
00052 }
00053
00054 void TraceCore::RegisterLanguage(int lID, const char* ln)
00055 {
00056
00057 if(traceCoreOn == 0){
00058 return;
00059 }
00060 traceLogger->RegisterLanguage(lID, ln);
00061
00062
00063 if(maxlID < lID){
00064 maxlID = lID;
00065 }
00066 lIDList[numLangs] = lID;
00067 lNames[numLangs] = new char[strlen(ln)+1];
00068 sprintf(lNames[numLangs],"%s",ln);
00069 numLangs++;
00070
00071 }
00072
00073 struct TraceCoreEvent *insert_TraceCoreEvent(struct TraceCoreEvent *root,int eID){
00074 struct TraceCoreEvent *p;
00075
00076 if(root == NULL){
00077 p = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
00078 p->next = NULL;
00079 p->eID = eID;
00080 return p;
00081 }
00082 p = root;
00083 while(p->next != NULL)
00084 p = p->next;
00085 p->next = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
00086 p->next->next = NULL;
00087 p->next->eID = eID;
00088
00089 return root;
00090 }
00091
00092
00093 void print_TraceCoreEvent(FILE *fpPtc,struct TraceCoreEvent *root,char *lang){
00094 struct TraceCoreEvent *p;
00095
00096 p = root;
00097 while(p!=NULL){
00098 fprintf(fpPtc,"%d %s%d ",p->eID,lang,p->eID);
00099 p = p->next;
00100
00101 }
00102 }
00103
00104
00105 void TraceCore::RegisterEvent(int lID, int eID)
00106 {
00107
00108 if(traceCoreOn == 0){
00109 return;
00110 }
00111
00112 for(int i=0;i<numLangs;i++){
00113 if(lIDList[i] == lID){
00114 if(maxeID[i] < eID){
00115 maxeID[i] = eID;
00116 }
00117 numEvents[i]++;
00118 eventLists[i] = insert_TraceCoreEvent(eventLists[i],eID);
00119 break;
00120 }
00121 }
00122 }
00123
00124 void TraceCore::startPtc(){
00125 if(traceCoreOn ==0){
00126 return;
00127 }
00128 char *str = new char[strlen(CpvAccess(_traceCoreRoot))+strlen(".ptc")+1];
00129 sprintf(str,"%s.ptc",CpvAccess(_traceCoreRoot));
00130 fpPtc = fopen(str,"w");
00131 if(fpPtc == NULL){
00132 CmiAbort("Can't generate Ptc file");
00133 }
00134 fprintf(fpPtc,"%d\n",CmiNumPes());
00135 for(int i=0;i<MAX_NUM_LANGUAGES;i++){
00136 eventLists[i] = NULL;
00137 maxeID[i] = 0;
00138 numEvents[i] = 0;
00139 }
00140 maxlID = 0;
00141 numLangs = 0;
00142 delete [] str;
00143 }
00144
00145
00146 void TraceCore::closePtc(){
00147 int i;
00148 if(traceCoreOn ==0){
00149 return;
00150 }
00151 fprintf(fpPtc,"%d %d ",maxlID,numLangs);
00152 for(i=0;i<numLangs;i++){
00153 fprintf(fpPtc,"%d %s ",lIDList[i],lNames[i]);
00154 }
00155 fprintf(fpPtc,"\n");
00156 for(i=0;i<numLangs;i++){
00157 fprintf(fpPtc,"%d %d %d ",lIDList[i],maxeID[i],numEvents[i]);
00158 print_TraceCoreEvent(fpPtc,eventLists[i],lNames[i]);
00159 fprintf(fpPtc,"\n");
00160 }
00161 fclose(fpPtc);
00162 }
00163
00164
00165
00166
00167
00168 void TraceCore::LogEvent(int lID, int eID)
00169 {
00170 if(traceCoreOn == 0){
00171 return;
00172 }
00173 LogEvent(lID, eID, 0, NULL, 0, NULL);
00174 }
00175
00176 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData)
00177 {
00178 if(traceCoreOn == 0){
00179 return;
00180 }
00181 LogEvent(lID, eID, iLen, iData, 0, NULL);
00182 }
00183
00184 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData,double t){
00185 if(traceCoreOn == 0){
00186 return;
00187 }
00188 CmiPrintf("TraceCore LogEvent called \n");
00189 #if CMK_TRACE_ENABLED
00190 int *iDataalloc;
00191 if(iLen != 0){
00192 iDataalloc = (int *)malloc(iLen*sizeof(int));
00193 for(int i=0;i<iLen;i++){
00194 iDataalloc[i] = iData[i];
00195 }
00196 }else{
00197 iDataalloc = NULL;
00198 }
00199 traceLogger->add(lID,eID,TraceCoreTimer(t),iLen,iDataalloc,0,NULL);
00200 #endif
00201 }
00202
00203
00204 void TraceCore::LogEvent(int lID, int eID, int sLen, const char* sData)
00205 {
00206 if(traceCoreOn == 0){
00207 return;
00208 }
00209 LogEvent(lID, eID, 0, NULL, sLen, sData);
00210 }
00211
00212 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData, int sLen,const char* sData)
00213 {
00214
00215 if(traceCoreOn == 0){
00216 return;
00217 }
00218
00219
00220 #if CMK_TRACE_ENABLED
00221 int *iDataalloc;
00222 char *sDataalloc;
00223 if(iLen != 0){
00224 iDataalloc = (int *)malloc(iLen*sizeof(int));
00225 for(int i=0;i<iLen;i++){
00226 iDataalloc[i] = iData[i];
00227 }
00228 }else{
00229 iDataalloc = NULL;
00230 }
00231 if(sLen != 0){
00232 sDataalloc = (char *)malloc(sLen*sizeof(char));
00233 for(int i=0;i<sLen;i++){
00234 sDataalloc[i] = sData[i];
00235 }
00236 }else{
00237 sDataalloc = NULL;
00238 }
00239
00240 traceLogger->add(lID, eID, TraceCoreTimer(), iLen, iDataalloc, sLen, sDataalloc);
00241 #endif
00242 }
00243
00244
00245 TraceEntry::TraceEntry(TraceEntry& te)
00246 {
00247 languageID = te.languageID;
00248 eventID = te.eventID;
00249 timestamp = te.timestamp;
00250 eLen = te.eLen;
00251 entity = te.entity;
00252 iLen = te.iLen;
00253 iData = te.iData;
00254 sLen = te.sLen;
00255 sData = te.sData;
00256 }
00257
00258 TraceEntry::~TraceEntry()
00259 {
00260 if(entity) free(entity);
00261 if(iData) free(iData);
00262 if(sData) free(sData);
00263 }
00264
00265 void TraceEntry::write(FILE* fp, int prevLID, int prevSeek, int nextLID, int nextSeek)
00266 {
00267
00268 if(prevLID == 0 && nextLID ==0)
00269 fprintf(fp, "%d %f %d %d ", eventID, timestamp, 0, 0);
00270 else if(prevLID == 0 && nextLID !=0)
00271 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, 0, nextLID, nextSeek);
00272 else if(prevLID != 0 && nextLID ==0)
00273 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, prevLID, prevSeek, 0);
00274 else
00275 fprintf(fp, "%d %f %d %d %d %d", eventID, timestamp, prevLID, prevSeek, nextLID, nextSeek);
00276
00277 fprintf(fp, " %d", eLen);
00278 if(eLen != 0) {
00279 for(int i=0; i<eLen; i++) fprintf(fp, " %d", entity[i]);
00280 }
00281
00282 fprintf(fp, " %d", iLen);
00283 if(iLen != 0) {
00284 for(int i=0; i<iLen; i++) fprintf(fp, " %d", iData[i]);
00285 }
00286
00287 if(sLen !=0) fprintf(fp, " %s\n", sData);
00288 else fprintf(fp, "\n");
00289
00290
00291 if(entity){
00292 free(entity);
00293 }
00294 entity = NULL;
00295 if(iData){
00296 free(iData);
00297 }
00298 iData = NULL;
00299 if(sData){
00300 free(sData);
00301 }
00302 sData=NULL;
00303 }
00304
00305
00306 TraceLogger::TraceLogger(char* program, int b):
00307 numEntries(0), numLangs(1), lastWriteFlag(false), prevLID(0), prevSeek(0)
00308 {
00309 binary = b;
00310
00311
00312
00313 poolSize = 10000;
00314 pool = new TraceEntry[poolSize+5];
00315
00316
00317 for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
00318 lName[lID]=NULL;
00319 fName[lID]=NULL;
00320 }
00321
00322 pgm = new char[strlen(program)+1];
00323 sprintf(pgm, "%s", program);
00324 numEntries = 0;
00325 isWriting = false;
00326 buffer = NULL;
00327
00328
00329
00330
00331 }
00332
00333 void TraceLogger::initlogfiles(){
00334 openLogFiles();
00335 closeLogFiles();
00336 }
00337
00338
00339 TraceLogger::~TraceLogger()
00340 {
00341 if(binary)
00342 { lastWriteFlag = true; writeBinary(); }
00343 else
00344 { lastWriteFlag = true; write(); }
00345 for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
00346 delete[] lName[lID];
00347 delete[] fName[lID];
00348 }
00349 }
00350
00351 void TraceLogger::RegisterLanguage(int lID, const char* ln)
00352 {
00353 numLangs++;
00354
00355 lName[lID] = new char[strlen(ln)+1];
00356 sprintf(lName[lID], "%s", ln);
00357
00358 char pestr[10]; sprintf(pestr, "%d", CmiMyPe());
00359 fName[lID] = new char[strlen(pgm)+1+strlen(pestr)+1+strlen(ln)+strlen(".log")+10];
00360 sprintf(fName[lID], "%s.%s.%s.log", pgm, pestr, ln);
00361
00362
00363
00364 if(CpvAccess(_traceCoreOn) == 0){
00365 CmiPrintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1_traceCoreOn = 0 in RegisterLanguage \n");
00366 return;
00367 }
00368 FILE* fp = NULL;
00369 do
00370 {
00371 fp = fopen(fName[lID], "w");
00372 } while (!fp && (errno == EINTR || errno == EMFILE));
00373 if(!fp) {
00374 CmiAbort("Cannot open Projector Trace File for writing ... \n");
00375 }
00376 if(!binary) {
00377 fprintf(fp, "PROJECTOR-RECORD: %s.%s\n", pestr, lName[lID]);
00378 }
00379
00380 fptrs[lID] = fp;
00381 }
00382
00383 void TraceLogger::verifyFptrs(){
00384
00385 for(int i=1; i<numLangs; i++){
00386 if(!fptrs[i]){
00387 CmiPrintf("Null File Pointer Found after Open\n");
00388 }
00389 }
00390 }
00391
00392 void TraceLogger::write(void)
00393 {
00394 if(CpvAccess(_traceCoreOn) == 0){
00395 return;
00396 }
00397
00398 verifyFptrs();
00399 int currLID=0, nextLID=0;
00400 int pLID=0, nLID=0;
00401 int currSeek=0, nextSeek=0;
00402 int i;
00403 for(i=0; i<numEntries-1; i++) {
00404 currLID = pool[i].languageID;
00405 FILE* fp = fptrs[currLID];
00406 if(fp == NULL)
00407 return;
00408 currSeek = ftell(fp);
00409 nextLID = pool[i+1].languageID;
00410 nextSeek = ftell(fptrs[nextLID]);
00411
00412 pLID = ((prevLID==currLID)?0:prevLID);
00413 nLID = ((nextLID==currLID)?0:nextLID);
00414 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
00415
00416 prevSeek = currSeek; prevLID = currLID;
00417 flushLogFiles();
00418 }
00419 if(lastWriteFlag) {
00420 currLID = pool[i].languageID;
00421 FILE* fp = fptrs[currLID];
00422 if(fp == NULL)
00423 return;
00424 currSeek = ftell(fp);
00425 nextLID = nextSeek = 0;
00426
00427 pLID = ((prevLID==currLID)?0:prevLID);
00428 nLID = ((nextLID==currLID)?0:nextLID);
00429 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
00430 closeLogFiles();
00431 }
00432
00433
00434 }
00435
00436
00437 void TraceLogger::writeBinary(void) {}
00438
00439 void TraceLogger::writeSts(void) {}
00440
00441 void TraceLogger::add(int lID, int eID, double timestamp, int iLen, int* iData, int sLen, char* sData)
00442 {
00443
00444 if(isWriting){
00445
00446 buffer = new TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
00447 }else{
00448 new (&pool[numEntries]) TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
00449 numEntries = numEntries+1;
00450 if(numEntries>= poolSize) {
00451 double writeTime = TraceCoreTimer();
00452 isWriting = true;
00453 if(binary) writeBinary();
00454 else write();
00455
00456
00457 new (&pool[0]) TraceEntry(pool[numEntries-1]);
00458
00459 numEntries=1;
00460 if(buffer != NULL){
00461 new (&pool[1]) TraceEntry(*buffer);
00462 numEntries=2;
00463 delete buffer;
00464 buffer = NULL;
00465 }
00466 isWriting = false;
00467
00468
00469
00470 }
00471 }
00472 }
00473
00474 void TraceLogger::openLogFiles()
00475 {
00476 CmiPrintf("[%d]Entering openLogFile \n",CmiMyPe());
00477 for(int i=1; i<numLangs; i++) {
00478
00479 FILE* fp = NULL;
00480 do
00481 {
00482
00483 fp = fopen(fName[i], "a");
00484
00485 } while (!fp && (errno == EINTR || errno == EMFILE));
00486 if(!fp) {
00487
00488 CmiAbort("Cannot open Projector Trace File for writing ... \n");
00489 }
00490 CmiPrintf("[%d]Iteration %d : fp %d \n",CmiMyPe(),i,fp);
00491 fptrs[i] = fp;
00492
00493 if(i == 1)
00494 assert(fptrs[1]);
00495 else if(i == 2)
00496 {
00497 assert(fptrs[1]);
00498 assert(fptrs[2]);
00499 }
00500 else if(i>= 3)
00501 {
00502 assert(fptrs[1]);
00503 assert(fptrs[2]);
00504 assert(fptrs[3]);
00505 }
00506 }
00507 CmiAssert(fptrs[1]);
00508 CmiAssert(fptrs[2]);
00509 CmiAssert(fptrs[3]);
00510 CmiPrintf("[%d]In Open log files ........\n",CmiMyPe());
00511 verifyFptrs();
00512 CmiPrintf("[%d].....................\n",CmiMyPe());
00513 }
00514
00515 void TraceLogger::closeLogFiles()
00516 {
00517
00518 for(int i=1; i<numLangs; i++){
00519 if(fptrs[i])
00520 fclose(fptrs[i]);
00521 fptrs[i]=NULL;
00522
00523 }
00524 }
00525
00526 void TraceLogger::flushLogFiles(){
00527 for(int i=1;i<numLangs;i++){
00528 fflush(fptrs[i]);
00529 }
00530 }
00531