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