Beispiel #1
0
  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);
  }
Beispiel #2
0
  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);
  }
Beispiel #3
0
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);
}