void generateLocalWrapper(XStr& decls, XStr& defs, int isVoid, XStr& signature, Entry* entry, std::list<CStateVar*>* params, XStr* next) { // generate wrapper for local calls to the function templateGuardBegin(false, defs); defs << entry->getContainer()->tspec() << "void " << entry->getContainer()->baseName() << "::" << signature << "{\n"; defs << " " << *entry->genClosureTypeNameProxyTemp << "*" << " genClosure = new " << *entry->genClosureTypeNameProxyTemp << "()" << ";\n"; if (params) { int i = 0; for (std::list<CStateVar*>::iterator it = params->begin(); it != params->end(); ++it, ++i) { CStateVar& var = **it; if (var.name) defs << " genClosure->getP" << i << "() = " << var.name << ";\n"; } } defs << " " << *next << "(genClosure);\n"; defs << " genClosure->deref();\n"; defs << "}\n\n"; templateGuardEnd(defs); }
void CEntry::generateCode(XStr& decls, XStr& defs) { CStateVar *sv; int i = 0; int isVoid = 1; int lastWasVoid; XStr signature; signature << *entry << "("; for(list<CStateVar*>::iterator it = myParameters.begin(); it != myParameters.end(); ++it, ++i) { sv = *it; isVoid = sv->isVoid; if ((sv->isMsg != 1) && (sv->isVoid != 1)) { if (i >0) signature <<", "; if (sv->byConst) signature << "const "; signature << sv->type << " "; if (sv->arrayLength != 0) signature << "*"; else if (sv->declaredRef) { signature <<"&"; } if (sv->numPtrs != 0) { for(int k = 0; k< sv->numPtrs; k++) signature << "*"; } if (sv->name != 0) signature << sv->name; } else if (sv->isVoid != 1){ if (i < 1) signature << sv->type << "* " << sv->name << "_msg"; else printf("ERROR: A message must be the only parameter in an entry function\n"); } else signature <<"void"; } signature << ")"; XStr newSig; if (isVoid) { newSig << *entry << "()"; decls << " void " << newSig << ";\n"; } else if (needsParamMarshalling) { newSig << *entry << "(" << *decl_entry->genClosureTypeNameProxyTemp << "* genClosure)"; decls << " void " << newSig << ";\n"; // generate local wrapper decls decls << " void " << signature << ";\n"; generateLocalWrapper(decls, defs, isVoid, signature, decl_entry, &myParameters, entry); } else { // a message newSig << signature << ""; decls << " void " << newSig << ";\n"; } templateGuardBegin(false, defs); defs << decl_entry->getContainer()->tspec() << "void " << decl_entry->getContainer()->baseName() << "::" << newSig << "{\n"; defs << " if (!__dep.get()) _sdag_init();\n"; #if CMK_BIGSIM_CHARM defs << " void* _bgParentLog = NULL;\n"; defs << " CkElapse(0.01e-6);\n"; SdagConstruct::generateTlineEndCall(defs); #endif if (needsParamMarshalling || isVoid) { // add the incoming message to a buffer #if CMK_BIGSIM_CHARM defs << " SDAG::Buffer* cmsgbuf = "; #endif // note that there will always be a closure even when the method has no // parameters for consistency defs << " __dep->pushBuffer(" << entryNum << ", " << (isVoid ? "0" : "genClosure") << ", " << (refNumNeeded ? "genClosure->getP0()" : "0") <<");\n"; } else { defs << " CMK_REFNUM_TYPE refnum = "; if (refNumNeeded) defs << "CkGetRefNum(" << sv->name << "_msg);\n"; else defs << "0;\n"; // possible memory pressure problem: this message will be kept as long as // it is a state parameter! there are ways to remediate this, but it // involves either live variable analysis (which is not feasible) or // keeping a meta-structure for every message passed in //increase reference count by one for the state parameter defs << " CmiReference(UsrToEnv(" << sv->name << "_msg));\n"; #if CMK_BIGSIM_CHARM defs << " SDAG::Buffer* cmsgbuf = "; #endif defs << " __dep->pushBuffer(" << entryNum << ", new SDAG::MsgClosure(" << sv->name << "_msg" << "), refnum);\n"; } // @todo write the code to fetch the message with the ref num // search for a continuation to restart execution defs << " SDAG::Continuation* c = __dep->tryFindContinuation(" << entryNum << ");\n"; // found a continuation defs << " if (c) {\n"; SdagConstruct::generateTraceEndCall(defs, 2); #if CMK_BIGSIM_CHARM SdagConstruct::generateEndExec(defs); #endif if (whenList.size() == 1) { (*whenList.begin())->generateWhenCode(defs, 2); } else { // switch on the possible entry points for the continuation // each continuation entry knows how to generate its own code defs << " switch(c->whenID) {\n"; for(list<WhenConstruct*>::iterator cn = whenList.begin(); cn != whenList.end(); ++cn) { defs << " case " << (*cn)->nodeNum << ":\n"; (*cn)->generateWhenCode(defs, 3); defs << " break;\n"; } defs << " }\n"; } SdagConstruct::generateDummyBeginExecute(defs, 2); // delete the continuation now that we are finished with it defs << " delete c;\n"; defs << " }\n"; defs << "}\n\n"; templateGuardEnd(defs); }
void Message::genDefs(XStr& str) { int i, count, num = numVars(); int numArray = numArrays(); MsgVarList *ml; MsgVar *mv; XStr ptype, mtype, tspec; ptype<<proxyPrefix()<<type; if(templat) templat->genVars(ptype); mtype << type; if(templat) templat->genVars(mtype); if(templat) { templat->genSpec(tspec); tspec << " "; } str << "/* DEFS: "; print(str); str << " */\n"; templateGuardBegin(templat, str); if(!(external||type->isTemplated())) { // new (size_t) str << tspec << "void *" << ptype << "::operator new(size_t s){\n"; str << " return " << mtype << "::alloc(__idx, s, 0, 0);\n}\n"; // new (size_t, int*) str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz){\n"; str << " return " << mtype << "::alloc(__idx, s, sz, 0);\n}\n"; // new (size_t, int*, priobits) str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,"; str << "const int pb){\n"; str << " return " << mtype << "::alloc(__idx, s, sz, pb);\n}\n"; // new (size_t, int, int, ..., int) if(numArray>0) { str << tspec << "void *" << ptype << "::operator new(size_t s"; for(i=0;i<numArray;i++) str << ", int sz" << i; str << ") {\n"; str << " int sizes[" << numArray << "];\n"; for(i=0;i<numArray;i++) str << " sizes[" << i << "] = sz" << i << ";\n"; str << " return " << mtype << "::alloc(__idx, s, sizes, 0);\n"; str << "}\n"; } // new (size_t, int, int, ..., int, priobits) // degenerates to new(size_t, priobits) if no varsize std::vector<MsgVar *> arrayVars; str << tspec << "void *"<< ptype << "::operator new(size_t s, "; for(i=0;i<numArray;i++) str << "int sz" << i << ", "; str << "const int p) {\n"; if (numArray>0) { str << " int sizes[" << numArray << "];\n"; for(i=0, count=0, ml=mvlist ;i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isArray()) { str << " sizes[" << count << "] = sz" << count << ";\n"; count ++; arrayVars.push_back(mv); } } } str << " return " << mtype << "::alloc(__idx, s, " << (numArray>0?"sizes":"0") << ", p);\n"; str << "}\n"; // alloc(int, size_t, int*, priobits) str << tspec << "void* " << ptype; str << "::alloc(int msgnum, size_t sz, int *sizes, int pb) {\n"; str << " CkpvAccess(_offsets)[0] = ALIGN_DEFAULT(sz);\n"; for(count = 0; count < numArray; count++) { mv = arrayVars[count]; str << " if(sizes==0)\n"; str << " CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[0];\n"; str << " else\n"; str << " CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[" << count << "] + "; str << "ALIGN_DEFAULT(sizeof(" << mv->type << ")*sizes[" << count << "]);\n"; } str << " return CkAllocMsg(msgnum, CkpvAccess(_offsets)[" << numArray << "], pb);\n"; str << "}\n"; str << tspec << ptype << "::" << proxyPrefix() << type << "() {\n"; str << mtype << " *newmsg = (" << mtype << " *)this;\n"; for(i=0, count=0, ml=mvlist; i<num; i++,ml=ml->next) { mv = ml->msg_var; if (mv->isArray()) { str << " newmsg->" << mv->name << " = (" << mv->type << " *) "; str << "((char *)newmsg + CkpvAccess(_offsets)[" << count << "]);\n"; count ++; } } str << "}\n"; int numCond = numConditional(); str << tspec << "void " << ptype << "::dealloc(void *p) {\n"; if (numCond > 0) { str << " " << mtype << " *msg = (" << mtype << "*) p;\n"; for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isConditional()) { if (mv->type->isPointer()) XLAT_ERROR_NOCOL("conditional variable cannot be a pointer", line); str << " CkConditional *cond_" << mv->name << " = static_cast<CkConditional*>(msg->" << mv->name << ");\n"; str << " if (cond_" << mv->name << "!=NULL) cond_" << mv->name << "->deallocate();\n"; } } } str << " CkFreeMsg(p);\n"; str << "}\n"; // pack str << tspec << "void* " << ptype << "::pack(" << mtype << " *msg) {\n"; for(i=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isArray()) { str << " msg->" << mv->name << " = (" <<mv->type << " *) "; str << "((char *)msg->" << mv->name << " - (char *)msg);\n"; } } if (numCond > 0) { str << " int impl_off[" << numCond+1 << "];\n"; str << " impl_off[0] = UsrToEnv(msg)->getUsersize();\n"; for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isConditional()) { str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of "; mv->type->print(str); str << " " << mv->name << " */\n"; str << " PUP::sizer implP;\n"; str << " implP|*msg->" << mv->name << ";\n"; str << " impl_off[" << count+1 << "] = impl_off[" << count << "] + implP.size();\n"; str << " } else {\n"; str << " impl_off[" << count+1 << "] = impl_off[" << count << "];\n"; str << " }\n"; count ++; } } str << " " << mtype << " *newmsg = (" << mtype << "*) CkAllocMsg(__idx, impl_off[" << numCond << "], UsrToEnv(msg)->getPriobits());\n"; str << " envelope *newenv = UsrToEnv(newmsg);\n"; str << " UInt newSize = newenv->getTotalsize();\n"; str << " CmiMemcpy(newenv, UsrToEnv(msg), impl_off[0]+sizeof(envelope));\n"; str << " newenv->setTotalsize(newSize);\n"; str << " if (UsrToEnv(msg)->getPriobits() > 0) CmiMemcpy(newenv->getPrioPtr(), UsrToEnv(msg)->getPrioPtr(), newenv->getPrioBytes());\n"; for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isConditional()) { str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of "; mv->type->print(str); str << " " << mv->name << " */\n"; str << " newmsg->" << mv->name << " = ("; mv->type->print(str); str << "*)(((char*)newmsg)+impl_off[" << count << "]);\n"; str << " PUP::toMem implP((void *)newmsg->" << mv->name << ");\n"; str << " implP|*msg->" << mv->name << ";\n"; str << " newmsg->" << mv->name << " = (" << mv->type << "*) ((char *)newmsg->" << mv->name << " - (char *)newmsg);\n"; str << " }\n"; count++; } } str << " CkFreeMsg(msg);\n"; str << " msg = newmsg;\n"; } str << " return (void *) msg;\n}\n"; // unpack str << tspec << mtype << "* " << ptype << "::unpack(void* buf) {\n"; str << " " << mtype << " *msg = (" << mtype << " *) buf;\n"; for(i=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isArray()) { str << " msg->" << mv->name << " = (" <<mv->type << " *) "; str << "((size_t)msg->" << mv->name << " + (char *)msg);\n"; } } if (numCond > 0) { for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) { mv = ml->msg_var; if (mv->isConditional()) { str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of "; mv->type->print(str); str << " " << mv->name << " */\n"; str << " PUP::fromMem implP((char*)msg + (size_t)msg->" << mv->name << ");\n"; str << " msg->" << mv->name << " = new " << mv->type << ";\n"; str << " implP|*msg->" << mv->name << ";\n"; str << " }\n"; count ++; } } } str << " return msg;\n}\n"; } if(!templat) { if(!external && !type->isTemplated()) { str << "int "<< ptype <<"::__idx=0;\n"; } } else { str << tspec << "int "<< ptype <<"::__idx=0;\n"; } templateGuardEnd(str); }