arch/uth/machine.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * $Source: /cvsroot/charm/src/arch/uth/machine.c,v $
00003  * $Author: gzheng $
00004  * $Date: 2008-04-23 18:15:17 $
00005  * $Revision: 1.55 $
00006  *****************************************************************************/
00007 
00014 #include <stdio.h>
00015 #include <math.h>
00016 #include "converse.h"
00017 
00018 /***********************************************************************
00019  *
00020  * Abort function:
00021  *
00022  ************************************************************************/
00023 
00024 void CmiAbort(const char *message)
00025 {
00026   CmiError(message);
00027   exit(1);
00028 }
00029 
00030 /*****************************************************************************
00031  *
00032  * Module variables
00033  * 
00034  ****************************************************************************/
00035 
00036 int        _Cmi_mype;
00037 int        _Cmi_myrank;
00038 int        _Cmi_numpes;
00039 int        Cmi_nodesize;
00040 int        Cmi_stacksize = 64000;
00041 char     **CmiArgv;
00042 CmiStartFn CmiStart;
00043 int        CmiUsched;
00044 CthThread *CmiThreads;
00045 void*      *CmiQueues;
00046 int       *CmiBarred;
00047 int        CmiNumBarred=0;
00048 
00049 CpvDeclare(void*, CmiLocalQueue);
00050 
00051 /*****************************************************************************
00052  *
00053  * Comm handles are nonexistent in uth version
00054  *
00055  *****************************************************************************/
00056 
00057 int CmiAsyncMsgSent(c)
00058 CmiCommHandle c ;
00059 {
00060   return 1;
00061 }
00062 
00063 void CmiReleaseCommHandle(c)
00064 CmiCommHandle c ;
00065 {
00066 }
00067 
00068 /********************* CONTEXT-SWITCHING FUNCTIONS ******************/
00069 
00070 static void CmiNext()
00071 {
00072   CthThread t; int index; int orig;
00073   index = (CmiMyPe()+1) % CmiNumPes();
00074   orig = index;
00075   while (1) {
00076     t = CmiThreads[index];
00077     if ((t)&&(!CmiBarred[index])) break;
00078     index = (index+1) % CmiNumPes();
00079     if (index == orig) exit(0);
00080   }
00081   _Cmi_mype = index;
00082   CthResume(t);
00083 }
00084 
00085 void CmiExit()
00086 {
00087   CmiThreads[CmiMyPe()] = 0;
00088   CmiFree(CthSelf());
00089   CmiNext();
00090 }
00091 
00092 void *CmiGetNonLocal()
00093 {
00094   CmiThreads[CmiMyPe()] = CthSelf();
00095   CmiNext();
00096   return 0;
00097 }
00098 
00099 void CmiNotifyIdle()
00100 {
00101   CmiThreads[CmiMyPe()] = CthSelf();
00102   CmiNext();
00103 }
00104 
00105 void CmiNodeBarrier()
00106 {
00107   int i;
00108   CmiNumBarred++;
00109   CmiBarred[CmiMyPe()] = 1;
00110   if (CmiNumBarred == CmiNumPes()) {
00111     for (i=0; i<CmiNumPes(); i++) CmiBarred[i]=0;
00112     CmiNumBarred=0;
00113   }
00114   CmiGetNonLocal();
00115 }
00116 
00117 void CmiNodeAllBarrier()
00118 {
00119   int i;
00120   CmiNumBarred++;
00121   CmiBarred[CmiMyPe()] = 1;
00122   if (CmiNumBarred == CmiNumPes()) {
00123     for (i=0; i<CmiNumPes(); i++) CmiBarred[i]=0;
00124     CmiNumBarred=0;
00125   }
00126   CmiGetNonLocal();
00127 }
00128 
00129 CmiNodeLock CmiCreateLock()
00130 {
00131   CmiNodeLock lk = (CmiNodeLock)malloc(sizeof(int));
00132   *lk = 0;
00133   return lk;
00134 }
00135 
00136 void CmiLock(CmiNodeLock lk)
00137 {
00138   while (*lk) CmiGetNonLocal();
00139   *lk = 1;
00140 }
00141 
00142 void CmiUnlock(CmiNodeLock lk)
00143 {
00144   if (*lk==0) {
00145     CmiError("CmiNodeLock not locked, can't unlock.");
00146     exit(1);
00147   }
00148   *lk = 0;
00149 }
00150 
00151 int CmiTryLock(CmiNodeLock lk)
00152 {
00153   if (*lk==0) { *lk=1; return 0; }
00154   return -1;
00155 }
00156 
00157 void CmiDestroyLock(CmiNodeLock lk)
00158 {
00159   free(lk);
00160 }
00161 
00162 
00163 
00164 /********************* MESSAGE SEND FUNCTIONS ******************/
00165 
00166 void CmiSyncSendFn(destPE, size, msg)
00167 int destPE;
00168 int size;
00169 char * msg;
00170 {
00171   char *buf = (char *)CmiAlloc(size);
00172   memcpy(buf,msg,size);
00173   CdsFifo_Enqueue(CmiQueues[destPE],buf);
00174   CQdCreate(CpvAccess(cQdState), 1);
00175 }
00176 
00177 CmiCommHandle CmiAsyncSendFn(destPE, size, msg) 
00178 int destPE;
00179 int size;
00180 char * msg;
00181 {
00182   char *buf = (char *)CmiAlloc(size);
00183   memcpy(buf,msg,size);
00184   CdsFifo_Enqueue(CmiQueues[destPE],buf);
00185   CQdCreate(CpvAccess(cQdState), 1);
00186   return 0;
00187 }
00188 
00189 void CmiFreeSendFn(destPE, size, msg)
00190 int destPE;
00191 int size;
00192 char * msg;
00193 {
00194   CdsFifo_Enqueue(CmiQueues[destPE], msg);
00195   CQdCreate(CpvAccess(cQdState), 1);
00196 }
00197 
00198 void CmiSyncBroadcastFn(size, msg)
00199 int size;
00200 char * msg;
00201 {
00202   int i;
00203   for(i=0; i<CmiNumPes(); i++)
00204     if (i != CmiMyPe()) CmiSyncSendFn(i,size,msg);
00205 }
00206 
00207 CmiCommHandle CmiAsyncBroadcastFn(size, msg)
00208 int size;
00209 char * msg;
00210 {
00211   CmiSyncBroadcastFn(size, msg);
00212   return 0;
00213 }
00214 
00215 void CmiFreeBroadcastFn(size, msg)
00216 int size;
00217 char * msg;
00218 {
00219   CmiSyncBroadcastFn(size, msg);
00220   CmiFree(msg);
00221 }
00222 
00223 void CmiSyncBroadcastAllFn(size, msg)
00224 int size;
00225 char * msg;
00226 {
00227   int i;
00228   for(i=0; i<CmiNumPes(); i++)
00229     CmiSyncSendFn(i,size,msg);
00230 }
00231 
00232 CmiCommHandle CmiAsyncBroadcastAllFn(size, msg)
00233 int size;
00234 char * msg;
00235 {
00236   CmiSyncBroadcastAllFn(size,msg);
00237   return 0 ;
00238 }
00239 
00240 void CmiFreeBroadcastAllFn(size, msg)
00241 int size;
00242 char * msg;
00243 {
00244   int i;
00245   for(i=0; i<CmiNumPes(); i++)
00246     if (i!=CmiMyPe()) CmiSyncSendFn(i,size,msg);
00247   CdsFifo_Enqueue(CpvAccess(CmiLocalQueue),msg);
00248   CQdCreate(CpvAccess(cQdState), 1);
00249 }
00250 
00251 
00252 int CmiBarrier()
00253 {
00254   return -1;
00255 }
00256 
00257 int CmiBarrierZero()
00258 {
00259   return -1;
00260 }
00261 
00262 /************************** SETUP ***********************************/
00263 
00264 static void CmiParseArgs(argv)
00265 char **argv;
00266 {
00267   CmiGetArgInt(argv,"++stacksize",&Cmi_stacksize);
00268   _Cmi_numpes=1;
00269   CmiGetArgInt(argv,"+p",&_Cmi_numpes);
00270   if (CmiNumPes()<1) {
00271     printf("Error: must specify number of processors to simulate with +pXXX\n",CmiNumPes());
00272     exit(1);
00273   }
00274 }
00275 
00276 char **CmiInitPE()
00277 {
00278   int argc; char **argv;
00279   argv = CmiCopyArgs(CmiArgv);
00280   CpvAccess(CmiLocalQueue) = CmiQueues[CmiMyPe()];
00281   CmiTimerInit();
00282   ConverseCommonInit(argv);
00283   CcdCallOnConditionKeep(CcdPROCESSOR_STILL_IDLE,CmiNotifyIdle,NULL);
00284   return argv;
00285 }
00286 
00287 void CmiCallMain()
00288 {
00289   char **argv;
00290   argv = CmiInitPE();
00291   CmiStart(CmiGetArgc(argv), argv);
00292   if (CmiUsched==0) CsdScheduler(-1);
00293   ConverseExit();
00294 }
00295 
00296 void ConverseExit()
00297 {
00298   ConverseCommonExit();
00299   CmiThreads[CmiMyPe()] = 0;
00300   CmiNext();
00301 }
00302 
00303 #if CMK_CONDS_USE_SPECIAL_CODE
00304 static int CmiSwitchToPEFn(int newpe)
00305 {
00306   int oldpe = _Cmi_mype;
00307   if (newpe == CcdIGNOREPE) return CcdIGNOREPE;
00308   _Cmi_mype = newpe;
00309   return oldpe;
00310 }
00311 #endif
00312 
00313 
00314 void ConverseInit(argc,argv,fn,usched,initret)
00315 int argc;
00316 char **argv;
00317 CmiStartFn fn;
00318 int usched, initret;
00319 {
00320   CthThread t; int stacksize, i;
00321   
00322 #if CMK_USE_HP_MAIN_FIX
00323 #if FOR_CPLUS
00324   _main(argc,argv);
00325 #endif
00326 #endif
00327   
00328   CmiSwitchToPE = CmiSwitchToPEFn;
00329 
00330   CmiArgv = CmiCopyArgs(argv);
00331   CmiStart = fn;
00332   CmiUsched = usched;
00333   CmiParseArgs(CmiArgv);
00334   CthInit(CmiArgv);
00335   CpvInitialize(void*, CmiLocalQueue);
00336   CmiThreads = (CthThread *)CmiAlloc(CmiNumPes()*sizeof(CthThread));
00337   CmiBarred  = (int       *)CmiAlloc(CmiNumPes()*sizeof(int));
00338   CmiQueues  = (void**)CmiAlloc(CmiNumPes()*sizeof(void*));
00339   
00340   smp_mutex = CmiCreateLock();
00341 
00342   /* Create threads for all PE except PE 0 */
00343   for(i=0; i<CmiNumPes(); i++) {
00344     t = (i==0) ? CthSelf() : CthCreate(CmiCallMain, 0, Cmi_stacksize);
00345     CmiThreads[i] = t;
00346     CmiBarred[i] = 0;
00347     CmiQueues[i] = CdsFifo_Create();
00348   }
00349   _Cmi_mype = 0;
00350   argv = CmiInitPE();
00351   if (initret==0) {
00352     fn(CmiGetArgc(argv), argv);
00353     if (usched==0) CsdScheduler(-1);
00354     ConverseExit();
00355   }
00356 }
00357 

Generated on Sun Jun 29 13:29:05 2008 for Charm++ by  doxygen 1.5.1