00001
00052 #include <stdio.h>
00053 #include <stdlib.h>
00054 #include <string.h>
00055 #include <errno.h>
00056 #ifndef _WIN32
00057 #include <sys/time.h>
00058 #include <sys/resource.h>
00059 #endif
00060
00061 #include "converse.h"
00062 #include "conv-trace.h"
00063 #include "sockRoutines.h"
00064 #include "queueing.h"
00065 #include "conv-ccs.h"
00066 #include "ccs-server.h"
00067 #include "memory-isomalloc.h"
00068 #if CMK_PROJECTOR
00069 #include "converseEvents.h"
00070 #include "traceCoreCommon.h"
00071 #include "machineEvents.h"
00072 #endif
00073
00074 extern const char * const CmiCommitID;
00075
00076 #if CMK_OUT_OF_CORE
00077 #include "conv-ooc.h"
00078 #endif
00079
00080 #if CONVERSE_POOL
00081 #include "cmipool.h"
00082 #endif
00083
00084 #if CMK_CONDS_USE_SPECIAL_CODE
00085 CmiSwitchToPEFnPtr CmiSwitchToPE;
00086 #endif
00087
00088 CpvExtern(int, _traceCoreOn);
00089 extern void CcdModuleInit(char **);
00090 extern void CmiMemoryInit(char **);
00091 extern void CldModuleInit(char **);
00092
00093 #if CMK_WHEN_PROCESSOR_IDLE_USLEEP
00094 #include <sys/types.h>
00095 #include <sys/time.h>
00096 #endif
00097
00098 #if CMK_TIMER_USE_TIMES
00099 #include <sys/times.h>
00100 #include <limits.h>
00101 #include <unistd.h>
00102 #endif
00103
00104 #if CMK_TIMER_USE_GETRUSAGE
00105 #include <sys/time.h>
00106 #include <sys/resource.h>
00107 #endif
00108
00109 #if CMK_TIMER_USE_RDTSC
00110 #include <string.h>
00111 #include <unistd.h>
00112 #include <time.h>
00113 #include <stdio.h>
00114 #include <sys/time.h>
00115 #include <sys/resource.h>
00116 #endif
00117
00118 #ifdef CMK_TIMER_USE_WIN32API
00119 #include <stdlib.h>
00120 #include <time.h>
00121 #include <sys/types.h>
00122 #include <sys/timeb.h>
00123 #endif
00124
00125 #ifdef CMK_HAS_ASCTIME
00126 #include <time.h>
00127 #endif
00128
00129 #ifdef CMK_CUDA
00130 #include "cuda-hybrid-api.h"
00131 #endif
00132
00133 #include "quiescence.h"
00134
00135 CpvDeclare(int,_curRestartPhase);
00136 static int CsdLocalMax = CSD_LOCAL_MAX_DEFAULT;
00137
00138 int CharmLibInterOperate = 0;
00139 CpvDeclare(int,charmLibExitFlag);
00140
00141 CpvStaticDeclare(int, CmiMainHandlerIDP);
00142
00143 #if CMK_MEM_CHECKPOINT
00144 void (*notify_crash_fn)(int) = NULL;
00145 #endif
00146
00147 CpvDeclare(char *, _validProcessors);
00148
00149
00150
00151
00152
00153
00154
00155 #ifdef MEMMONITOR
00156 typedef unsigned long mmulong;
00157 CpvDeclare(mmulong,MemoryUsage);
00158 CpvDeclare(mmulong,HiWaterMark);
00159 CpvDeclare(mmulong,ReportedHiWaterMark);
00160 CpvDeclare(int,AllocCount);
00161 CpvDeclare(int,BlocksAllocated);
00162 #endif
00163
00164 #define MAX_HANDLERS 512
00165
00166 #if ! CMK_CMIPRINTF_IS_A_BUILTIN
00167 CpvDeclare(int,expIOFlushFlag);
00168 #if CMI_IO_BUFFER_EXPLICIT
00169
00170 #define DEFAULT_IO_BUFFER_SIZE 250000
00171 CpvDeclare(char*,explicitIOBuffer);
00172 CpvDeclare(int,expIOBufferSize);
00173 #endif
00174 #endif
00175
00176 #if CMK_NODE_QUEUE_AVAILABLE
00177 void *CmiGetNonLocalNodeQ();
00178 #endif
00179
00180 CpvDeclare(void*, CsdSchedQueue);
00181
00182 #if CMK_OUT_OF_CORE
00183
00184 CpvDeclare(void*, CsdPrefetchQueue);
00185 pthread_mutex_t prefetchLock;
00186 #endif
00187
00188 #if CMK_NODE_QUEUE_AVAILABLE
00189 CsvDeclare(void*, CsdNodeQueue);
00190 CsvDeclare(CmiNodeLock, CsdNodeQueueLock);
00191 #endif
00192 CpvDeclare(int, CsdStopFlag);
00193 CpvDeclare(int, CsdLocalCounter);
00194
00195 CpvDeclare(int, _urgentSend);
00196
00197 CmiNodeLock _smp_mutex;
00198
00199 #if CONVERSE_VERSION_VMI
00200 void *CMI_VMI_CmiAlloc (int size);
00201 void CMI_VMI_CmiFree (void *ptr);
00202 #endif
00203
00204 #if CONVERSE_VERSION_ELAN
00205 void* elan_CmiAlloc(int size);
00206 #endif
00207
00208 #if CMK_USE_IBVERBS | CMK_USE_IBUD
00209 void *infi_CmiAlloc(int size);
00210 void infi_CmiFree(void *ptr);
00211 void infi_freeMultipleSend(void *ptr);
00212 void infi_unregAndFreeMeta(void *ch);
00213 #endif
00214
00215
00216 #if CMK_GRID_QUEUE_AVAILABLE
00217 CpvDeclare(void *, CkGridObject);
00218 CpvDeclare(void *, CsdGridQueue);
00219 #endif
00220
00221 #if CMK_CRAYXE
00222 void* LrtsAlloc(int, int);
00223 void LrtsFree(void*);
00224 #endif
00225
00226 CpvStaticDeclare(int, cmiMyPeIdle);
00227 int CmiIsMyNodeIdle();
00228
00229
00230
00231
00232
00233
00234
00235 static int usageChecked=0;
00236 static int printUsage=0;
00237 static const char *CLAformatString="%20s %10s %s\n";
00238
00243 typedef struct {
00244 const char *arg;
00245 const char *param;
00246 const char *desc;
00247 } CLA;
00248 static int CLAlistLen=0;
00249 static int CLAlistMax=0;
00250 static CLA *CLAlist=NULL;
00251
00253 static void CmiAddCLA(const char *arg,const char *param,const char *desc) {
00254 int i;
00255 if (CmiMyPe()!=0) return;
00256 if (desc==NULL) return;
00257 if (usageChecked) {
00258 if (printUsage)
00259 CmiPrintf(CLAformatString,arg,param,desc);
00260 }
00261 else {
00262
00263
00264 i=CLAlistLen++;
00265 if (CLAlistLen>CLAlistMax) {
00266 CLAlistMax=16+2*CLAlistLen;
00267 CLAlist=realloc(CLAlist,sizeof(CLA)*CLAlistMax);\
00268 }
00269 CLAlist[i].arg=arg;
00270 CLAlist[i].param=param;
00271 CLAlist[i].desc=desc;
00272 }
00273 }
00274
00276 static void CmiPrintCLAs(void) {
00277 int i;
00278 if (CmiMyPe()!=0) return;
00279 CmiPrintf("Converse Machine Command-line Parameters:\n ");
00280 CmiPrintf(CLAformatString,"Option:","Parameter:","Description:");
00281 for (i=0;i<CLAlistLen;i++) {
00282 CLA *c=&CLAlist[i];
00283 CmiPrintf(CLAformatString,c->arg,c->param,c->desc);
00284 }
00285 }
00286
00292 void CmiArgInit(char **argv) {
00293 int i;
00294 for (i=0;argv[i]!=NULL;i++)
00295 {
00296 if (0==strcmp(argv[i],"-?") ||
00297 0==strcmp(argv[i],"-h") ||
00298 0==strcmp(argv[i],"--help"))
00299 {
00300 printUsage=1;
00301
00302
00303 CmiPrintCLAs();
00304 }
00305 }
00306 if (CmiMyPe()==0) {
00307 CLAlistLen=CLAlistMax=0;
00308 free(CLAlist); CLAlist=NULL;
00309 }
00310 usageChecked=1;
00311 }
00312
00314 int CmiArgGivingUsage(void) {
00315 return (CmiMyPe()==0) && printUsage;
00316 }
00317
00319 void CmiArgGroup(const char *parentName,const char *groupName) {
00320 if (CmiArgGivingUsage()) {
00321 if (groupName==NULL) groupName=parentName;
00322 CmiPrintf("\n%s Command-line Parameters:\n",groupName);
00323 }
00324 }
00325
00327 int CmiGetArgc(char **argv)
00328 {
00329 int i=0,argc=0;
00330 if (argv)
00331 while (argv[i++]!=NULL)
00332 argc++;
00333 return argc;
00334 }
00335
00337 char **CmiCopyArgs(char **argv)
00338 {
00339 int argc=CmiGetArgc(argv);
00340 char **ret=(char **)malloc(sizeof(char *)*(argc+1));
00341 int i;
00342 for (i=0;i<=argc;i++)
00343 ret[i]=argv[i];
00344 return ret;
00345 }
00346
00352 void CmiDeleteArgs(char **argv,int k)
00353 {
00354 int i=0;
00355 while ((argv[i]=argv[i+k])!=NULL)
00356 i++;
00357 }
00358
00366 int CmiGetArgStringDesc(char **argv,const char *arg,char **optDest,const char *desc)
00367 {
00368 int i;
00369 CmiAddCLA(arg,"string",desc);
00370 for (i=0;argv[i]!=NULL;i++)
00371 if (0==strcmp(argv[i],arg))
00372 {
00373 if (argv[i+1]==NULL) CmiAbort("Argument not complete!");
00374 *optDest=argv[i+1];
00375 CmiDeleteArgs(&argv[i],2);
00376 return 1;
00377 }
00378 return 0;
00379 }
00380 int CmiGetArgString(char **argv,const char *arg,char **optDest) {
00381 return CmiGetArgStringDesc(argv,arg,optDest,"");
00382 }
00383
00387 int CmiGetArgDoubleDesc(char **argv,const char *arg,double *optDest,const char *desc) {
00388 char *number=NULL;
00389 CmiAddCLA(arg,"number",desc);
00390 if (!CmiGetArgStringDesc(argv,arg,&number,NULL)) return 0;
00391 if (1!=sscanf(number,"%lg",optDest)) return 0;
00392 return 1;
00393 }
00394 int CmiGetArgDouble(char **argv,const char *arg,double *optDest) {
00395 return CmiGetArgDoubleDesc(argv,arg,optDest,"");
00396 }
00397
00405 int CmiGetArgIntDesc(char **argv,const char *arg,int *optDest,const char *desc)
00406 {
00407 int i;
00408 int argLen=strlen(arg);
00409 CmiAddCLA(arg,"integer",desc);
00410 for (i=0;argv[i]!=NULL;i++)
00411 if (0==strncmp(argv[i],arg,argLen))
00412 {
00413 const char *opt=NULL;
00414 int nDel=0;
00415 switch(argv[i][argLen]) {
00416 case 0:
00417 opt=argv[i+1]; nDel=2; break;
00418 case '=':
00419 opt=&argv[i][argLen+1]; nDel=1; break;
00420 case '-':case '+':
00421 case '0':case '1':case '2':case '3':case '4':
00422 case '5':case '6':case '7':case '8':case '9':
00423
00424 opt=&argv[i][argLen]; nDel=1; break;
00425 default:
00426 continue;
00427 }
00428 if (opt==NULL) continue;
00429 if (sscanf(opt,"%i",optDest)<1) {
00430
00431 fprintf(stderr,"Cannot parse %s option '%s' "
00432 "as an integer.\n",arg,opt);
00433 CmiAbort("Bad command-line argument\n");
00434 }
00435 CmiDeleteArgs(&argv[i],nDel);
00436 return 1;
00437 }
00438 return 0;
00439 }
00440 int CmiGetArgInt(char **argv,const char *arg,int *optDest) {
00441 return CmiGetArgIntDesc(argv,arg,optDest,"");
00442 }
00443
00444 int CmiGetArgLongDesc(char **argv,const char *arg,CmiInt8 *optDest,const char *desc)
00445 {
00446 int i;
00447 int argLen=strlen(arg);
00448 CmiAddCLA(arg,"integer",desc);
00449 for (i=0;argv[i]!=NULL;i++)
00450 if (0==strncmp(argv[i],arg,argLen))
00451 {
00452 const char *opt=NULL;
00453 int nDel=0;
00454 switch(argv[i][argLen]) {
00455 case 0:
00456 opt=argv[i+1]; nDel=2; break;
00457 case '=':
00458 opt=&argv[i][argLen+1]; nDel=1; break;
00459 case '-':case '+':
00460 case '0':case '1':case '2':case '3':case '4':
00461 case '5':case '6':case '7':case '8':case '9':
00462
00463 opt=&argv[i][argLen]; nDel=1; break;
00464 default:
00465 continue;
00466 }
00467 if (opt==NULL) continue;
00468 if (sscanf(opt,"%ld",optDest)<1) {
00469
00470 fprintf(stderr,"Cannot parse %s option '%s' "
00471 "as a long integer.\n",arg,opt);
00472 CmiAbort("Bad command-line argument\n");
00473 }
00474 CmiDeleteArgs(&argv[i],nDel);
00475 return 1;
00476 }
00477 return 0;
00478 }
00479 int CmiGetArgLong(char **argv,const char *arg,CmiInt8 *optDest) {
00480 return CmiGetArgLongDesc(argv,arg,optDest,"");
00481 }
00482
00488 int CmiGetArgFlagDesc(char **argv,const char *arg,const char *desc)
00489 {
00490 int i;
00491 CmiAddCLA(arg,"",desc);
00492 for (i=0;argv[i]!=NULL;i++)
00493 if (0==strcmp(argv[i],arg))
00494 {
00495 CmiDeleteArgs(&argv[i],1);
00496 return 1;
00497 }
00498 return 0;
00499 }
00500 int CmiGetArgFlag(char **argv,const char *arg) {
00501 return CmiGetArgFlagDesc(argv,arg,"");
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 #include "cmibacktrace.c"
00511
00512
00513
00514
00515
00516
00517 static char *_implTrimParenthesis(char *str, int trimname) {
00518 char *lParen=str, *ret=NULL, *rParen=NULL;
00519 while (*lParen!='(') {
00520 if (*lParen==0) return str;
00521 lParen++;
00522 }
00523
00524 ret=lParen+1;
00525 rParen=ret;
00526 while (*rParen!=')') {
00527 if (*rParen==0) return ret;
00528 rParen++;
00529 }
00530
00531 *rParen=trimname?0:' ';
00532 return ret;
00533 }
00534
00535
00536
00537
00538
00539
00540 static const char* _implGetBacktraceSys(const char *name) {
00541 if (0==strncmp(name,"_call",5))
00542 {
00543 if (0==strncmp(name,"_call_",6)) return "Call Entry Method";
00544 if (0==strncmp(name,"_callthr_",9)) return "Call Threaded Entry Method";
00545 }
00546 if (0==strncmp(name,"CthResume",9)) return "Resumed thread";
00547 if (0==strncmp(name,"qt_args",7)) return "Converse thread";
00548
00549 return 0;
00550 }
00551
00553 void CmiBacktracePrint(void **retPtrs,int nLevels) {
00554 if (nLevels>0) {
00555 int i;
00556 char **names=CmiBacktraceLookup(retPtrs,nLevels);
00557 if (names==NULL) return;
00558 CmiPrintf("[%d] Stack Traceback:\n", CmiMyPe());
00559 for (i=0;i<nLevels;i++) {
00560 if (names[i] == NULL) continue;
00561 {
00562 const char *trimmed=_implTrimParenthesis(names[i], 0);
00563 const char *print=trimmed;
00564 const char *sys=_implGetBacktraceSys(print);
00565 if (sys) {
00566 CmiPrintf(" [%d] Charm++ Runtime: %s (%s)\n",i,sys,print);
00567 break;
00568 } else {
00569 CmiPrintf(" [%d:%d] %s\n",CmiMyPe(),i,print);
00570 }
00571 }
00572 }
00573 free(names);
00574 }
00575 }
00576
00577
00578
00579
00580 void CmiPrintStackTrace(int nSkip) {
00581 #if CMK_USE_BACKTRACE
00582 int nLevels=max_stack;
00583 void *stackPtrs[max_stack];
00584 CmiBacktraceRecord(stackPtrs,1+nSkip,&nLevels);
00585 CmiBacktracePrint(stackPtrs,nLevels);
00586 #endif
00587 }
00588
00589 int CmiIsFortranLibraryCall() {
00590 #if CMK_USE_BACKTRACE
00591 int ret = 0;
00592 int nLevels=9;
00593 void *stackPtrs[18];
00594 CmiBacktraceRecord(stackPtrs,1,&nLevels);
00595 if (nLevels>0) {
00596 int i;
00597 char **names=CmiBacktraceLookup(stackPtrs,nLevels);
00598 if (names==NULL) return 0;
00599 for (i=0;i<nLevels;i++) {
00600 if (names[i] == NULL) continue;
00601 const char *trimmed=_implTrimParenthesis(names[i], 1);
00602 if (strncmp(trimmed, "for__", 5) == 0
00603 || strncmp(trimmed, "_xlf", 4) == 0
00604 || strncmp(trimmed, "_xlfBeginIO", 11) == 0
00605 || strncmp(trimmed, "_gfortran_", 10) == 0
00606 )
00607 {
00608 ret = 1; break; }
00609 }
00610 free(names);
00611 }
00612 return ret;
00613 #else
00614 return 0;
00615 #endif
00616 }
00617
00618
00619
00620
00621
00622
00623
00624 CpvDeclare(int, CstatsMaxChareQueueLength);
00625 CpvDeclare(int, CstatsMaxForChareQueueLength);
00626 CpvDeclare(int, CstatsMaxFixedChareQueueLength);
00627 CpvStaticDeclare(int, CstatPrintQueueStatsFlag);
00628 CpvStaticDeclare(int, CstatPrintMemStatsFlag);
00629
00630 void CstatsInit(argv)
00631 char **argv;
00632 {
00633
00634 #ifdef MEMMONITOR
00635 CpvInitialize(mmulong,MemoryUsage);
00636 CpvAccess(MemoryUsage) = 0;
00637 CpvInitialize(mmulong,HiWaterMark);
00638 CpvAccess(HiWaterMark) = 0;
00639 CpvInitialize(mmulong,ReportedHiWaterMark);
00640 CpvAccess(ReportedHiWaterMark) = 0;
00641 CpvInitialize(int,AllocCount);
00642 CpvAccess(AllocCount) = 0;
00643 CpvInitialize(int,BlocksAllocated);
00644 CpvAccess(BlocksAllocated) = 0;
00645 #endif
00646
00647 CpvInitialize(int, CstatsMaxChareQueueLength);
00648 CpvInitialize(int, CstatsMaxForChareQueueLength);
00649 CpvInitialize(int, CstatsMaxFixedChareQueueLength);
00650 CpvInitialize(int, CstatPrintQueueStatsFlag);
00651 CpvInitialize(int, CstatPrintMemStatsFlag);
00652
00653 CpvAccess(CstatsMaxChareQueueLength) = 0;
00654 CpvAccess(CstatsMaxForChareQueueLength) = 0;
00655 CpvAccess(CstatsMaxFixedChareQueueLength) = 0;
00656 CpvAccess(CstatPrintQueueStatsFlag) = 0;
00657 CpvAccess(CstatPrintMemStatsFlag) = 0;
00658
00659 #if 0
00660 if (CmiGetArgFlagDesc(argv,"+mems", "Print memory statistics at shutdown"))
00661 CpvAccess(CstatPrintMemStatsFlag)=1;
00662 if (CmiGetArgFlagDesc(argv,"+qs", "Print queue statistics at shutdown"))
00663 CpvAccess(CstatPrintQueueStatsFlag)=1;
00664 #endif
00665 }
00666
00667 int CstatMemory(i)
00668 int i;
00669 {
00670 return 0;
00671 }
00672
00673 int CstatPrintQueueStats()
00674 {
00675 return CpvAccess(CstatPrintQueueStatsFlag);
00676 }
00677
00678 int CstatPrintMemStats()
00679 {
00680 return CpvAccess(CstatPrintMemStatsFlag);
00681 }
00682
00683
00684
00685
00686
00687
00688
00689 CpvDeclare(CmiHandlerInfo*, CmiHandlerTable);
00690 CpvStaticDeclare(int , CmiHandlerCount);
00691 CpvStaticDeclare(int , CmiHandlerLocal);
00692 CpvStaticDeclare(int , CmiHandlerGlobal);
00693 CpvDeclare(int, CmiHandlerMax);
00694
00695 static void CmiExtendHandlerTable(int atLeastLen) {
00696 int max = CpvAccess(CmiHandlerMax);
00697 int newmax = (atLeastLen+(atLeastLen>>2)+32);
00698 int bytes = max*sizeof(CmiHandlerInfo);
00699 int newbytes = newmax*sizeof(CmiHandlerInfo);
00700 CmiHandlerInfo *nu = (CmiHandlerInfo*)malloc(newbytes);
00701 CmiHandlerInfo *tab = CpvAccess(CmiHandlerTable);
00702 _MEMCHECK(nu);
00703 memcpy(nu, tab, bytes);
00704 memset(((char *)nu)+bytes, 0, (newbytes-bytes));
00705 free(tab); tab=nu;
00706 CpvAccess(CmiHandlerTable) = tab;
00707 CpvAccess(CmiHandlerMax) = newmax;
00708 }
00709
00710 void CmiNumberHandler(int n, CmiHandler h)
00711 {
00712 CmiHandlerInfo *tab;
00713 if (n >= CpvAccess(CmiHandlerMax)) CmiExtendHandlerTable(n);
00714 tab = CpvAccess(CmiHandlerTable);
00715 tab[n].hdlr = (CmiHandlerEx)h;
00716 tab[n].userPtr = 0;
00717 }
00718 void CmiNumberHandlerEx(int n, CmiHandlerEx h,void *userPtr) {
00719 CmiHandlerInfo *tab;
00720 if (n >= CpvAccess(CmiHandlerMax)) CmiExtendHandlerTable(n);
00721 tab = CpvAccess(CmiHandlerTable);
00722 tab[n].hdlr = h;
00723 tab[n].userPtr=userPtr;
00724 }
00725
00726 #if CMI_LOCAL_GLOBAL_AVAILABLE
00727 # define DIST_BETWEEN_HANDLERS 3
00728 #else
00729 # define DIST_BETWEEN_HANDLERS 1
00730 #endif
00731
00732 int CmiRegisterHandler(CmiHandler h)
00733 {
00734 int Count = CpvAccess(CmiHandlerCount);
00735 CmiNumberHandler(Count, h);
00736 CpvAccess(CmiHandlerCount) = Count+DIST_BETWEEN_HANDLERS;
00737 return Count;
00738 }
00739 int CmiRegisterHandlerEx(CmiHandlerEx h,void *userPtr)
00740 {
00741 int Count = CpvAccess(CmiHandlerCount);
00742 CmiNumberHandlerEx(Count, h, userPtr);
00743 CpvAccess(CmiHandlerCount) = Count+DIST_BETWEEN_HANDLERS;
00744 return Count;
00745 }
00746
00747 #if CMI_LOCAL_GLOBAL_AVAILABLE
00748 int CmiRegisterHandlerLocal(h)
00749 CmiHandler h;
00750 {
00751 int Local = CpvAccess(CmiHandlerLocal);
00752 CmiNumberHandler(Local, h);
00753 CpvAccess(CmiHandlerLocal) = Local+3;
00754 return Local;
00755 }
00756
00757 int CmiRegisterHandlerGlobal(h)
00758 CmiHandler h;
00759 {
00760 int Global = CpvAccess(CmiHandlerGlobal);
00761 if (CmiMyPe()!=0)
00762 CmiError("CmiRegisterHandlerGlobal must only be called on PE 0.\n");
00763 CmiNumberHandler(Global, h);
00764 CpvAccess(CmiHandlerGlobal) = Global+3;
00765 return Global;
00766 }
00767 #endif
00768
00769 static void _cmiZeroHandler(void *msg) {
00770 CmiAbort("Converse zero handler executed-- was a message corrupted?\n");
00771 }
00772
00773 static void CmiHandlerInit()
00774 {
00775 CpvInitialize(CmiHandlerInfo *, CmiHandlerTable);
00776 CpvInitialize(int , CmiHandlerCount);
00777 CpvInitialize(int , CmiHandlerLocal);
00778 CpvInitialize(int , CmiHandlerGlobal);
00779 CpvInitialize(int , CmiHandlerMax);
00780 CpvAccess(CmiHandlerCount) = 0;
00781 CpvAccess(CmiHandlerLocal) = 1;
00782 CpvAccess(CmiHandlerGlobal) = 2;
00783 CpvAccess(CmiHandlerMax) = 0;
00784 CpvAccess(CmiHandlerTable) = NULL;
00785 CmiRegisterHandler((CmiHandler)_cmiZeroHandler);
00786 }
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 #if CMK_HAS_ASCTIME
00799
00800 char *CmiPrintDate()
00801 {
00802 struct tm *local;
00803 time_t t;
00804
00805 t = time(NULL);
00806 local = localtime(&t);
00807 return asctime(local);
00808 }
00809
00810 #else
00811
00812 char *CmiPrintDate()
00813 {
00814 return "N/A";
00815 }
00816
00817 #endif
00818
00819 static int _absoluteTime = 0;
00820
00821 #if CMK_TIMER_USE_TIMES
00822
00823 CpvStaticDeclare(double, clocktick);
00824 CpvStaticDeclare(int,inittime_wallclock);
00825 CpvStaticDeclare(int,inittime_virtual);
00826
00827 int CmiTimerIsSynchronized()
00828 {
00829 return 0;
00830 }
00831
00832 int CmiTimerAbsolute()
00833 {
00834 return 0;
00835 }
00836
00837 double CmiStartTimer()
00838 {
00839 return 0.0;
00840 }
00841
00842 double CmiInitTime()
00843 {
00844 return CpvAccess(inittime_wallclock);
00845 }
00846
00847 void CmiTimerInit(char **argv)
00848 {
00849 struct tms temp;
00850 CpvInitialize(double, clocktick);
00851 CpvInitialize(int, inittime_wallclock);
00852 CpvInitialize(int, inittime_virtual);
00853 CpvAccess(inittime_wallclock) = times(&temp);
00854 CpvAccess(inittime_virtual) = temp.tms_utime + temp.tms_stime;
00855 CpvAccess(clocktick) = 1.0 / (sysconf(_SC_CLK_TCK));
00856 }
00857
00858 double CmiWallTimer()
00859 {
00860 struct tms temp;
00861 double currenttime;
00862 int now;
00863
00864 now = times(&temp);
00865 currenttime = (now - CpvAccess(inittime_wallclock)) * CpvAccess(clocktick);
00866 return (currenttime);
00867 }
00868
00869 double CmiCpuTimer()
00870 {
00871 struct tms temp;
00872 double currenttime;
00873 int now;
00874
00875 times(&temp);
00876 now = temp.tms_stime + temp.tms_utime;
00877 currenttime = (now - CpvAccess(inittime_virtual)) * CpvAccess(clocktick);
00878 return (currenttime);
00879 }
00880
00881 double CmiTimer()
00882 {
00883 return CmiCpuTimer();
00884 }
00885
00886 #endif
00887
00888 #if CMK_TIMER_USE_GETRUSAGE
00889
00890 #if CMK_SMP
00891 # if CMK_HAS_RUSAGE_THREAD
00892 #define RUSAGE_WHO 1
00893 #else
00894 #undef RUSAGE_WHO
00895 #endif
00896 #else
00897 #define RUSAGE_WHO 0
00898 #endif
00899
00900 static double inittime_wallclock;
00901 CpvStaticDeclare(double, inittime_virtual);
00902
00903 int CmiTimerIsSynchronized()
00904 {
00905 return 0;
00906 }
00907
00908 int CmiTimerAbsolute()
00909 {
00910 return _absoluteTime;
00911 }
00912
00913 double CmiStartTimer()
00914 {
00915 return 0.0;
00916 }
00917
00918 double CmiInitTime()
00919 {
00920 return inittime_wallclock;
00921 }
00922
00923 void CmiTimerInit(char **argv)
00924 {
00925 struct timeval tv;
00926 struct rusage ru;
00927 CpvInitialize(double, inittime_virtual);
00928
00929 _absoluteTime = CmiGetArgFlagDesc(argv,"+useAbsoluteTime", "Use system's absolute time as wallclock time.");
00930
00931 #if !CMK_MEM_CHECKPOINT && !_FAULT_MLOG_ && !_FAULT_CAUSAL_
00932
00933 CmiBarrier();
00934 CmiBarrier();
00935 CmiBarrier();
00936 #endif
00937
00938 gettimeofday(&tv,0);
00939 inittime_wallclock = (tv.tv_sec * 1.0) + (tv.tv_usec*0.000001);
00940 #ifndef RUSAGE_WHO
00941 CpvAccess(inittime_virtual) = inittime_wallclock;
00942 #else
00943 getrusage(RUSAGE_WHO, &ru);
00944 CpvAccess(inittime_virtual) =
00945 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
00946 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
00947 #endif
00948
00949 #if ! CMK_MEM_CHECKPOINT && !_FAULT_MLOG_ && !_FAULT_CAUSAL_
00950 CmiBarrier();
00951
00952 #endif
00953 }
00954
00955 double CmiCpuTimer()
00956 {
00957 #ifndef RUSAGE_WHO
00958 return CmiWallTimer();
00959 #else
00960 struct rusage ru;
00961 double currenttime;
00962
00963 getrusage(RUSAGE_WHO, &ru);
00964 currenttime =
00965 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
00966 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
00967
00968 return currenttime - CpvAccess(inittime_virtual);
00969 #endif
00970 }
00971
00972 static double lastT = -1.0;
00973
00974 double CmiWallTimer()
00975 {
00976 struct timeval tv;
00977 double currenttime;
00978
00979 gettimeofday(&tv,0);
00980 currenttime = (tv.tv_sec * 1.0) + (tv.tv_usec * 0.000001);
00981 #if CMK_ERROR_CHECKING
00982 if (lastT > 0.0 && currenttime < lastT) {
00983 currenttime = lastT;
00984 }
00985 lastT = currenttime;
00986 #endif
00987 return _absoluteTime?currenttime:currenttime - inittime_wallclock;
00988 }
00989
00990 double CmiTimer()
00991 {
00992 return CmiCpuTimer();
00993 }
00994
00995 #endif
00996
00997 #if CMK_TIMER_USE_RDTSC
00998
00999 static double readMHz(void)
01000 {
01001 double x;
01002 char str[1000];
01003 char buf[100];
01004 FILE *fp;
01005 CmiLock(_smp_mutex);
01006 fp = fopen("/proc/cpuinfo", "r");
01007 if (fp != NULL)
01008 while(fgets(str, 1000, fp)!=0) {
01009 if(sscanf(str, "cpu MHz%[^:]",buf)==1)
01010 {
01011 char *s = strchr(str, ':'); s=s+1;
01012 sscanf(s, "%lf", &x);
01013 fclose(fp);
01014 CmiUnlock(_smp_mutex);
01015 return x;
01016 }
01017 }
01018 CmiUnlock(_smp_mutex);
01019 CmiAbort("Cannot read CPU MHz from /proc/cpuinfo file.");
01020 return 0.0;
01021 }
01022
01023 double _cpu_speed_factor;
01024 CpvStaticDeclare(double, inittime_virtual);
01025 CpvStaticDeclare(double, inittime_walltime);
01026
01027 double CmiStartTimer(void)
01028 {
01029 return CpvAccess(inittime_walltime);
01030 }
01031
01032 double CmiInitTime()
01033 {
01034 return CpvAccess(inittime_walltime);
01035 }
01036
01037 void CmiTimerInit(char **argv)
01038 {
01039 struct rusage ru;
01040
01041 CmiBarrier();
01042 CmiBarrier();
01043
01044 _cpu_speed_factor = 1.0/(readMHz()*1.0e6);
01045 rdtsc(); rdtsc(); rdtsc(); rdtsc(); rdtsc();
01046 CpvInitialize(double, inittime_walltime);
01047 CpvAccess(inittime_walltime) = CmiWallTimer();
01048 CpvInitialize(double, inittime_virtual);
01049 getrusage(0, &ru);
01050 CpvAccess(inittime_virtual) =
01051 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
01052 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
01053
01054 CmiBarrierZero();
01055 }
01056
01057 double CmiCpuTimer()
01058 {
01059 struct rusage ru;
01060 double currenttime;
01061
01062 getrusage(0, &ru);
01063 currenttime =
01064 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
01065 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
01066 return currenttime - CpvAccess(inittime_virtual);
01067 }
01068
01069 #endif
01070
01071 #if CMK_BLUEGENEL || CMK_BLUEGENEP
01072 #include "dcopy.h"
01073 #endif
01074
01075 #if CMK_TIMER_USE_BLUEGENEL
01076
01077 #include "rts.h"
01078
01079 #if 0
01080 #define SPRN_TBRL 0x10C
01081 #define SPRN_TBRU 0x10D
01082 #define SPRN_PIR 0x11E
01083
01084 static inline unsigned long long BGLTimebase(void)
01085 {
01086 unsigned volatile u1, u2, lo;
01087 union
01088 {
01089 struct { unsigned hi, lo; } w;
01090 unsigned long long d;
01091 } result;
01092
01093 do {
01094 asm volatile ("mfspr %0,%1" : "=r" (u1) : "i" (SPRN_TBRU));
01095 asm volatile ("mfspr %0,%1" : "=r" (lo) : "i" (SPRN_TBRL));
01096 asm volatile ("mfspr %0,%1" : "=r" (u2) : "i" (SPRN_TBRU));
01097 } while (u1!=u2);
01098
01099 result.w.lo = lo;
01100 result.w.hi = u2;
01101 return result.d;
01102 }
01103 #endif
01104
01105 static unsigned long long inittime_wallclock = 0;
01106 CpvStaticDeclare(double, clocktick);
01107
01108 int CmiTimerIsSynchronized()
01109 {
01110 return 0;
01111 }
01112
01113 int CmiTimerAbsolute()
01114 {
01115 return 1;
01116 }
01117
01118 double CmiStartTimer()
01119 {
01120 return 0.0;
01121 }
01122
01123 double CmiInitTime()
01124 {
01125 return inittime_wallclock;
01126 }
01127
01128 void CmiTimerInit(char **argv)
01129 {
01130 BGLPersonality dst;
01131 CpvInitialize(double, clocktick);
01132 int size = sizeof(BGLPersonality);
01133 rts_get_personality(&dst, size);
01134 CpvAccess(clocktick) = 1.0 / dst.clockHz;
01135
01136
01137 CmiBarrier();
01138 CmiBarrier();
01139 CmiBarrier();
01140
01141
01142 inittime_wallclock = 0.0;
01143 }
01144
01145 double CmiWallTimer()
01146 {
01147 unsigned long long currenttime;
01148 currenttime = rts_get_timebase();
01149 return CpvAccess(clocktick)*(currenttime-inittime_wallclock);
01150 }
01151
01152 double CmiCpuTimer()
01153 {
01154 return CmiWallTimer();
01155 }
01156
01157 double CmiTimer()
01158 {
01159 return CmiWallTimer();
01160 }
01161
01162 #endif
01163
01164 #if CMK_TIMER_USE_BLUEGENEP
01165
01166 int CmiTimerAbsolute()
01167 {
01168 return 0;
01169 }
01170
01171 double CmiStartTimer()
01172 {
01173 return 0.0;
01174 }
01175
01176 double CmiInitTime()
01177 {
01178 return 0.0;
01179 }
01180
01181 void CmiTimerInit(char **argv) {}
01182
01183 #include "dcmf.h"
01184
01185 double CmiWallTimer () {
01186 return DCMF_Timer();
01187 }
01188
01189 double CmiCpuTimer()
01190 {
01191 return CmiWallTimer();
01192 }
01193
01194 double CmiTimer()
01195 {
01196 return CmiWallTimer();
01197 }
01198 #endif
01199
01200
01201 #if CMK_TIMER_USE_BLUEGENEQ
01202
01203 CpvStaticDeclare(unsigned long, inittime);
01204 CpvStaticDeclare(double, clocktick);
01205
01206 int CmiTimerIsSynchronized()
01207 {
01208 return 1;
01209 }
01210
01211 int CmiTimerAbsolute()
01212 {
01213 return 0;
01214 }
01215
01216 #include "hwi/include/bqc/A2_inlines.h"
01217 #include "spi/include/kernel/process.h"
01218
01219 double CmiStartTimer()
01220 {
01221 return 0.0;
01222 }
01223
01224 double CmiInitTime()
01225 {
01226 return CpvAccess(inittime);
01227 }
01228
01229 void CmiTimerInit(char **argv)
01230 {
01231 CpvInitialize(double, clocktick);
01232 CpvInitialize(unsigned long, inittime);
01233
01234 Personality_t pers;
01235 Kernel_GetPersonality(&pers, sizeof(pers));
01236 uint32_t clockMhz = pers.Kernel_Config.FreqMHz;
01237 CpvAccess(clocktick) = 1.0 / (clockMhz * 1e6);
01238
01239 fprintf(stderr, "Blue Gene/Q running at clock speed of %d Mhz\n", clockMhz);
01240
01241
01242 CmiBarrier();
01243 CmiBarrier();
01244 CmiBarrier();
01245
01246 CpvAccess(inittime) = GetTimeBase ();
01247 }
01248
01249 double CmiWallTimer()
01250 {
01251 unsigned long long currenttime;
01252 currenttime = GetTimeBase();
01253 return CpvAccess(clocktick)*(currenttime-CpvAccess(inittime));
01254 }
01255
01256 double CmiCpuTimer()
01257 {
01258 return CmiWallTimer();
01259 }
01260
01261 double CmiTimer()
01262 {
01263 return CmiWallTimer();
01264 }
01265
01266 #endif
01267
01268
01269 #if CMK_TIMER_USE_WIN32API
01270
01271 CpvStaticDeclare(double, inittime_wallclock);
01272 CpvStaticDeclare(double, inittime_virtual);
01273
01274 double CmiStartTimer()
01275 {
01276 return 0.0;
01277 }
01278
01279 int CmiTimerAbsolute()
01280 {
01281 return 0;
01282 }
01283
01284 double CmiInitTime()
01285 {
01286 return CpvAccess(inittime_wallclock);
01287 }
01288
01289 void CmiTimerInit(char **argv)
01290 {
01291 #ifdef __CYGWIN__
01292 struct timeb tv;
01293 #else
01294 struct _timeb tv;
01295 #endif
01296 clock_t ru;
01297
01298 CpvInitialize(double, inittime_wallclock);
01299 CpvInitialize(double, inittime_virtual);
01300 _ftime(&tv);
01301 CpvAccess(inittime_wallclock) = tv.time*1.0 + tv.millitm*0.001;
01302 ru = clock();
01303 CpvAccess(inittime_virtual) = ((double) ru)/CLOCKS_PER_SEC;
01304 }
01305
01306 double CmiCpuTimer()
01307 {
01308 clock_t ru;
01309 double currenttime;
01310
01311 ru = clock();
01312 currenttime = (double) ru/CLOCKS_PER_SEC;
01313
01314 return currenttime - CpvAccess(inittime_virtual);
01315 }
01316
01317 double CmiWallTimer()
01318 {
01319 #ifdef __CYGWIN__
01320 struct timeb tv;
01321 #else
01322 struct _timeb tv;
01323 #endif
01324 double currenttime;
01325
01326 _ftime(&tv);
01327 currenttime = tv.time*1.0 + tv.millitm*0.001;
01328
01329 return currenttime - CpvAccess(inittime_wallclock);
01330 }
01331
01332
01333 double CmiTimer()
01334 {
01335 return CmiCpuTimer();
01336 }
01337
01338 #endif
01339
01340 #if CMK_TIMER_USE_RTC
01341
01342 #if __crayx1
01343
01344 #include <intrinsics.h>
01345 #endif
01346
01347 static double clocktick;
01348 CpvStaticDeclare(long long, inittime_wallclock);
01349
01350 double CmiStartTimer()
01351 {
01352 return 0.0;
01353 }
01354
01355 double CmiInitTime()
01356 {
01357 return CpvAccess(inittime_wallclock);
01358 }
01359
01360 void CmiTimerInit(char **argv)
01361 {
01362 CpvInitialize(long long, inittime_wallclock);
01363 CpvAccess(inittime_wallclock) = _rtc();
01364 clocktick = 1.0 / (double)(sysconf(_SC_SV2_USER_TIME_RATE));
01365 }
01366
01367 int CmiTimerAbsolute()
01368 {
01369 return 0;
01370 }
01371
01372 double CmiWallTimer()
01373 {
01374 long long now;
01375
01376 now = _rtc();
01377 return (clocktick * (now - CpvAccess(inittime_wallclock)));
01378 }
01379
01380 double CmiCpuTimer()
01381 {
01382 return CmiWallTimer();
01383 }
01384
01385 double CmiTimer()
01386 {
01387 return CmiCpuTimer();
01388 }
01389
01390 #endif
01391
01392 #if CMK_TIMER_USE_AIX_READ_TIME
01393
01394 #include <sys/time.h>
01395
01396 static timebasestruct_t inittime_wallclock;
01397 static double clocktick;
01398 CpvStaticDeclare(double, inittime_virtual);
01399
01400 double CmiStartTimer()
01401 {
01402 return 0.0;
01403 }
01404
01405 double CmiInitTime()
01406 {
01407 return inittime_wallclock;
01408 }
01409
01410 void CmiTimerInit(char **argv)
01411 {
01412 struct rusage ru;
01413
01414 if (CmiMyRank() == 0) {
01415 read_wall_time(&inittime_wallclock, TIMEBASE_SZ);
01416 time_base_to_time(&inittime_wallclock, TIMEBASE_SZ);
01417 }
01418
01419 CpvInitialize(double, inittime_virtual);
01420 getrusage(0, &ru);
01421 CpvAccess(inittime_virtual) =
01422 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
01423 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
01424 }
01425
01426 int CmiTimerAbsolute()
01427 {
01428 return 0;
01429 }
01430
01431 double CmiWallTimer()
01432 {
01433 int secs, n_secs;
01434 double curt;
01435 timebasestruct_t now;
01436 read_wall_time(&now, TIMEBASE_SZ);
01437 time_base_to_time(&now, TIMEBASE_SZ);
01438
01439 secs = now.tb_high - inittime_wallclock.tb_high;
01440 n_secs = now.tb_low - inittime_wallclock.tb_low;
01441 if (n_secs < 0) {
01442 secs--;
01443 n_secs += 1000000000;
01444 }
01445 curt = secs*1.0 + n_secs*1e-9;
01446 return curt;
01447 }
01448
01449 double CmiCpuTimer()
01450 {
01451 struct rusage ru;
01452 double currenttime;
01453
01454 getrusage(0, &ru);
01455 currenttime =
01456 (ru.ru_utime.tv_sec * 1.0)+(ru.ru_utime.tv_usec * 0.000001) +
01457 (ru.ru_stime.tv_sec * 1.0)+(ru.ru_stime.tv_usec * 0.000001);
01458 return currenttime - CpvAccess(inittime_virtual);
01459 }
01460
01461 double CmiTimer()
01462 {
01463 return CmiWallTimer();
01464 }
01465
01466 #endif
01467
01468 #ifndef CMK_USE_SPECIAL_MESSAGE_QUEUE_CHECK
01469
01471 int CmiLongSendQueue(int forNode,int longerThanBytes) {
01472 return 0;
01473 }
01474 #endif
01475
01476 #if CMK_SIGNAL_USE_SIGACTION
01477 #include <signal.h>
01478 void CmiSignal(int sig1, int sig2, int sig3, void (*handler)())
01479 {
01480 struct sigaction in, out ;
01481 in.sa_handler = handler;
01482 sigemptyset(&in.sa_mask);
01483 if (sig1) sigaddset(&in.sa_mask, sig1);
01484 if (sig2) sigaddset(&in.sa_mask, sig2);
01485 if (sig3) sigaddset(&in.sa_mask, sig3);
01486 in.sa_flags = 0;
01487 if (sig1) if (sigaction(sig1, &in, &out)<0) exit(1);
01488 if (sig2) if (sigaction(sig2, &in, &out)<0) exit(1);
01489 if (sig3) if (sigaction(sig3, &in, &out)<0) exit(1);
01490 }
01491 #endif
01492
01493 #if CMK_SIGNAL_USE_SIGACTION_WITH_RESTART
01494 #include <signal.h>
01495 void CmiSignal(sig1, sig2, sig3, handler)
01496 int sig1, sig2, sig3;
01497 void (*handler)();
01498 {
01499 struct sigaction in, out ;
01500 in.sa_handler = handler;
01501 sigemptyset(&in.sa_mask);
01502 if (sig1) sigaddset(&in.sa_mask, sig1);
01503 if (sig2) sigaddset(&in.sa_mask, sig2);
01504 if (sig3) sigaddset(&in.sa_mask, sig3);
01505 in.sa_flags = SA_RESTART;
01506 if (sig1) if (sigaction(sig1, &in, &out)<0) exit(1);
01507 if (sig2) if (sigaction(sig2, &in, &out)<0) exit(1);
01508 if (sig3) if (sigaction(sig3, &in, &out)<0) exit(1);
01509 }
01510 #endif
01511
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 void CsdBeginIdle(void)
01557 {
01558 CcdCallBacks();
01559 #if CMK_TRACE_ENABLED && CMK_PROJECTOR
01560 _LOG_E_PROC_IDLE();
01561 #endif
01562
01563 CpvAccess(cmiMyPeIdle) = 1;
01564
01565 CcdRaiseCondition(CcdPROCESSOR_BEGIN_IDLE) ;
01566 }
01567
01568 void CsdStillIdle(void)
01569 {
01570 CcdRaiseCondition(CcdPROCESSOR_STILL_IDLE);
01571 }
01572
01573 void CsdEndIdle(void)
01574 {
01575 #if CMK_TRACE_ENABLED && CMK_PROJECTOR
01576 _LOG_E_PROC_BUSY();
01577 #endif
01578
01579 CpvAccess(cmiMyPeIdle) = 0;
01580
01581 CcdRaiseCondition(CcdPROCESSOR_BEGIN_BUSY) ;
01582 }
01583
01584 extern int _exitHandlerIdx;
01585
01587 void CmiHandleMessage(void *msg)
01588 {
01589
01590
01591
01592 CmiHandlerInfo *h;
01593 #if CMK_TRACE_ENABLED && CMK_PROJECTOR
01594 CmiUInt2 handler=CmiGetHandler(msg);
01595 _LOG_E_HANDLER_BEGIN(handler);
01596
01597 #endif
01598
01599
01600
01601
01602
01603
01604
01605
01606 MESSAGE_PHASE_CHECK(msg)
01607
01608 h=&CmiGetHandlerInfo(msg);
01609 (h->hdlr)(msg,h->userPtr);
01610 #if CMK_TRACE_ENABLED
01611
01612
01613 #endif
01614 }
01615
01616 #if CMK_CMIDELIVERS_USE_COMMON_CODE
01617
01618 void CmiDeliversInit()
01619 {
01620 }
01621
01622 int CmiDeliverMsgs(int maxmsgs)
01623 {
01624 return CsdScheduler(maxmsgs);
01625 }
01626
01627 #if CMK_OBJECT_QUEUE_AVAILABLE
01628 CpvDeclare(void *, CsdObjQueue);
01629 #endif
01630
01631 void CsdSchedulerState_new(CsdSchedulerState_t *s)
01632 {
01633 #if CMK_OBJECT_QUEUE_AVAILABLE
01634 s->objQ=CpvAccess(CsdObjQueue);
01635 #endif
01636 s->localQ=CpvAccess(CmiLocalQueue);
01637 s->schedQ=CpvAccess(CsdSchedQueue);
01638 s->localCounter=&(CpvAccess(CsdLocalCounter));
01639 #if CMK_NODE_QUEUE_AVAILABLE
01640 s->nodeQ=CsvAccess(CsdNodeQueue);
01641 s->nodeLock=CsvAccess(CsdNodeQueueLock);
01642 #endif
01643 #if CMK_GRID_QUEUE_AVAILABLE
01644 s->gridQ=CpvAccess(CsdGridQueue);
01645 #endif
01646 }
01647
01648
01699 void *CsdNextMessage(CsdSchedulerState_t *s) {
01700 void *msg;
01701 if((*(s->localCounter))-- >0)
01702 {
01703
01704 msg=CdsFifo_Dequeue(s->localQ);
01705 if (msg!=NULL)
01706 {
01707 CpvAccess(cQdState)->mProcessed++;
01708 return msg;
01709 }
01710 CqsDequeue(s->schedQ,(void **)&msg);
01711 if (msg!=NULL) return msg;
01712 }
01713
01714 *(s->localCounter)=CsdLocalMax;
01715 if ( NULL!=(msg=CmiGetNonLocal()) ||
01716 NULL!=(msg=CdsFifo_Dequeue(s->localQ)) ) {
01717 CpvAccess(cQdState)->mProcessed++;
01718 return msg;
01719 }
01720 #if CMK_GRID_QUEUE_AVAILABLE
01721
01722 CqsDequeue (s->gridQ, (void **) &msg);
01723 if (msg != NULL) {
01724 return (msg);
01725 }
01726 #endif
01727 #if CMK_NODE_QUEUE_AVAILABLE
01728
01729 if (NULL!=(msg=CmiGetNonLocalNodeQ())) return msg;
01730 if (!CqsEmpty(s->nodeQ)
01731 && !CqsPrioGT(CqsGetPriority(s->nodeQ),
01732 CqsGetPriority(s->schedQ))) {
01733 CmiLock(s->nodeLock);
01734 CqsDequeue(s->nodeQ,(void **)&msg);
01735 CmiUnlock(s->nodeLock);
01736 if (msg!=NULL) return msg;
01737 }
01738 #endif
01739 #if CMK_OBJECT_QUEUE_AVAILABLE
01740
01741 if (NULL!=(msg=CdsFifo_Dequeue(s->objQ))) {
01742 return msg;
01743 }
01744 #endif
01745 if(!CsdLocalMax) {
01746 CqsDequeue(s->schedQ,(void **)&msg);
01747 if (msg!=NULL) return msg;
01748 }
01749 return NULL;
01750 }
01751
01752
01753 void *CsdNextLocalNodeMessage(CsdSchedulerState_t *s) {
01754 void *msg;
01755 #if CMK_NODE_QUEUE_AVAILABLE
01756
01757
01758 if (!CqsEmpty(s->nodeQ))
01759 {
01760 CmiLock(s->nodeLock);
01761 CqsDequeue(s->nodeQ,(void **)&msg);
01762 CmiUnlock(s->nodeLock);
01763 if (msg!=NULL) return msg;
01764 }
01765 #endif
01766 return NULL;
01767
01768 }
01769
01770 int CsdScheduler(int maxmsgs)
01771 {
01772 if (maxmsgs<0) CsdScheduleForever();
01773 else if (maxmsgs==0)
01774 CsdSchedulePoll();
01775 else
01776 return CsdScheduleCount(maxmsgs);
01777 return 0;
01778 }
01779
01780
01781 #define SCHEDULE_TOP \
01782 void *msg;\
01783 int *CsdStopFlag_ptr = &CpvAccess(CsdStopFlag); \
01784 int cycle = CpvAccess(CsdStopFlag); \
01785 CsdSchedulerState_t state;\
01786 CsdSchedulerState_new(&state);
01787
01788
01789 #define SCHEDULE_MESSAGE \
01790 CmiHandleMessage(msg);\
01791 if (*CsdStopFlag_ptr != cycle) break;
01792
01793
01794 #define SCHEDULE_IDLE \
01795 if (!isIdle) {isIdle=1;CsdBeginIdle();}\
01796 else CsdStillIdle();\
01797 if (*CsdStopFlag_ptr != cycle) {\
01798 CsdEndIdle();\
01799 break;\
01800 }
01801
01802
01803
01804
01805 extern void CkClearAllArrayElements();
01806
01807
01808 extern void machine_OffloadAPIProgress();
01809
01811 void CsdScheduleForever(void)
01812 {
01813 #if CMK_CELL
01814 #define CMK_CELL_PROGRESS_FREQ 96
01815 int progressCount = CMK_CELL_PROGRESS_FREQ;
01816 #endif
01817
01818 #ifdef CMK_CUDA
01819 #define CMK_CUDA_PROGRESS_FREQ 50
01820 int cudaProgressCount = CMK_CUDA_PROGRESS_FREQ;
01821 #endif
01822
01823 int isIdle=0;
01824 SCHEDULE_TOP
01825 while (1) {
01826
01827 if(CharmLibInterOperate) {
01828 if(CpvAccess(charmLibExitFlag)) {
01829 CpvAccess(charmLibExitFlag) = 0;
01830 break;
01831 }
01832 }
01833 msg = CsdNextMessage(&state);
01834 if (msg!=NULL) {
01835 if (isIdle) {isIdle=0;CsdEndIdle();}
01836 SCHEDULE_MESSAGE
01837
01838 #if CMK_CELL
01839 if (progressCount <= 0) {
01840
01841 machine_OffloadAPIProgress();
01842 progressCount = CMK_CELL_PROGRESS_FREQ;
01843 }
01844 progressCount--;
01845 #endif
01846
01847 #ifdef CMK_CUDA
01848 if (cudaProgressCount == 0) {
01849 gpuProgressFn();
01850 cudaProgressCount = CMK_CUDA_PROGRESS_FREQ;
01851 }
01852 cudaProgressCount--;
01853 #endif
01854
01855 } else {
01856 SCHEDULE_IDLE
01857
01858 #if CMK_CELL
01859
01860 machine_OffloadAPIProgress();
01861 progressCount = CMK_CELL_PROGRESS_FREQ;
01862 #endif
01863
01864 #ifdef CMK_CUDA
01865 gpuProgressFn();
01866 cudaProgressCount = CMK_CUDA_PROGRESS_FREQ;
01867 #endif
01868
01869 }
01870 CsdPeriodic();
01871 }
01872 }
01873 int CsdScheduleCount(int maxmsgs)
01874 {
01875 int isIdle=0;
01876 SCHEDULE_TOP
01877 while (1) {
01878 msg = CsdNextMessage(&state);
01879 if (msg!=NULL) {
01880 if (isIdle) {isIdle=0;CsdEndIdle();}
01881 maxmsgs--;
01882 SCHEDULE_MESSAGE
01883 if (maxmsgs==0) break;
01884 } else {
01885 SCHEDULE_IDLE
01886 }
01887 CsdPeriodic();
01888 }
01889 return maxmsgs;
01890 }
01891
01892 void CsdSchedulePoll(void)
01893 {
01894 SCHEDULE_TOP
01895 while (1)
01896 {
01897 CsdPeriodic();
01898
01899 if (NULL!=(msg = CsdNextMessage(&state)))
01900 {
01901 SCHEDULE_MESSAGE
01902 }
01903 else break;
01904 }
01905 }
01906
01907 void CsdScheduleNodePoll(void)
01908 {
01909 SCHEDULE_TOP
01910 while (1)
01911 {
01912
01913
01914 if (NULL!=(msg = CsdNextLocalNodeMessage(&state)))
01915 {
01916 SCHEDULE_MESSAGE
01917 }
01918 else break;
01919 }
01920 }
01921
01922 void CmiDeliverSpecificMsg(handler)
01923 int handler;
01924 {
01925 int *msg; int side;
01926 void *localqueue = CpvAccess(CmiLocalQueue);
01927
01928 side = 0;
01929 while (1) {
01930 CsdPeriodic();
01931 side ^= 1;
01932 if (side) msg = CmiGetNonLocal();
01933 else msg = CdsFifo_Dequeue(localqueue);
01934 if (msg) {
01935 if (CmiGetHandler(msg)==handler) {
01936 CpvAccess(cQdState)->mProcessed++;
01937 CmiHandleMessage(msg);
01938 return;
01939 } else {
01940 CdsFifo_Enqueue(localqueue, msg);
01941 }
01942 }
01943 }
01944 }
01945
01946 #endif
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971 CpvStaticDeclare(CthThread, CthMainThread);
01972 CpvStaticDeclare(CthThread, CthSchedulingThread);
01973 CpvStaticDeclare(CthThread, CthSleepingStandins);
01974 CpvDeclare(int , CthResumeNormalThreadIdx);
01975 CpvStaticDeclare(int , CthResumeSchedulingThreadIdx);
01976
01977
01978 void CthStandinCode()
01979 {
01980 while (1) CsdScheduler(0);
01981 }
01982
01983
01984 static CthThread CthSuspendNormalThread()
01985 {
01986 return CpvAccess(CthSchedulingThread);
01987 }
01988
01989 void CthEnqueueSchedulingThread(CthThreadToken *token, int, int, unsigned int*);
01990 CthThread CthSuspendSchedulingThread();
01991
01992 CthThread CthSuspendSchedulingThread()
01993 {
01994 CthThread succ = CpvAccess(CthSleepingStandins);
01995
01996 if (succ) {
01997 CpvAccess(CthSleepingStandins) = CthGetNext(succ);
01998 } else {
01999 succ = CthCreate(CthStandinCode, 0, 256000);
02000 CthSetStrategy(succ,
02001 CthEnqueueSchedulingThread,
02002 CthSuspendSchedulingThread);
02003 }
02004
02005 CpvAccess(CthSchedulingThread) = succ;
02006 return succ;
02007 }
02008
02009
02010 void CthResumeNormalThread(CthThreadToken* token)
02011 {
02012 CthThread t = token->thread;
02013
02014
02015
02016
02017
02018 if(t == NULL){
02019 free(token);
02020 return;
02021 }
02022 #if CMK_TRACE_ENABLED
02023 #if ! CMK_TRACE_IN_CHARM
02024 if(CpvAccess(traceOn))
02025 CthTraceResume(t);
02026
02027
02028 #endif
02029 #endif
02030
02031
02032
02033
02034
02035
02036 CthResume(t);
02037 }
02038
02039 void CthResumeSchedulingThread(CthThreadToken *token)
02040 {
02041 CthThread t = token->thread;
02042 CthThread me = CthSelf();
02043 if (me == CpvAccess(CthMainThread)) {
02044 CthEnqueueSchedulingThread(CthGetToken(me),CQS_QUEUEING_FIFO, 0, 0);
02045 } else {
02046 CthSetNext(me, CpvAccess(CthSleepingStandins));
02047 CpvAccess(CthSleepingStandins) = me;
02048 }
02049 CpvAccess(CthSchedulingThread) = t;
02050 #if CMK_TRACE_ENABLED
02051 #if ! CMK_TRACE_IN_CHARM
02052 if(CpvAccess(traceOn))
02053 CthTraceResume(t);
02054
02055
02056 #endif
02057 #endif
02058 CthResume(t);
02059 }
02060
02061 void CthEnqueueNormalThread(CthThreadToken* token, int s,
02062 int pb,unsigned int *prio)
02063 {
02064 CmiSetHandler(token, CpvAccess(CthResumeNormalThreadIdx));
02065 CsdEnqueueGeneral(token, s, pb, prio);
02066 }
02067
02068 void CthEnqueueSchedulingThread(CthThreadToken* token, int s,
02069 int pb,unsigned int *prio)
02070 {
02071 CmiSetHandler(token, CpvAccess(CthResumeSchedulingThreadIdx));
02072 CsdEnqueueGeneral(token, s, pb, prio);
02073 }
02074
02075 void CthSetStrategyDefault(CthThread t)
02076 {
02077 CthSetStrategy(t,
02078 CthEnqueueNormalThread,
02079 CthSuspendNormalThread);
02080 }
02081
02082 void CthSchedInit()
02083 {
02084 CpvInitialize(CthThread, CthMainThread);
02085 CpvInitialize(CthThread, CthSchedulingThread);
02086 CpvInitialize(CthThread, CthSleepingStandins);
02087 CpvInitialize(int , CthResumeNormalThreadIdx);
02088 CpvInitialize(int , CthResumeSchedulingThreadIdx);
02089
02090 CpvAccess(CthMainThread) = CthSelf();
02091 CpvAccess(CthSchedulingThread) = CthSelf();
02092 CpvAccess(CthSleepingStandins) = 0;
02093 CpvAccess(CthResumeNormalThreadIdx) =
02094 CmiRegisterHandler((CmiHandler)CthResumeNormalThread);
02095 CpvAccess(CthResumeSchedulingThreadIdx) =
02096 CmiRegisterHandler((CmiHandler)CthResumeSchedulingThread);
02097 CthSetStrategy(CthSelf(),
02098 CthEnqueueSchedulingThread,
02099 CthSuspendSchedulingThread);
02100 }
02101
02102 void CsdInit(argv)
02103 char **argv;
02104 {
02105 CpvInitialize(void *, CsdSchedQueue);
02106 CpvInitialize(int, CsdStopFlag);
02107 CpvInitialize(int, CsdLocalCounter);
02108 if(!CmiGetArgIntDesc(argv,"+csdLocalMax",&CsdLocalMax,"Set the max number of local messages to process before forcing a check for remote messages."))
02109 {
02110 CsdLocalMax= CSD_LOCAL_MAX_DEFAULT;
02111 }
02112 CpvAccess(CsdLocalCounter) = CsdLocalMax;
02113 CpvAccess(CsdSchedQueue) = (void *)CqsCreate();
02114
02115 #if CMK_OBJECT_QUEUE_AVAILABLE
02116 CpvInitialize(void *,CsdObjQueue);
02117 CpvAccess(CsdObjQueue) = CdsFifo_Create();
02118 #endif
02119
02120 #if CMK_NODE_QUEUE_AVAILABLE
02121 CsvInitialize(CmiLock, CsdNodeQueueLock);
02122 CsvInitialize(void *, CsdNodeQueue);
02123 if (CmiMyRank() ==0) {
02124 CsvAccess(CsdNodeQueueLock) = CmiCreateLock();
02125 CsvAccess(CsdNodeQueue) = (void *)CqsCreate();
02126 }
02127 CmiNodeAllBarrier();
02128 #endif
02129
02130 #if CMK_GRID_QUEUE_AVAILABLE
02131 CsvInitialize(void *, CsdGridQueue);
02132 CpvAccess(CsdGridQueue) = (void *)CqsCreate();
02133 #endif
02134
02135 CpvAccess(CsdStopFlag) = 0;
02136 }
02137
02138
02139
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158 #if CMK_VECTOR_SEND_USES_COMMON_CODE
02159
02160 void CmiSyncVectorSend(int destPE, int n, int *sizes, char **msgs) {
02161 int total;
02162 char *mesg;
02163 #if CMK_USE_IBVERBS
02164 VECTOR_COMPACT(total, mesg, n, sizes, msgs,sizeof(infiCmiChunkHeader));
02165 #else
02166 VECTOR_COMPACT(total, mesg, n, sizes, msgs,sizeof(CmiChunkHeader));
02167 #endif
02168 CmiSyncSendAndFree(destPE, total, mesg);
02169 }
02170
02171 CmiCommHandle CmiASyncVectorSend(int destPE, int n, int *sizes, char **msgs) {
02172 CmiSyncVectorSend(destPE, n, sizes, msgs);
02173 return NULL;
02174 }
02175
02176 void CmiSyncVectorSendAndFree(int destPE, int n, int *sizes, char **msgs) {
02177 int i;
02178 CmiSyncVectorSend(destPE, n, sizes, msgs);
02179 for(i=0;i<n;i++) CmiFree(msgs[i]);
02180 CmiFree(sizes);
02181 CmiFree(msgs);
02182 }
02183
02184 #endif
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228 CpvStaticDeclare(int, CmiReductionMessageHandler);
02229 CpvStaticDeclare(int, CmiReductionDynamicRequestHandler);
02230
02231 CpvStaticDeclare(CmiReduction**, _reduce_info);
02232 CpvStaticDeclare(int, _reduce_info_size);
02233 CpvStaticDeclare(CmiUInt2, _reduce_seqID_global);
02234 CpvStaticDeclare(CmiUInt2, _reduce_seqID_request);
02235 CpvStaticDeclare(CmiUInt2, _reduce_seqID_dynamic);
02236
02237 enum {
02238 CmiReductionID_globalOffset = 0,
02239 CmiReductionID_requestOffset = 1,
02240 CmiReductionID_dynamicOffset = 2,
02241 CmiReductionID_multiplier = 3
02242 };
02243
02244 CmiReduction* CmiGetReductionCreate(int id, short int numChildren) {
02245 int index = id & ~((~0)<<CpvAccess(_reduce_info_size));
02246 CmiReduction *red = CpvAccess(_reduce_info)[index];
02247 if (red != NULL && red->seqID != id) {
02248
02249 CmiAbort("Too many simultaneous reductions");
02250 }
02251 if (red == NULL || red->numChildren < numChildren) {
02252 CmiReduction *newred;
02253 if (red != NULL) CmiPrintf("[%d] Reduction structure reallocated\n",CmiMyPe());
02254 CmiAssert(red == NULL || red->localContributed == 0);
02255 if (numChildren == 0) numChildren = 4;
02256 newred = (CmiReduction*)malloc(sizeof(CmiReduction)+numChildren*sizeof(void*));
02257 newred->numRemoteReceived = 0;
02258 newred->localContributed = 0;
02259 newred->seqID = id;
02260 if (red != NULL) {
02261 memcpy(newred, red, sizeof(CmiReduction)+red->numChildren*sizeof(void*));
02262 free(red);
02263 }
02264 red = newred;
02265 red->numChildren = numChildren;
02266 red->remoteData = (char**)(red+1);
02267 CpvAccess(_reduce_info)[index] = red;
02268 }
02269 return red;
02270 }
02271
02272 CmiReduction* CmiGetReduction(int id) {
02273 return CmiGetReductionCreate(id, 0);
02274 }
02275
02276 void CmiClearReduction(int id) {
02277 int index = id & ~((~0)<<CpvAccess(_reduce_info_size));
02278 free(CpvAccess(_reduce_info)[index]);
02279 CpvAccess(_reduce_info)[index] = NULL;
02280 }
02281
02282 CmiReduction* CmiGetNextReduction(short int numChildren) {
02283 int id = CpvAccess(_reduce_seqID_global);
02284 CpvAccess(_reduce_seqID_global) += CmiReductionID_multiplier;
02285 if (id > 0xFFF0) CpvAccess(_reduce_seqID_global) = CmiReductionID_globalOffset;
02286 return CmiGetReductionCreate(id, numChildren);
02287 }
02288
02289 CmiReductionID CmiGetGlobalReduction() {
02290 return CpvAccess(_reduce_seqID_request)+=CmiReductionID_multiplier;
02291 }
02292
02293 CmiReductionID CmiGetDynamicReduction() {
02294 if (CmiMyPe() != 0) CmiAbort("Cannot call CmiGetDynamicReduction on processors other than zero!\n");
02295 return CpvAccess(_reduce_seqID_dynamic)+=CmiReductionID_multiplier;
02296 }
02297
02298 void CmiReductionHandleDynamicRequest(char *msg) {
02299 int *values = (int*)(msg+CmiMsgHeaderSizeBytes);
02300 int pe = values[0];
02301 int size = CmiMsgHeaderSizeBytes+2*sizeof(int)+values[1];
02302 values[0] = CmiGetDynamicReduction();
02303 CmiSetHandler(msg, CmiGetXHandler(msg));
02304 if (pe >= 0) {
02305 CmiSyncSendAndFree(pe, size, msg);
02306 } else {
02307 CmiSyncBroadcastAllAndFree(size, msg);
02308 }
02309 }
02310
02311 void CmiGetDynamicReductionRemote(int handlerIdx, int pe, int dataSize, void *data) {
02312 int size = CmiMsgHeaderSizeBytes+2*sizeof(int)+dataSize;
02313 char *msg = (char*)CmiAlloc(size);
02314 int *values = (int*)(msg+CmiMsgHeaderSizeBytes);
02315 values[0] = pe;
02316 values[1] = dataSize;
02317 CmiSetXHandler(msg, handlerIdx);
02318 if (dataSize) memcpy(msg+CmiMsgHeaderSizeBytes+2*sizeof(int), data, dataSize);
02319 if (CmiMyPe() == 0) {
02320 CmiReductionHandleDynamicRequest(msg);
02321 } else {
02322
02323 CmiSetHandler(msg, CpvAccess(CmiReductionDynamicRequestHandler));
02324 CmiSyncSendAndFree(0, size, msg);
02325 }
02326 }
02327
02328 void CmiSendReduce(CmiReduction *red) {
02329 void *mergedData, *msg;
02330 int msg_size;
02331 if (!red->localContributed || red->numChildren != red->numRemoteReceived) return;
02332 mergedData = red->localData;
02333 msg_size = red->localSize;
02334 if (red->numChildren > 0) {
02335 int i, offset=0;
02336 if (red->ops.pupFn != NULL) {
02337 offset = CmiReservedHeaderSize;
02338 for (i=0; i<red->numChildren; ++i) red->remoteData[i] += offset;
02339 }
02340 mergedData = (red->ops.mergeFn)(&msg_size, red->localData, (void **)red->remoteData, red->numChildren);
02341 for (i=0; i<red->numChildren; ++i) CmiFree(red->remoteData[i] - offset);
02342 }
02343
02344
02345 msg = mergedData;
02346 if (red->parent != -1) {
02347 if (red->ops.pupFn != NULL) {
02348 pup_er p = pup_new_sizer();
02349 (red->ops.pupFn)(p, mergedData);
02350 msg_size = pup_size(p) + CmiReservedHeaderSize;
02351 pup_destroy(p);
02352 msg = CmiAlloc(msg_size);
02353 p = pup_new_toMem((void*)(((char*)msg)+CmiReservedHeaderSize));
02354 (red->ops.pupFn)(p, mergedData);
02355 pup_destroy(p);
02356 if (red->ops.deleteFn != NULL) (red->ops.deleteFn)(red->localData);
02357 }
02358 CmiSetHandler(msg, CpvAccess(CmiReductionMessageHandler));
02359 CmiSetRedID(msg, red->seqID);
02360
02361 CmiSyncSendAndFree(red->parent, msg_size, msg);
02362 } else {
02363 (red->ops.destination)(msg);
02364 }
02365 CmiClearReduction(red->seqID);
02366 }
02367
02368 void *CmiReduceMergeFn_random(int *size, void *data, void** remote, int n) {
02369 return data;
02370 }
02371
02372 static void CmiGlobalReduce(void *msg, int size, CmiReduceMergeFn mergeFn, CmiReduction *red) {
02373 CmiAssert(red->localContributed == 0);
02374 red->localContributed = 1;
02375 red->localData = msg;
02376 red->localSize = size;
02377 red->numChildren = CmiNumSpanTreeChildren(CmiMyPe());
02378 red->parent = CmiSpanTreeParent(CmiMyPe());
02379 red->ops.destination = (CmiHandler)CmiGetHandlerFunction(msg);
02380 red->ops.mergeFn = mergeFn;
02381 red->ops.pupFn = NULL;
02382
02383 CmiSendReduce(red);
02384 }
02385
02386 static void CmiGlobalReduceStruct(void *data, CmiReducePupFn pupFn,
02387 CmiReduceMergeFn mergeFn, CmiHandler dest,
02388 CmiReduceDeleteFn deleteFn, CmiReduction *red) {
02389 CmiAssert(red->localContributed == 0);
02390 red->localContributed = 1;
02391 red->localData = data;
02392 red->localSize = 0;
02393 red->numChildren = CmiNumSpanTreeChildren(CmiMyPe());
02394 red->parent = CmiSpanTreeParent(CmiMyPe());
02395 red->ops.destination = dest;
02396 red->ops.mergeFn = mergeFn;
02397 red->ops.pupFn = pupFn;
02398 red->ops.deleteFn = deleteFn;
02399
02400 CmiSendReduce(red);
02401 }
02402
02403 void CmiReduce(void *msg, int size, CmiReduceMergeFn mergeFn) {
02404 CmiReduction *red = CmiGetNextReduction(CmiNumSpanTreeChildren(CmiMyPe()));
02405 CmiGlobalReduce(msg, size, mergeFn, red);
02406 }
02407
02408 void CmiReduceStruct(void *data, CmiReducePupFn pupFn,
02409 CmiReduceMergeFn mergeFn, CmiHandler dest,
02410 CmiReduceDeleteFn deleteFn) {
02411 CmiReduction *red = CmiGetNextReduction(CmiNumSpanTreeChildren(CmiMyPe()));
02412 CmiGlobalReduceStruct(data, pupFn, mergeFn, dest, deleteFn, red);
02413 }
02414
02415 void CmiReduceID(void *msg, int size, CmiReduceMergeFn mergeFn, CmiReductionID id) {
02416 CmiReduction *red = CmiGetReductionCreate(id, CmiNumSpanTreeChildren(CmiMyPe()));
02417 CmiGlobalReduce(msg, size, mergeFn, red);
02418 }
02419
02420 void CmiReduceStructID(void *data, CmiReducePupFn pupFn,
02421 CmiReduceMergeFn mergeFn, CmiHandler dest,
02422 CmiReduceDeleteFn deleteFn, CmiReductionID id) {
02423 CmiReduction *red = CmiGetReductionCreate(id, CmiNumSpanTreeChildren(CmiMyPe()));
02424 CmiGlobalReduceStruct(data, pupFn, mergeFn, dest, deleteFn, red);
02425 }
02426
02427 void CmiListReduce(int npes, int *pes, void *msg, int size, CmiReduceMergeFn mergeFn, CmiReductionID id) {
02428 CmiReduction *red = CmiGetReductionCreate(id, CmiNumSpanTreeChildren(CmiMyPe()));
02429 int myPos;
02430 CmiAssert(red->localContributed == 0);
02431 red->localContributed = 1;
02432 red->localData = msg;
02433 red->localSize = size;
02434 for (myPos=0; myPos<npes; ++myPos) {
02435 if (pes[myPos] == CmiMyPe()) break;
02436 }
02437 CmiAssert(myPos < npes);
02438 red->numChildren = npes - (myPos << 2) - 1;
02439 if (red->numChildren > 4) red->numChildren = 4;
02440 if (red->numChildren < 0) red->numChildren = 0;
02441 if (myPos == 0) red->parent = -1;
02442 else red->parent = pes[(myPos - 1) >> 2];
02443 red->ops.destination = (CmiHandler)CmiGetHandlerFunction(msg);
02444 red->ops.mergeFn = mergeFn;
02445 red->ops.pupFn = NULL;
02446
02447 CmiSendReduce(red);
02448 }
02449
02450 void CmiListReduceStruct(int npes, int *pes,
02451 void *data, CmiReducePupFn pupFn,
02452 CmiReduceMergeFn mergeFn, CmiHandler dest,
02453 CmiReduceDeleteFn deleteFn, CmiReductionID id) {
02454 CmiReduction *red = CmiGetReductionCreate(id, CmiNumSpanTreeChildren(CmiMyPe()));
02455 int myPos;
02456 CmiAssert(red->localContributed == 0);
02457 red->localContributed = 1;
02458 red->localData = data;
02459 red->localSize = 0;
02460 for (myPos=0; myPos<npes; ++myPos) {
02461 if (pes[myPos] == CmiMyPe()) break;
02462 }
02463 CmiAssert(myPos < npes);
02464 red->numChildren = npes - (myPos << 2) - 1;
02465 if (red->numChildren > 4) red->numChildren = 4;
02466 if (red->numChildren < 0) red->numChildren = 0;
02467 red->parent = (myPos - 1) >> 2;
02468 if (myPos == 0) red->parent = -1;
02469 red->ops.destination = dest;
02470 red->ops.mergeFn = mergeFn;
02471 red->ops.pupFn = pupFn;
02472 red->ops.deleteFn = deleteFn;
02473 CmiSendReduce(red);
02474 }
02475
02476 void CmiGroupReduce(CmiGroup grp, void *msg, int size, CmiReduceMergeFn mergeFn, CmiReductionID id) {
02477 int npes, *pes;
02478 CmiLookupGroup(grp, &npes, &pes);
02479 CmiListReduce(npes, pes, msg, size, mergeFn, id);
02480 }
02481
02482 void CmiGroupReduceStruct(CmiGroup grp, void *data, CmiReducePupFn pupFn,
02483 CmiReduceMergeFn mergeFn, CmiHandler dest,
02484 CmiReduceDeleteFn deleteFn, CmiReductionID id) {
02485 int npes, *pes;
02486 CmiLookupGroup(grp, &npes, &pes);
02487 CmiListReduceStruct(npes, pes, data, pupFn, mergeFn, dest, deleteFn, id);
02488 }
02489
02490 void CmiNodeReduce(void *data, int size, CmiReduceMergeFn mergeFn, int redID, int numChildren, int parent) {
02491 CmiAbort("Feel free to implement CmiNodeReduce...");
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503 }
02504 #if 0
02505 void CmiNodeReduce(void *data, int size, void * (*mergeFn)(void*,void**,int), int redID) {
02506 CmiNodeReduce(data, size, mergeFn, redID, CmiNumNodeSpanTreeChildren(CmiMyNode()),
02507 CmiNodeFirst(CmiNodeSpanTreeParent(CmiMyNode())));
02508 }
02509 void CmiNodeReduce(void *data, int size, void * (*mergeFn)(void*,void**,int), int numChildren, int parent) {
02510 CmiNodeReduce(data, size, mergeFn, CmiReduceNextID(), numChildren, parent);
02511 }
02512 void CmiNodeReduce(void *data, int size, void * (*mergeFn)(void*,void**,int)) {
02513 CmiNodeReduce(data, size, mergeFn, CmiReduceNextID(), CmiNumNodeSpanTreeChildren(CmiMyNode()),
02514 CmiNodeFirst(CmiNodeSpanTreeParent(CmiMyNode())));
02515 }
02516 #endif
02517
02518 void CmiNodeReduceStruct(void *data, CmiReducePupFn pupFn,
02519 CmiReduceMergeFn mergeFn, CmiHandler dest,
02520 CmiReduceDeleteFn deleteFn) {
02521 CmiAbort("Feel free to implement CmiNodeReduceStruct...");
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533 }
02534
02535 void CmiHandleReductionMessage(void *msg) {
02536 CmiReduction *red = CmiGetReduction(CmiGetRedID(msg));
02537 if (red->numRemoteReceived == red->numChildren) red = CmiGetReductionCreate(CmiGetRedID(msg), red->numChildren+4);
02538 red->remoteData[red->numRemoteReceived++] = msg;
02539
02540 CmiSendReduce(red);
02541
02542
02543
02544
02545 }
02546
02547 void CmiReductionsInit() {
02548 int i;
02549 CpvInitialize(int, CmiReductionMessageHandler);
02550 CpvAccess(CmiReductionMessageHandler) = CmiRegisterHandler((CmiHandler)CmiHandleReductionMessage);
02551 CpvInitialize(int, CmiReductionDynamicRequestHandler);
02552 CpvAccess(CmiReductionDynamicRequestHandler) = CmiRegisterHandler((CmiHandler)CmiReductionHandleDynamicRequest);
02553 CpvInitialize(CmiUInt2, _reduce_seqID_global);
02554 CpvAccess(_reduce_seqID_global) = CmiReductionID_globalOffset;
02555 CpvInitialize(CmiUInt2, _reduce_seqID_request);
02556 CpvAccess(_reduce_seqID_request) = CmiReductionID_requestOffset;
02557 CpvInitialize(CmiUInt2, _reduce_seqID_dynamic);
02558 CpvAccess(_reduce_seqID_dynamic) = CmiReductionID_dynamicOffset;
02559 CpvInitialize(int, _reduce_info_size);
02560 CpvAccess(_reduce_info_size) = 4;
02561 CpvInitialize(CmiReduction**, _reduce_info);
02562 CpvAccess(_reduce_info) = malloc(16*sizeof(CmiReduction*));
02563 for (i=0; i<16; ++i) CpvAccess(_reduce_info)[i] = NULL;
02564 }
02565
02566
02567
02568
02569
02570
02571
02572 #if CMK_MULTICAST_DEF_USE_COMMON_CODE
02573
02574 typedef struct GroupDef
02575 {
02576 union {
02577 char core[CmiMsgHeaderSizeBytes];
02578 struct GroupDef *next;
02579 } core;
02580 CmiGroup group;
02581 int npes;
02582 int pes[1];
02583 }
02584 *GroupDef;
02585
02586 #define GROUPTAB_SIZE 101
02587
02588 CpvStaticDeclare(int, CmiGroupHandlerIndex);
02589 CpvStaticDeclare(int, CmiGroupCounter);
02590 CpvStaticDeclare(GroupDef *, CmiGroupTable);
02591
02592 void CmiGroupHandler(GroupDef def)
02593 {
02594
02595 GroupDef *table = CpvAccess(CmiGroupTable);
02596 unsigned int hashval, bucket;
02597 hashval = (def->group.id ^ def->group.pe);
02598 bucket = hashval % GROUPTAB_SIZE;
02599 def->core.next = table[bucket];
02600 table[bucket] = def;
02601 }
02602
02603 CmiGroup CmiEstablishGroup(int npes, int *pes)
02604 {
02605
02606 CmiGroup grp; GroupDef def; int len, i;
02607 grp.id = CpvAccess(CmiGroupCounter)++;
02608 grp.pe = CmiMyPe();
02609 len = sizeof(struct GroupDef)+(npes*sizeof(int));
02610 def = (GroupDef)CmiAlloc(len);
02611 def->group = grp;
02612 def->npes = npes;
02613 for (i=0; i<npes; i++)
02614 def->pes[i] = pes[i];
02615 CmiSetHandler(def, CpvAccess(CmiGroupHandlerIndex));
02616 CmiSyncBroadcastAllAndFree(len, def);
02617 return grp;
02618 }
02619
02620 void CmiLookupGroup(CmiGroup grp, int *npes, int **pes)
02621 {
02622 unsigned int hashval, bucket; GroupDef def;
02623 GroupDef *table = CpvAccess(CmiGroupTable);
02624 hashval = (grp.id ^ grp.pe);
02625 bucket = hashval % GROUPTAB_SIZE;
02626 for (def=table[bucket]; def; def=def->core.next) {
02627 if ((def->group.id == grp.id)&&(def->group.pe == grp.pe)) {
02628 *npes = def->npes;
02629 *pes = def->pes;
02630 return;
02631 }
02632 }
02633 *npes = 0; *pes = 0;
02634 }
02635
02636 void CmiGroupInit()
02637 {
02638 CpvInitialize(int, CmiGroupHandlerIndex);
02639 CpvInitialize(int, CmiGroupCounter);
02640 CpvInitialize(GroupDef *, CmiGroupTable);
02641 CpvAccess(CmiGroupHandlerIndex) = CmiRegisterHandler((CmiHandler)CmiGroupHandler);
02642 CpvAccess(CmiGroupCounter) = 0;
02643 CpvAccess(CmiGroupTable) =
02644 (GroupDef*)calloc(GROUPTAB_SIZE, sizeof(GroupDef));
02645 if (CpvAccess(CmiGroupTable) == 0)
02646 CmiAbort("Memory Allocation Error");
02647 }
02648
02649 #endif
02650
02651
02652
02653
02654
02655
02656
02657 #if CMK_MULTICAST_LIST_USE_COMMON_CODE
02658
02659 void CmiSyncListSendFn(int npes, int *pes, int len, char *msg)
02660 {
02661 int i;
02662 #if CMK_BROADCAST_USE_CMIREFERENCE
02663 for(i=0;i<npes;i++) {
02664 if (pes[i] == CmiMyPe())
02665 CmiSyncSend(pes[i], len, msg);
02666 else {
02667 CmiReference(msg);
02668 CmiSyncSendAndFree(pes[i], len, msg);
02669 }
02670 }
02671 #else
02672 for(i=0;i<npes;i++) {
02673 CmiSyncSend(pes[i], len, msg);
02674 }
02675 #endif
02676 }
02677
02678 CmiCommHandle CmiAsyncListSendFn(int npes, int *pes, int len, char *msg)
02679 {
02680
02681 CmiSyncListSendFn(npes, pes, len, msg);
02682 return (CmiCommHandle) 0;
02683 }
02684
02685 void CmiFreeListSendFn(int npes, int *pes, int len, char *msg)
02686 {
02687 #if CMK_BROADCAST_USE_CMIREFERENCE
02688 if (npes == 1) {
02689 CmiSyncSendAndFree(pes[0], len, msg);
02690 return;
02691 }
02692 CmiSyncListSendFn(npes, pes, len, msg);
02693 CmiFree(msg);
02694 #else
02695 int i;
02696 for(i=0;i<npes-1;i++) {
02697 CmiSyncSend(pes[i], len, msg);
02698 }
02699 if (npes>0)
02700 CmiSyncSendAndFree(pes[npes-1], len, msg);
02701 else
02702 CmiFree(msg);
02703 #endif
02704 }
02705
02706 #endif
02707
02708 #if CMK_MULTICAST_GROUP_USE_COMMON_CODE
02709
02710 typedef struct MultiMsg
02711 {
02712 char core[CmiMsgHeaderSizeBytes];
02713 CmiGroup group;
02714 int pos;
02715 int origlen;
02716 }
02717 *MultiMsg;
02718
02719
02720 CpvDeclare(int, CmiMulticastHandlerIndex);
02721
02722 void CmiMulticastDeliver(MultiMsg msg)
02723 {
02724 int npes, *pes; int olen, nlen, pos, child1, child2;
02725 olen = msg->origlen;
02726 nlen = olen + sizeof(struct MultiMsg);
02727 CmiLookupGroup(msg->group, &npes, &pes);
02728 if (pes==0) {
02729 CmiSyncSendAndFree(CmiMyPe(), nlen, msg);
02730 return;
02731 }
02732 if (npes==0) {
02733 CmiFree(msg);
02734 return;
02735 }
02736 if (msg->pos == -1) {
02737 msg->pos=0;
02738 CmiSyncSendAndFree(pes[0], nlen, msg);
02739 return;
02740 }
02741 pos = msg->pos;
02742 child1 = ((pos+1)<<1);
02743 child2 = child1-1;
02744 if (child1 < npes) {
02745 msg->pos = child1;
02746 CmiSyncSend(pes[child1], nlen, msg);
02747 }
02748 if (child2 < npes) {
02749 msg->pos = child2;
02750 CmiSyncSend(pes[child2], nlen, msg);
02751 }
02752 if(olen < sizeof(struct MultiMsg)) {
02753 memcpy(msg, msg+1, olen);
02754 } else {
02755 memcpy(msg, (((char*)msg)+olen), sizeof(struct MultiMsg));
02756 }
02757 CmiSyncSendAndFree(CmiMyPe(), olen, msg);
02758 }
02759
02760 void CmiMulticastHandler(MultiMsg msg)
02761 {
02762 CmiMulticastDeliver(msg);
02763 }
02764
02765 void CmiSyncMulticastFn(CmiGroup grp, int len, char *msg)
02766 {
02767 int newlen; MultiMsg newmsg;
02768 newlen = len + sizeof(struct MultiMsg);
02769 newmsg = (MultiMsg)CmiAlloc(newlen);
02770 if(len < sizeof(struct MultiMsg)) {
02771 memcpy(newmsg+1, msg, len);
02772 } else {
02773 memcpy(newmsg+1, msg+sizeof(struct MultiMsg), len-sizeof(struct MultiMsg));
02774 memcpy(((char *)newmsg+len), msg, sizeof(struct MultiMsg));
02775 }
02776 newmsg->group = grp;
02777 newmsg->origlen = len;
02778 newmsg->pos = -1;
02779 CmiSetHandler(newmsg, CpvAccess(CmiMulticastHandlerIndex));
02780 CmiMulticastDeliver(newmsg);
02781 }
02782
02783 void CmiFreeMulticastFn(CmiGroup grp, int len, char *msg)
02784 {
02785 CmiSyncMulticastFn(grp, len, msg);
02786 CmiFree(msg);
02787 }
02788
02789 CmiCommHandle CmiAsyncMulticastFn(CmiGroup grp, int len, char *msg)
02790 {
02791 CmiError("Async Multicast not implemented.");
02792 return (CmiCommHandle) 0;
02793 }
02794
02795 void CmiMulticastInit()
02796 {
02797 CpvInitialize(int, CmiMulticastHandlerIndex);
02798 CpvAccess(CmiMulticastHandlerIndex) =
02799 CmiRegisterHandler((CmiHandler)CmiMulticastHandler);
02800 }
02801
02802 #endif
02803
02804 #if CONVERSE_VERSION_SHMEM && CMK_ARENA_MALLOC
02805 extern void *arena_malloc(int size);
02806 extern void arena_free(void *blockPtr);
02807 #endif
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832 void *CmiAlloc(int size)
02833 {
02834
02835 char *res;
02836
02837 #if CONVERSE_VERSION_ELAN
02838 res = (char *) elan_CmiAlloc(size+sizeof(CmiChunkHeader));
02839 #elif CONVERSE_VERSION_VMI
02840 res = (char *) CMI_VMI_CmiAlloc(size+sizeof(CmiChunkHeader));
02841 #elif CONVERSE_VERSION_SHMEM && CMK_ARENA_MALLOC
02842 res = (char*) arena_malloc(size+sizeof(CmiChunkHeader));
02843 #elif CMK_USE_IBVERBS | CMK_USE_IBUD
02844 res = (char *) infi_CmiAlloc(size+sizeof(CmiChunkHeader));
02845 #elif CMK_CONVERSE_GEMINI_UGNI
02846 res =(char *) LrtsAlloc(size, sizeof(CmiChunkHeader));
02847 #elif CONVERSE_POOL
02848 res =(char *) CmiPoolAlloc(size+sizeof(CmiChunkHeader));
02849 #else
02850 res =(char *) malloc_nomigrate(size+sizeof(CmiChunkHeader));
02851 #endif
02852
02853 _MEMCHECK(res);
02854
02855 #ifdef MEMMONITOR
02856 CpvAccess(MemoryUsage) += size+sizeof(CmiChunkHeader);
02857 CpvAccess(AllocCount)++;
02858 CpvAccess(BlocksAllocated)++;
02859 if (CpvAccess(MemoryUsage) > CpvAccess(HiWaterMark)) {
02860 CpvAccess(HiWaterMark) = CpvAccess(MemoryUsage);
02861 }
02862 if (CpvAccess(MemoryUsage) > 1.1 * CpvAccess(ReportedHiWaterMark)) {
02863 CmiPrintf("HIMEM STAT PE%d: %d Allocs, %d blocks, %lu K, Max %lu K\n",
02864 CmiMyPe(), CpvAccess(AllocCount), CpvAccess(BlocksAllocated),
02865 CpvAccess(MemoryUsage)/1024, CpvAccess(HiWaterMark)/1024);
02866 CpvAccess(ReportedHiWaterMark) = CpvAccess(MemoryUsage);
02867 }
02868 if ((CpvAccess(AllocCount) % 1000) == 0) {
02869 CmiPrintf("MEM STAT PE%d: %d Allocs, %d blocks, %lu K, Max %lu K\n",
02870 CmiMyPe(), CpvAccess(AllocCount), CpvAccess(BlocksAllocated),
02871 CpvAccess(MemoryUsage)/1024, CpvAccess(HiWaterMark)/1024);
02872 }
02873 #endif
02874
02875 res+=sizeof(CmiChunkHeader);
02876 SIZEFIELD(res)=size;
02877 REFFIELD(res)=1;
02878 return (void *)res;
02879 }
02880
02882 static void *CmiAllocFindEnclosing(void *blk) {
02883 int refCount = REFFIELD(blk);
02884 while (refCount < 0) {
02885 blk = (void *)((char*)blk+refCount);
02886 refCount = REFFIELD(blk);
02887 }
02888 return blk;
02889 }
02890
02891 int CmiGetReference(void *blk)
02892 {
02893 return REFFIELD(CmiAllocFindEnclosing(blk));
02894 }
02895
02898 void CmiReference(void *blk)
02899 {
02900 REFFIELD(CmiAllocFindEnclosing(blk))++;
02901 }
02902
02904 int CmiSize(void *blk)
02905 {
02906 return SIZEFIELD(blk);
02907 }
02908
02910 void CmiFree(void *blk)
02911 {
02912 void *parentBlk=CmiAllocFindEnclosing(blk);
02913 int refCount=REFFIELD(parentBlk);
02914 #if CMK_ERROR_CHECKING
02915 if(refCount==0)
02916 CmiAbort("CmiFree reference count was zero-- is this a duplicate free?");
02917 #endif
02918 refCount--;
02919 REFFIELD(parentBlk) = refCount;
02920 if(refCount==0) {
02921 #ifdef MEMMONITOR
02922 int size=SIZEFIELD(parentBlk);
02923 if (size > 1000000000)
02924 CmiPrintf("MEMSTAT Uh-oh -- SIZEFIELD=%d\n",size);
02925 CpvAccess(MemoryUsage) -= (size + sizeof(CmiChunkHeader));
02926 CpvAccess(BlocksAllocated)--;
02927 #endif
02928
02929 #if CONVERSE_VERSION_ELAN
02930 elan_CmiFree(BLKSTART(parentBlk));
02931 #elif CONVERSE_VERSION_VMI
02932 CMI_VMI_CmiFree(BLKSTART(parentBlk));
02933 #elif CONVERSE_VERSION_SHMEM && CMK_ARENA_MALLOC
02934 arena_free(BLKSTART(parentBlk));
02935 #elif CMK_USE_IBVERBS | CMK_USE_IBUD
02936
02937
02938
02939 #ifdef CMK_IBVERS_CLEAN_MULTIPLESEND
02940 if(CmiGetHandler(parentBlk)==CpvAccess(CmiMainHandlerIDP))
02941 {
02942 infi_freeMultipleSend(parentBlk);
02943 }
02944 #endif
02945 infi_CmiFree(BLKSTART(parentBlk));
02946 #elif CMK_CONVERSE_GEMINI_UGNI
02947 LrtsFree(BLKSTART(parentBlk));
02948 #elif CONVERSE_POOL
02949 CmiPoolFree(BLKSTART(parentBlk));
02950 #else
02951 free_nomigrate(BLKSTART(parentBlk));
02952 #endif
02953 }
02954 }
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967 #define CMI_TMP_BUF_MAX 128*1024
02968
02969 typedef struct {
02970 char *buf;
02971 int cur;
02972 int max;
02973 } CmiTmpBuf_t;
02974 CpvDeclare(CmiTmpBuf_t,CmiTmpBuf);
02975
02976 static void CmiTmpSetup(CmiTmpBuf_t *b) {
02977 b->buf=malloc(CMI_TMP_BUF_MAX);
02978 b->cur=0;
02979 b->max=CMI_TMP_BUF_MAX;
02980 }
02981
02982 void *CmiTmpAlloc(int size) {
02983 if (!CpvInitialized(CmiTmpBuf)) {
02984 return malloc(size);
02985 }
02986 else {
02987 CmiTmpBuf_t *b=&CpvAccess(CmiTmpBuf);
02988 void *t;
02989 if (b->cur+size>b->max) {
02990 if (b->max==0)
02991 CmiTmpSetup(b);
02992 else
02993 CmiAbort("CmiTmpAlloc: asked for too much temporary buffer space");
02994 }
02995 t=b->buf+b->cur;
02996 b->cur+=size;
02997 return t;
02998 }
02999 }
03000 void CmiTmpFree(void *t) {
03001 if (!CpvInitialized(CmiTmpBuf)) {
03002 free(t);
03003 }
03004 else {
03005 CmiTmpBuf_t *b=&CpvAccess(CmiTmpBuf);
03006
03007 int cur=((const char *)t)-b->buf;
03008 #if CMK_ERROR_CHECKING
03009 if (cur<0 || cur>b->max)
03010 CmiAbort("CmiTmpFree: called with an invalid pointer");
03011 #endif
03012 b->cur=cur;
03013 }
03014 }
03015
03016 void CmiTmpInit(char **argv) {
03017 CpvInitialize(CmiTmpBuf_t,CmiTmpBuf);
03018
03019 CmiTmpSetup(&CpvAccess(CmiTmpBuf));
03020 }
03021
03022
03023
03024
03025
03026
03027 #ifdef _MSC_VER
03028
03029 #include <windows.h>
03030
03031 void CmiMkdir(const char *dirName) {
03032 CreateDirectory(dirName,NULL);
03033 }
03034
03035 #else
03036
03037 #include <unistd.h>
03038 #include <sys/stat.h>
03039 #include <sys/types.h>
03040
03041 void CmiMkdir(const char *dirName) {
03042 #ifndef __MINGW_H
03043 mkdir(dirName,0777);
03044 #else
03045 mkdir(dirName);
03046 #endif
03047 }
03048
03049 #endif
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075 static int roundUpSize(unsigned int s) {
03076 return (int)((s+sizeof(double)-1)&~(sizeof(double)-1));
03077 }
03078
03079
03080
03081 static int paddingSize(unsigned int s) {
03082 return roundUpSize(s)-s;
03083 }
03084
03085
03086 typedef struct {
03087 char convHeader[CmiMsgHeaderSizeBytes];
03088 int nMessages;
03089 double pad;
03090 } CmiMultipleSendHeader;
03091
03092 #if CMK_USE_IBVERBS | CMK_USE_IBUD
03093
03094
03095 void infi_freeMultipleSend(void *msgWhole)
03096 {
03097 int len=((CmiMultipleSendHeader *)msgWhole)->nMessages;
03098 double pad=((CmiMultipleSendHeader *)msgWhole)->pad;
03099 int offset=sizeof(CmiMultipleSendHeader);
03100 int m;
03101 void *thisMsg=NULL;
03102 if (pad != 1234567.89) return;
03103 for(m=0;m<len;m++)
03104 {
03105
03106
03107
03108 infiCmiChunkHeader *ch=(infiCmiChunkHeader *)(msgWhole+offset);
03109 char *msg=(msgWhole+offset+sizeof(infiCmiChunkHeader));
03110 int msgSize=ch->chunkHeader.size;
03111 infi_unregAndFreeMeta(ch->metaData);
03112 offset+= sizeof(infiCmiChunkHeader) + msgSize;
03113 }
03114 }
03115 #endif
03116
03117
03118 static void _CmiMultipleSend(unsigned int destPE, int len, int sizes[], char *msgComps[], int immed)
03119 {
03120 CmiMultipleSendHeader header;
03121 int m;
03122
03123 #if CMK_USE_IBVERBS
03124 infiCmiChunkHeader *msgHdr;
03125 #else
03126 CmiChunkHeader *msgHdr;
03127 #endif
03128
03129 double pad = 0;
03130 int vecLen;
03131 int *vecSizes;
03132 char **vecPtrs;
03133 int vec;
03134
03135 #if CMK_USE_IBVERBS
03136 msgHdr = (infiCmiChunkHeader *)CmiTmpAlloc(len * sizeof(infiCmiChunkHeader));
03137 #else
03138 msgHdr = (CmiChunkHeader *)CmiTmpAlloc(len * sizeof(CmiChunkHeader));
03139 #endif
03140
03141
03142 vecLen=1+3*len;
03143 vecSizes = (int *)CmiTmpAlloc(vecLen * sizeof(int));
03144 vecPtrs = (char **)CmiTmpAlloc(vecLen * sizeof(char *));
03145 vec=0;
03146
03147
03148 header.nMessages=len;
03149 CmiSetHandler(&header, CpvAccess(CmiMainHandlerIDP));
03150 header.pad = 1234567.89;
03151 #if CMK_IMMEDIATE_MSG
03152 if (immed) CmiBecomeImmediate(&header);
03153 #endif
03154 vecSizes[vec]=sizeof(header); vecPtrs[vec]=(char *)&header;
03155 vec++;
03156
03157
03158
03159
03160 for (m=0;m<len;m++) {
03161 #if CMK_USE_IBVERBS
03162 msgHdr[m].chunkHeader.size=roundUpSize(sizes[m]);
03163 msgHdr[m].chunkHeader.ref=0;
03164 msgHdr[m].metaData=NULL;
03165 #else
03166 msgHdr[m].size=roundUpSize(sizes[m]);
03167 msgHdr[m].ref=0;
03168 #endif
03169
03170
03171 #if CMK_USE_IBVERBS
03172 vecSizes[vec]=sizeof(infiCmiChunkHeader);
03173 #else
03174 vecSizes[vec]=sizeof(CmiChunkHeader);
03175 #endif
03176 vecPtrs[vec]=(char *)&msgHdr[m];
03177 vec++;
03178
03179
03180 vecSizes[vec]=sizes[m]; vecPtrs[vec]=msgComps[m];
03181 vec++;
03182
03183
03184 vecSizes[vec]=paddingSize(sizes[m]); vecPtrs[vec]=(char *)&pad;
03185 vec++;
03186 }
03187 CmiAssert(vec==vecLen);
03188
03189 CmiSyncVectorSend(destPE, vecLen, vecSizes, vecPtrs);
03190
03191 CmiTmpFree(vecPtrs);
03192 CmiTmpFree(vecSizes);
03193 CmiTmpFree(msgHdr);
03194 }
03195
03196 void CmiMultipleSend(unsigned int destPE, int len, int sizes[], char *msgComps[])
03197 {
03198 _CmiMultipleSend(destPE, len, sizes, msgComps, 0);
03199 }
03200
03201 void CmiMultipleIsend(unsigned int destPE, int len, int sizes[], char *msgComps[])
03202 {
03203 _CmiMultipleSend(destPE, len, sizes, msgComps, 1);
03204 }
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215 static void CmiMultiMsgHandler(char *msgWhole);
03216
03217 void CmiInitMultipleSend(void)
03218 {
03219 CpvInitialize(int,CmiMainHandlerIDP);
03220 CpvAccess(CmiMainHandlerIDP) =
03221 CmiRegisterHandler((CmiHandler)CmiMultiMsgHandler);
03222 }
03223
03224
03225
03226
03227
03228
03229
03230 static void CmiMultiMsgHandler(char *msgWhole)
03231 {
03232 int len=((CmiMultipleSendHeader *)msgWhole)->nMessages;
03233 int offset=sizeof(CmiMultipleSendHeader);
03234 int m;
03235 for (m=0;m<len;m++) {
03236 #if CMK_USE_IBVERBS
03237 infiCmiChunkHeader *ch=(infiCmiChunkHeader *)(msgWhole+offset);
03238 char *msg=(msgWhole+offset+sizeof(infiCmiChunkHeader));
03239 int msgSize=ch->chunkHeader.size;
03240 ch->chunkHeader.ref=msgWhole-msg;
03241 ch->metaData = registerMultiSendMesg(msg,msgSize);
03242 #else
03243 CmiChunkHeader *ch=(CmiChunkHeader *)(msgWhole+offset);
03244 char *msg=(msgWhole+offset+sizeof(CmiChunkHeader));
03245 int msgSize=ch->size;
03246 ch->ref=msgWhole-msg;
03247 #endif
03248
03249 CmiReference(msg);
03250 CmiSyncSendAndFree(CmiMyPe(), msgSize, msg);
03251 #if CMK_USE_IBVERBS
03252 offset+= sizeof(infiCmiChunkHeader) + msgSize;
03253 #else
03254 offset+= sizeof(CmiChunkHeader) + msgSize;
03255 #endif
03256 }
03257
03258
03259 CmiFree(msgWhole);
03260 }
03261
03262
03263
03264
03265
03266 int HypercubeGetBcastDestinations(int mype, int total_pes, int k, int *dest_pes) {
03267 int num_pes = 0;
03268 for ( ; k>=0; --k) {
03269
03270 dest_pes[num_pes] = mype ^ (1<<k);
03271 if (dest_pes[num_pes] >= total_pes) {
03272
03273 dest_pes[num_pes] &= (-1)<<k;
03274
03275
03276
03277 if (total_pes>dest_pes[num_pes]) dest_pes[num_pes] += (mype - (mype & ((-1)<<k))) % (total_pes - dest_pes[num_pes]);
03278 }
03279 if (dest_pes[num_pes] < total_pes) {
03280
03281 ++num_pes;
03282 }
03283 }
03284 return num_pes;
03285 }
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296 int _immediateLock = 0;
03297 int _immediateFlag = 0;
03298
03299 CpvDeclare(int, CmiImmediateMsgHandlerIdx);
03300
03301
03302 static void CmiImmediateMsgHandler(char *msg)
03303 {
03304 CmiSetHandler(msg, CmiGetXHandler(msg));
03305 CmiHandleMessage(msg);
03306 }
03307
03308 void CmiInitImmediateMsg(void)
03309 {
03310 CpvInitialize(int,CmiImmediateMsgHandlerIdx);
03311 CpvAccess(CmiImmediateMsgHandlerIdx) =
03312 CmiRegisterHandler((CmiHandler)CmiImmediateMsgHandler);
03313 }
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325 typedef struct {
03326 int idle_timeout;
03327 int is_idle;
03328 int call_count;
03329 } cmi_cpu_idlerec;
03330
03331 static void on_timeout(cmi_cpu_idlerec *rec,double curWallTime)
03332 {
03333 rec->call_count--;
03334 if(rec->call_count==0 && rec->is_idle==1) {
03335 CmiError("Idle time on PE %d exceeded specified timeout.\n", CmiMyPe());
03336 CmiAbort("Exiting.\n");
03337 }
03338 }
03339 static void on_idle(cmi_cpu_idlerec *rec,double curWallTime)
03340 {
03341 CcdCallFnAfter((CcdVoidFn)on_timeout, rec, rec->idle_timeout);
03342 rec->call_count++;
03343 rec->is_idle = 1;
03344 }
03345 static void on_busy(cmi_cpu_idlerec *rec,double curWallTime)
03346 {
03347 rec->is_idle = 0;
03348 }
03349 static void CIdleTimeoutInit(char **argv)
03350 {
03351 int idle_timeout=0;
03352 CmiGetArgIntDesc(argv,"+idle-timeout",&idle_timeout,"Abort if idle for this many seconds");
03353 if(idle_timeout != 0) {
03354 cmi_cpu_idlerec *rec=(cmi_cpu_idlerec *)malloc(sizeof(cmi_cpu_idlerec));
03355 _MEMCHECK(rec);
03356 rec->idle_timeout=idle_timeout*1000;
03357 rec->is_idle=0;
03358 rec->call_count=0;
03359 CcdCallOnCondition(CcdPROCESSOR_BEGIN_IDLE, (CcdVoidFn)on_idle, rec);
03360 CcdCallOnCondition(CcdPROCESSOR_BEGIN_BUSY, (CcdVoidFn)on_busy, rec);
03361 }
03362 }
03363
03364
03365
03366
03367
03368
03369
03370 extern void CrnInit(void);
03371 extern void CmiIsomallocInit(char **argv);
03372 #if ! CMK_CMIPRINTF_IS_A_BUILTIN
03373 void CmiIOInit(char **argv);
03374 #endif
03375
03376
03377 extern void CmiInitCPUAffinityUtil();
03378
03379 static void CmiProcessPriority(char **argv)
03380 {
03381 int dummy, nicelevel=-100;
03382 CmiGetArgIntDesc(argv,"+nice",&nicelevel,"Set the process priority level");
03383
03384 while (CmiGetArgIntDesc(argv,"+nice",&dummy,"Set the process priority level"));
03385
03386 if (CmiMyRank() == 0 && nicelevel != -100) {
03387 #ifndef _WIN32
03388 if (0!=setpriority(PRIO_PROCESS, 0, nicelevel)) {
03389 CmiPrintf("[%d] setpriority failed with value %d. \n", CmiMyPe(), nicelevel);
03390 perror("setpriority");
03391 CmiAbort("setpriority failed.");
03392 }
03393 else
03394 CmiPrintf("[%d] Charm++: setpriority %d\n", CmiMyPe(), nicelevel);
03395 #else
03396 HANDLE hProcess = GetCurrentProcess();
03397 DWORD dwPriorityClass = NORMAL_PRIORITY_CLASS;
03398 char *prio_str = "NORMAL_PRIORITY_CLASS";
03399 BOOL status;
03400
03401
03402
03403
03404
03405
03406
03407
03408 if (0) ;
03409 #ifdef BELOW_NORMAL_PRIORITY_CLASS
03410 else if (nicelevel<10 && nicelevel>0) {
03411 dwPriorityClass = BELOW_NORMAL_PRIORITY_CLASS;
03412 prio_str = "BELOW_NORMAL_PRIORITY_CLASS";
03413 }
03414 #endif
03415 else if (nicelevel>0) {
03416 dwPriorityClass = IDLE_PRIORITY_CLASS;
03417 prio_str = "IDLE_PRIORITY_CLASS";
03418 }
03419 else if (nicelevel<=-20) {
03420 dwPriorityClass = REALTIME_PRIORITY_CLASS;
03421 prio_str = "REALTIME_PRIORITY_CLASS";
03422 }
03423 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
03424 else if (nicelevel>-10 && nicelevel<0) {
03425 dwPriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
03426 prio_str = "ABOVE_NORMAL_PRIORITY_CLASS";
03427 }
03428 #endif
03429 else if (nicelevel<0) {
03430 dwPriorityClass = HIGH_PRIORITY_CLASS;
03431 prio_str = "HIGH_PRIORITY_CLASS";
03432 }
03433 status = SetPriorityClass(hProcess, dwPriorityClass);
03434 if (!status) {
03435 int err=GetLastError();
03436 CmiPrintf("SetPriorityClass failed errno=%d, WSAerr=%d\n",errno, err);
03437 CmiAbort("SetPriorityClass failed.");
03438 }
03439 else
03440 CmiPrintf("[%d] Charm++: setpriority %s\n", CmiMyPe(), prio_str);
03441 #endif
03442 }
03443 }
03444
03445 void CommunicationServerInit()
03446 {
03447 #if CMK_IMMEDIATE_MSG
03448 CQdCpvInit();
03449 CpvInitialize(int,CmiImmediateMsgHandlerIdx);
03450 #endif
03451 }
03452
03453
03454 static int testEndian(void)
03455 {
03456 int test=0x1c;
03457 unsigned char *c=(unsigned char *)&test;
03458 if (c[sizeof(int)-1]==0x1c)
03459
03460 return 1;
03461 if (c[0]==0x1c)
03462
03463 return 0;
03464 return -2;
03465 }
03466
03467 int CmiEndianness()
03468 {
03469 static int _cmi_endianness = -1;
03470 if (_cmi_endianness == -1) _cmi_endianness = testEndian();
03471 CmiAssert(_cmi_endianness != -2);
03472 return _cmi_endianness;
03473 }
03474
03500 void ConverseCommonInit(char **argv)
03501 {
03502
03514 CpvInitialize(int, _urgentSend);
03515 CpvAccess(_urgentSend) = 0;
03516 #if CMK_CCS_AVAILABLE
03517 CpvInitialize(int, cmiArgDebugFlag);
03518 CpvAccess(cmiArgDebugFlag) = 0;
03519 #endif
03520 CpvInitialize(int,charmLibExitFlag);
03521 CpvAccess(charmLibExitFlag) = 0;
03522
03523 CpvInitialize(int,_curRestartPhase);
03524 CpvAccess(_curRestartPhase)=1;
03525 CmiArgInit(argv);
03526 CmiMemoryInit(argv);
03527 #if ! CMK_CMIPRINTF_IS_A_BUILTIN
03528 CmiIOInit(argv);
03529 #endif
03530 if (CmiMyPe() == 0)
03531 CmiPrintf("Converse/Charm++ Commit ID: %s\n", CmiCommitID);
03532
03533 CpvInitialize(int, cmiMyPeIdle);
03534 CpvAccess(cmiMyPeIdle) = 0;
03535
03536
03537 CmiPoolAllocInit(30);
03538
03539 CmiTmpInit(argv);
03540 CmiTimerInit(argv);
03541 CstatsInit(argv);
03542 CmiInitCPUAffinityUtil();
03543
03544 CcdModuleInit(argv);
03545 CmiHandlerInit();
03546 CmiReductionsInit();
03547 CIdleTimeoutInit(argv);
03548
03549 #if CMK_SHARED_VARS_POSIX_THREADS_SMP
03550 if(CmiGetArgFlagDesc(argv,"+CmiNoProcForComThread","Is there an extra processor for the communication thread on each node(only for net-smp-*) ?")){
03551 if(CmiMyRank() == 0) _Cmi_noprocforcommthread=1;
03552 }
03553 #endif
03554
03555 #if CMK_TRACE_ENABLED
03556 traceInit(argv);
03557
03558 #endif
03559 CmiProcessPriority(argv);
03560
03561 CmiPersistentInit();
03562 CmiIsomallocInit(argv);
03563 CmiDeliversInit();
03564 CsdInit(argv);
03565 #if CMK_CCS_AVAILABLE
03566 CcsInit(argv);
03567 #endif
03568 CpdInit();
03569 CthSchedInit();
03570 CmiGroupInit();
03571 CmiMulticastInit();
03572 CmiInitMultipleSend();
03573 CQdInit();
03574
03575 CrnInit();
03576 CmiInitImmediateMsg();
03577 CldModuleInit(argv);
03578
03579 #if CMK_CELL
03580 void CmiInitCell();
03581 CmiInitCell();
03582 #endif
03583
03584 #ifdef CMK_CUDA
03585 initHybridAPI(CmiMyPe());
03586 #endif
03587
03588
03589
03590
03591
03592
03593 #if CMK_BIGSIM_CHARM
03594
03595 extern void initQd(char **argv);
03596 initQd(argv);
03597 #endif
03598 }
03599
03600 void ConverseCommonExit(void)
03601 {
03602 CcsImpl_kill();
03603
03604 #if CMK_TRACE_ENABLED
03605 traceClose();
03606
03607 #endif
03608
03609 #if CMI_IO_BUFFER_EXPLICIT
03610 CmiFlush(stdout);
03611 #endif
03612
03613 #if CMK_CELL
03614 CloseOffloadAPI();
03615 #endif
03616
03617 #if CMK_CUDA
03618 exitHybridAPI();
03619 #endif
03620 seedBalancerExit();
03621 EmergencyExit();
03622 }
03623
03624
03625 #if CMK_CELL != 0
03626
03627 extern void register_accel_spe_funcs(void);
03628
03629 void CmiInitCell()
03630 {
03631
03632
03633 char fileNameBuf[64];
03634 sprintf(fileNameBuf, "speTiming.%d", CmiMyPe());
03635
03636 InitOffloadAPI(offloadCallback, NULL, NULL, fileNameBuf);
03637
03638
03639 CcdCallOnConditionKeep(CcdPROCESSOR_STILL_IDLE,
03640 (CcdVoidFn) OffloadAPIProgress, NULL);
03641
03642
03643 register_accel_spe_funcs();
03644 }
03645
03646 #include "cell-api.c"
03647
03648 #endif
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659 #if ! CMK_CMIPRINTF_IS_A_BUILTIN
03660 void CmiIOInit(char **argv) {
03661 CpvInitialize(int, expIOFlushFlag);
03662 #if CMI_IO_BUFFER_EXPLICIT
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673 CpvInitialize(char*, explicitIOBuffer);
03674 CpvInitialize(int, expIOBufferSize);
03675 if (!CmiGetArgIntDesc(argv,"+io_buffer_size", &CpvAccess(expIOBufferSize),
03676 "Explicit IO Buffer Size")) {
03677 CpvAccess(expIOBufferSize) = DEFAULT_IO_BUFFER_SIZE;
03678 }
03679 if (CpvAccess(expIOBufferSize) <= 0) {
03680 CpvAccess(expIOBufferSize) = DEFAULT_IO_BUFFER_SIZE;
03681 }
03682 CpvAccess(explicitIOBuffer) = (char*)CmiAlloc(CpvAccess(expIOBufferSize)*
03683 sizeof(char));
03684 if (setvbuf(stdout, CpvAccess(explicitIOBuffer), _IOFBF,
03685 CpvAccess(expIOBufferSize))) {
03686 CmiAbort("Explicit IO Buffering failed\n");
03687 }
03688 #endif
03689 #if CMI_IO_FLUSH_USER
03690
03691
03692 CpvAccess(expIOFlushFlag) = !CmiGetArgFlagDesc(argv,"+io_flush_system",
03693 "System Controls IO Flush");
03694 #else
03695
03696
03697 CpvAccess(expIOFlushFlag) = CmiGetArgFlagDesc(argv,"+io_flush_user",
03698 "User Controls IO Flush");
03699 #endif
03700 }
03701 #endif
03702
03703 #if ! CMK_CMIPRINTF_IS_A_BUILTIN
03704
03705 void CmiPrintf(const char *format, ...)
03706 {
03707 CpdSystemEnter();
03708 {
03709 va_list args;
03710 va_start(args,format);
03711 vfprintf(stdout,format, args);
03712 if (CpvInitialized(expIOFlushFlag) && !CpvAccess(expIOFlushFlag)) {
03713 CmiFlush(stdout);
03714 }
03715 va_end(args);
03716 #if CMK_CCS_AVAILABLE
03717 if (CpvAccess(cmiArgDebugFlag)) {
03718 va_start(args,format);
03719 print_node0(format, args);
03720 va_end(args);
03721 }
03722 #endif
03723 }
03724 CpdSystemExit();
03725 }
03726
03727 void CmiError(const char *format, ...)
03728 {
03729 CpdSystemEnter();
03730 {
03731 va_list args;
03732 va_start(args,format);
03733 vfprintf(stderr,format, args);
03734 CmiFlush(stderr);
03735 va_end(args);
03736 #if CMK_CCS_AVAILABLE
03737 if (CpvAccess(cmiArgDebugFlag)) {
03738 va_start(args,format);
03739 print_node0(format, args);
03740 va_end(args);
03741 }
03742 #endif
03743 }
03744 CpdSystemExit();
03745 }
03746
03747 #endif
03748
03749 void __cmi_assert(const char *expr, const char *file, int line)
03750 {
03751 CmiError("[%d] Assertion \"%s\" failed in file %s line %d.\n",
03752 CmiMyPe(), expr, file, line);
03753 CmiAbort("");
03754 }
03755
03756 char *CmiCopyMsg(char *msg, int len)
03757 {
03758 char *copy = (char *)CmiAlloc(len);
03759 _MEMCHECK(copy);
03760 memcpy(copy, msg, len);
03761 return copy;
03762 }
03763
03764 unsigned char computeCheckSum(unsigned char *data, int len)
03765 {
03766 int i;
03767 unsigned char ret = 0;
03768 for (i=0; i<len; i++) ret ^= (unsigned char)data[i];
03769 return ret;
03770 }
03771
03772
03773 int _BgOutOfCoreFlag=0;
03774 int _BgInOutOfCoreMode=0;
03775
03776 #if !CMK_HAS_LOG2
03777 unsigned int CmiILog2(unsigned int val) {
03778 unsigned int log = 0u;
03779 if ( val != 0u ) {
03780 while ( val > (1u<<log) ) { log++; }
03781 }
03782 return log;
03783 }
03784 double CmiLog2(double x) {
03785 return log(x)/log(2);
03786 }
03787 #endif
03788
03789
03790 int CmiMyRank_()
03791 {
03792 return CmiMyRank();
03793 }
03794
03795 double CmiReadSize(const char *str)
03796 {
03797 double val;
03798 if (strpbrk(str,"Gg")) {
03799
03800
03801 val = atof(str);
03802 val *= 1024ll*1024*1024;
03803 }
03804 else if (strpbrk(str,"Mm")) {
03805 val = atof(str);
03806 val *= 1024*1024;
03807 }
03808 else if (strpbrk(str,"Kk")) {
03809 val = atof(str);
03810 val *= 1024;
03811 }
03812 else {
03813 val = atof(str);
03814 }
03815 return val;
03816 }
03817
03818 int CmiIsMyNodeIdle(){
03819 int i;
03820 for(i=0; i<CmiMyNodeSize(); i++){
03821 if(CpvAccessOther(cmiMyPeIdle, i)) return 1;
03822 }
03823 return 0;
03824 }
03825