00001 #include "CEntry.h"
00002 #include "xi-symbol.h"
00003 #include "CStateVar.h"
00004
00005 namespace xi {
00006
00007 void CEntry::generateDeps(XStr& op)
00008 {
00009 SdagConstruct *cn;
00010 for(cn=whenList.begin(); !whenList.end(); cn=whenList.next()) {
00011 op << " __cDep->addDepends("<<cn->nodeNum<<","<<entryNum<<");\n";
00012 }
00013 }
00014
00015 static void generateWhenCode(XStr& op, SdagConstruct *cn)
00016 {
00017 XStr whenParams = "";
00018 CStateVar *sv = cn->stateVars->begin();
00019 int i = 0;
00020 int iArgs = 0;
00021 bool lastWasVoid = false;
00022 bool paramMarshalling = false;
00023
00024 #if CMK_BIGSIM_CHARM
00025
00026 op <<" cmsgbuf->bgLog2 = (void*)tr->args[1];\n";
00027 #endif
00028
00029 for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
00030 if ((sv->isMsg == 0) && (paramMarshalling == 0) && (sv->isVoid ==0)){
00031 paramMarshalling =1;
00032 op << " CkMarshallMsg *impl_msg" <<cn->nodeNum <<" = (CkMarshallMsg *) tr->args["<<iArgs++<<"];\n";
00033 op << " char *impl_buf" <<cn->nodeNum <<"=((CkMarshallMsg *)impl_msg" <<cn->nodeNum <<")->msgBuf;\n";
00034 op << " PUP::fromMem implP" <<cn->nodeNum <<"(impl_buf" <<cn->nodeNum <<");\n";
00035 }
00036 if (sv->isMsg == 1) {
00037 if((i!=0) && (lastWasVoid == 0))
00038 whenParams.append(", ");
00039 #if CMK_BIGSIM_CHARM
00040 if(i==1) {
00041 whenParams.append(" NULL ");
00042 lastWasVoid=0;
00043
00044 iArgs++;
00045 continue;
00046 }
00047 #endif
00048 whenParams.append("(");
00049 whenParams.append(sv->type->charstar());
00050 whenParams.append(") tr->args[");
00051 whenParams<<iArgs;
00052 whenParams.append("]");
00053 iArgs++;
00054 }
00055 else if (sv->isVoid == 1)
00056
00057 op <<" tr->args[" <<iArgs++ <<"] = 0;\n";
00058 else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
00059 if((i > 0) && (lastWasVoid == 0))
00060 whenParams.append(", ");
00061 whenParams.append(*(sv->name));
00062 if (sv->arrayLength != 0)
00063 op<<" int impl_off"<<cn->nodeNum <<"_"<<sv->name->charstar()<<"; implP"
00064 <<cn->nodeNum <<"|impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<";\n";
00065 else
00066 op<<" "<<sv->type->charstar()<<" "<<sv->name->charstar()<<"; implP"
00067 <<cn->nodeNum <<"|"<<sv->name->charstar()<<";\n";
00068 }
00069 lastWasVoid = sv->isVoid;
00070 }
00071 if (paramMarshalling == 1)
00072 op<<" impl_buf"<<cn->nodeNum <<"+=CK_ALIGN(implP" <<cn->nodeNum <<".size(),16);\n";
00073 i = 0;
00074 sv = (CStateVar *)cn->stateVars->begin();
00075 for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
00076 if (sv->arrayLength != 0)
00077 op<<" "<<sv->type->charstar()<<" *"<<sv->name->charstar()<<"=("<<sv->type->charstar()<<" *)(impl_buf" <<cn->nodeNum
00078 <<"+impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<");\n";
00079 }
00080 if (paramMarshalling == 1)
00081 op << " delete (CkMarshallMsg *)impl_msg" <<cn->nodeNum <<";\n";
00082 op << " " << cn->label->charstar() << "(" << whenParams.charstar();
00083 op << ");\n";
00084 op << " delete tr;\n";
00085
00086 #if CMK_BIGSIM_CHARM
00087 cn->generateTlineEndCall(op);
00088 cn->generateBeginExec(op, "sdagholder");
00089 #endif
00090 op << " ";
00091 cn->generateDummyBeginExecute(op);
00092
00093 op << " return;\n";
00094 }
00095
00096 void CEntry::generateCode(XStr& decls, XStr& defs)
00097 {
00098 CStateVar *sv;
00099 int i;
00100 int isVoid = 1;
00101 int lastWasVoid;
00102 sv = (CStateVar *)myParameters->begin();
00103 i = 0;
00104 decls << " void ";
00105
00106 templateGuardBegin(false, defs);
00107 defs << "void " << decl_entry->getContainer()->baseName() << "::";
00108
00109 XStr signature;
00110 signature << *entry << "(";
00111 for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
00112 isVoid = sv->isVoid;
00113 if ((sv->isMsg != 1) && (sv->isVoid != 1)) {
00114 if (i >0)
00115 signature <<", ";
00116 signature << sv->type->charstar() << " ";
00117 if (sv->arrayLength != 0)
00118 signature << "*";
00119 else if (sv->byRef != 0) {
00120 signature <<"&";
00121 }
00122 if (sv->numPtrs != 0) {
00123 for(int k = 0; k< sv->numPtrs; k++)
00124 signature << "*";
00125 }
00126 if (sv->name != 0)
00127 signature << sv->name->charstar();
00128 }
00129 else if (sv->isVoid != 1){
00130 if (i < 1)
00131 signature << sv->type->charstar() <<" "<<sv->name->charstar() <<"_msg";
00132 else
00133 printf("ERROR: A message must be the only parameter in an entry function\n");
00134 }
00135 else
00136 signature <<"void";
00137 }
00138 signature << ")";
00139
00140 decls << signature << ";\n";
00141
00142 defs << signature << "{\n";
00143 defs << " CWhenTrigger *tr;\n";
00144 defs << " void* _bgParentLog = NULL;\n";
00145 #if CMK_BIGSIM_CHARM
00146 defs << " CkElapse(0.01e-6);\n";
00147 SdagConstruct::generateTlineEndCall(defs);
00148 #endif
00149
00150 defs << " CMsgBuffer* cmsgbuf;\n";
00151
00152 int hasArrays = 0;
00153 int paramMarshalling = 0;
00154 int count = 0;
00155 sv = (CStateVar *)myParameters->begin();
00156 i = 0;
00157 if (isVoid == 1) {
00158 defs << " __cDep->bufferMessage("<<entryNum<<", (void *) CkAllocSysMsg(), (void*) _bgParentLog, 0);\n";
00159 defs << " tr = __cDep->getTrigger("<<entryNum<<", 0);\n";
00160 }
00161 else {
00162 for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
00163 if ((i==0) && (sv->isMsg !=1)) {
00164 defs <<" int impl_off=0; int impl_arrstart=0;\n";
00165 paramMarshalling = 1;
00166 }
00167 if(sv->arrayLength != 0) {
00168 hasArrays++ ;
00169 if (sv->numPtrs > 0)
00170 printf("ERROR: can't pass pointers across processors \n -- Indicate the array length with []'s, or pass a reference\n");
00171 defs <<" int impl_off_"<<sv->name->charstar()<<", impl_cnt_"<<sv->name->charstar()<<";\n";
00172 defs <<" impl_off_"<<sv->name->charstar()<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type->charstar()<<"));\n";
00173 defs <<" impl_off+=(impl_cnt_"<<sv->name->charstar()<<"=sizeof("<<sv->type->charstar()<<")*("<<sv->arrayLength->charstar()<<"));\n";
00174 }
00175 if (paramMarshalling ==0) {
00176 defs << " CmiReference(UsrToEnv(" << sv->name->charstar() << "_msg));\n";
00177 if(refNumNeeded) {
00178 defs << " int refnum = CkGetRefNum(" <<sv->name->charstar() <<"_msg);\n";
00179 defs << " cmsgbuf = __cDep->bufferMessage("<<entryNum<<",(void *) "<<sv->name->charstar() <<"_msg , (void *) _bgParentLog, refnum);\n";
00180 defs << " tr = __cDep->getTrigger("<<entryNum<<", refnum);\n";
00181 } else {
00182 defs << " cmsgbuf = __cDep->bufferMessage("<<entryNum<<", (void *) "<<sv->name->charstar() <<"_msg, (void *) _bgParentLog, 0);\n";
00183 defs << " tr = __cDep->getTrigger("<<entryNum<<", 0);\n";
00184 }
00185 }
00186 count++;
00187 }
00188 }
00189 if (paramMarshalling == 1) {
00190 defs <<" {\n";
00191 defs <<" PUP::sizer implP1;\n";
00192 sv = (CStateVar *)myParameters->begin();
00193 i = 0;
00194
00195 for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
00196 if(sv->arrayLength != 0)
00197 defs <<" implP1|impl_off_"<<sv->name->charstar()<<";\n";
00198 else if(sv->byRef != 0)
00199 defs <<" implP1|(" <<sv->type->charstar() <<" &)" <<sv->name->charstar() <<";\n";
00200 else
00201 defs <<" implP1|"<<sv->name->charstar()<<";\n";
00202 }
00203
00204 if (hasArrays > 0)
00205 {
00206 defs <<" impl_arrstart=CK_ALIGN(implP1.size(),16);\n";
00207 defs <<" impl_off+=impl_arrstart;\n";
00208 }
00209 else
00210 defs <<" impl_off+=implP1.size();\n";
00211
00212 defs <<" }\n";
00213
00214
00215 defs <<" CkMarshallMsg *impl_msg1=CkAllocateMarshallMsg(impl_off,NULL);\n";
00216
00217 defs <<" {\n";
00218 defs <<" PUP::toMem implP1((void *)impl_msg1->msgBuf);\n";
00219 sv = (CStateVar *)myParameters->begin();
00220 i = 0;
00221
00222 for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
00223 if(sv->arrayLength != 0)
00224 defs <<" implP1|impl_off_"<<sv->name->charstar()<<";\n";
00225 else if(sv->byRef != 0)
00226 defs <<" implP1|(" <<sv->type->charstar() <<" &)" <<sv->name->charstar() <<";\n";
00227 else
00228 defs <<" implP1|"<<sv->name->charstar()<<";\n";
00229 }
00230 defs <<" }\n";
00231 if (hasArrays > 0)
00232 {
00233 defs <<" char *impl_buf1=impl_msg1->msgBuf+impl_arrstart;\n";
00234 sv = (CStateVar *)myParameters->begin();
00235 i = 0;
00236 for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
00237 if(sv->arrayLength != 0) {
00238 defs <<" memcpy(impl_buf1+impl_off_"<<sv->name->charstar()<<","<<sv->name->charstar()<<",impl_cnt_"<<sv->name->charstar()<<");\n";
00239 }
00240 }
00241 }
00242
00243
00244
00245
00246
00247 const char* refNumArg = refNumNeeded ? myParameters->begin()->name->charstar() : "0";
00248
00249 defs << " cmsgbuf = __cDep->bufferMessage(" << entryNum
00250 << ", (void *) impl_msg1, (void*) _bgParentLog, "
00251 << refNumArg << ");\n";
00252 defs << " tr = __cDep->getTrigger(" << entryNum << ", "
00253 << refNumArg << ");\n";
00254 }
00255
00256 defs << " if (tr == 0)\n";
00257 defs << " return;\n";
00258
00259 SdagConstruct::generateTraceEndCall(defs);
00260 #if CMK_BIGSIM_CHARM
00261 SdagConstruct::generateEndExec(defs);
00262 #endif
00263
00264 if(whenList.length() == 1) {
00265 defs << " {\n";
00266 generateWhenCode(defs, whenList.begin());
00267 defs << " }\n";
00268 }
00269 else {
00270 defs << " switch(tr->whenID) {\n";
00271 for(SdagConstruct *cn=whenList.begin(); !whenList.end(); cn=whenList.next())
00272 {
00273 defs << " case " << cn->nodeNum << ":\n";
00274 defs << " {\n";
00275
00276 generateWhenCode(defs, cn);
00277 defs << " }\n";
00278 }
00279 defs << " }\n";
00280 }
00281
00282
00283 defs << "}\n\n";
00284 templateGuardEnd(defs);
00285 }
00286
00287 }