SDAG: ensure that necessary data structure is initialized
authorPhil Miller <mille121@illinois.edu>
Wed, 10 Oct 2012 00:31:08 +0000 (19:31 -0500)
committerPhil Miller <mille121@illinois.edu>
Wed, 10 Oct 2012 00:31:08 +0000 (19:31 -0500)
The __cDep structure that SDAG depends on to track the dependencies and state
was not being initialized in some edge cases. Fix them by having every declared
SDAG entry method (either top-level or when-defined) check and initialize this
if it's missing.

In the case of a chare class constructor calling some SDAG method on itself
from the constructor, the surrounding generated method's call to
impl_obj->_sdag_init() won't have happened yet. In the case of inheritance from
a class with SDAG code, the generated code that would have called _sdag_init()
was never running. Incidentally, this may enable SDAG to function for classes
with SDAG content at multiple levels of their inheritance hierarchy.

The change to auto_ptr is necessary because the bare pointer was being
value-initialized in some cases, and could thus be non-NULL junk that would
pass the test.

src/xlat-i/sdag/CEntry.C
src/xlat-i/sdag/CParsedFile.C
src/xlat-i/sdag/CSdagConstruct.C
src/xlat-i/xi-symbol.C

index 00586a77bb2df3f782c12ed5e6d35b4c7e224697..a6658f6c939c7083136b9e441061fa58a782db7b 100644 (file)
@@ -69,6 +69,7 @@ void CEntry::generateCode(XStr& decls, XStr& defs)
 #endif
 
   defs << "    CMsgBuffer* cmsgbuf;\n";
+  defs << "    if (!__cDep.get()) _sdag_init();\n";
 
   int hasArrays = 0;
   int paramMarshalling = 0;
index b752cc165b714b095d6146ef4a288be68c140dff..6bed313ece3aaafea3e1c1c4ed408d3af2baae43 100644 (file)
@@ -115,11 +115,11 @@ void CParsedFile::generateEntries(XStr& decls, XStr& defs)
 void CParsedFile::generateInitFunction(XStr& decls, XStr& defs)
 {
   decls << "public:\n";
-  decls << "  CDep *__cDep;\n";
+  decls << "  std::auto_ptr<CDep> __cDep;\n";
 
   XStr name = "_sdag_init";
   generateSignature(decls, defs, container, false, "void", &name, false, NULL);
-  defs << "    __cDep = new CDep(" << numEntries << "," << numWhens << ");\n";
+  defs << "    __cDep.reset(new CDep(" << numEntries << "," << numWhens << "));\n";
   CEntry *en;
   for(list<CEntry*>::iterator en=entryList.begin(); en != entryList.end(); ++en) {
     (*en)->generateDeps(defs);
@@ -160,7 +160,7 @@ void CParsedFile::generatePupFunction(XStr& decls)
 {
   decls << "public:\n";
   decls << "  void __sdag_pup(PUP::er& p) {\n";
-  decls << "    if (__cDep) { __cDep->pup(p); }\n";
+  decls << "    if (__cDep.get()) { __cDep->pup(p); }\n";
   decls << "  }\n";
 }
 
index 33677893fb8ecee3636fc8c0224fb3dfb1d8cc6c..357ea38cd225cc676ab2ce2337741106210ae313 100644 (file)
@@ -1270,6 +1270,8 @@ void SdagConstruct::generateSdagEntry(XStr& decls, XStr& defs, Entry *entry)
   if (!entry->getContainer()->isGroup() || !entry->isConstructor())
     generateTraceEndCall(defs);
 
+  defs << "    if (!__cDep.get())\n"
+       << "        _sdag_init();\n";
   defs << "    ";
   generateCall(defs, *stateVarsChildren, constructs->front()->label);
 
index c18da2ffccd3e280c18bdddde688a4be072424ba..c29458981e7d7a609a01ab9be4881dc464104af9 100644 (file)
@@ -541,7 +541,8 @@ Module::generate()
   declstr <<
   "#ifndef _DECL_"<<name<<"_H_\n"
   "#define _DECL_"<<name<<"_H_\n"
-  "#include \"charm++.h\"\n";
+  "#include \"charm++.h\"\n"
+  "#include <memory>\n";
   if (fortranMode) declstr << "#include \"charm-api.h\"\n";
   if (clist) clist->genDecls(declstr);
   declstr << "extern void _register"<<name<<"(void);\n";
@@ -4444,10 +4445,6 @@ void Entry::genCall(XStr& str, const XStr &preCall, bool redn_wrapper)
     else {//Normal case: unmarshall parameters (or just pass message)
         str<<"("; param->unmarshall(str); str<<");\n";
     }
-
-    if (isConstructor() && container->hasSdag()) {
-      str << "  impl_obj->_sdag_init();\n";
-    }
   }
 }