mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: cleanup codeStream - use dynamicCode, dynamicCodeContext encapsulation
Problems remain with codedFixedValueFvPatchScalarField: - readIfModified() notices change on system/codeDict, but the codeProperties::setUnmodified() means that only a single entry will get processed - it appears that while dlclose() may (or may not) be actually closing the library, there are probably still references about. This means that a subsequent reloading still points to the original functions and the lookup is not updated correctly.
This commit is contained in:
@ -13,7 +13,7 @@
|
|||||||
provide the actual dictionary entry. The snippet gets provided as three
|
provide the actual dictionary entry. The snippet gets provided as three
|
||||||
sections of C++ code which just gets inserted into a template:
|
sections of C++ code which just gets inserted into a template:
|
||||||
- =code= section: the actual body of the code. It gets called with arguments
|
- =code= section: the actual body of the code. It gets called with arguments
|
||||||
=const dictionary& dict, OStream& os= and the C++ code can do a
|
=OStream& os, const dictionary& dict= and the C++ code can do a
|
||||||
=dict.lookup= to find current dictionary values.
|
=dict.lookup= to find current dictionary values.
|
||||||
- optional =codeInclude= section: any #include statements to include OpenFOAM
|
- optional =codeInclude= section: any #include statements to include OpenFOAM
|
||||||
files.
|
files.
|
||||||
|
|||||||
@ -44,8 +44,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
void ${typeName}
|
void ${typeName}
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
Ostream& os,
|
||||||
Ostream& os
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//{{{ begin code
|
//{{{ begin code
|
||||||
|
|||||||
@ -83,67 +83,61 @@ bool Foam::functionEntries::codeStream::execute
|
|||||||
// get code, codeInclude, codeOptions
|
// get code, codeInclude, codeOptions
|
||||||
dynamicCodeContext context(codeDict);
|
dynamicCodeContext context(codeDict);
|
||||||
|
|
||||||
// codeName: prefix_ + sha1
|
// codeName: codeStream + _<sha1>
|
||||||
// codeDir : _<sha1>
|
// codeDir : _<sha1>
|
||||||
dynamicCode dynCode
|
dynamicCode dynCode
|
||||||
(
|
(
|
||||||
"codeStream_" + context.sha1().str(),
|
"codeStream" + context.sha1().str(true),
|
||||||
"_" + context.sha1().str()
|
context.sha1().str(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Load library if not already loaded
|
// Load library if not already loaded
|
||||||
// Version information is encoded in the libPath (encoded with the SHA1)
|
// Version information is encoded in the libPath (encoded with the SHA1)
|
||||||
const fileName libPath = dynCode.libPath();
|
const fileName libPath = dynCode.libPath();
|
||||||
|
|
||||||
|
// see if library is loaded
|
||||||
void* lib = dlLibraryTable::findLibrary(libPath);
|
void* lib = dlLibraryTable::findLibrary(libPath);
|
||||||
|
|
||||||
|
bool reuseLib = false;
|
||||||
|
|
||||||
|
// nothing loaded
|
||||||
|
// avoid compilation if possible by loading an existing library
|
||||||
if (!lib && dlLibraryTable::open(libPath, false))
|
if (!lib && dlLibraryTable::open(libPath, false))
|
||||||
{
|
{
|
||||||
lib = dlLibraryTable::findLibrary(libPath);
|
lib = dlLibraryTable::findLibrary(libPath);
|
||||||
|
reuseLib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// did not load - need to compile it
|
|
||||||
|
// create library if required
|
||||||
if (!lib)
|
if (!lib)
|
||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
if (!dynCode.upToDate(context))
|
if (!dynCode.upToDate(context))
|
||||||
{
|
{
|
||||||
Info<< "Creating new library in "
|
|
||||||
<< dynCode.libPath() << endl;
|
|
||||||
|
|
||||||
// filter C template
|
|
||||||
dynCode.addFilterFile(codeTemplateC);
|
|
||||||
|
|
||||||
// filter with this context
|
// filter with this context
|
||||||
dynCode.setFilterContext(context);
|
dynCode.reset(context);
|
||||||
|
|
||||||
// Write Make/files
|
// compile filtered C template
|
||||||
dynCode.addCreateFile
|
dynCode.addCompileFile(codeTemplateC);
|
||||||
(
|
|
||||||
"Make/files",
|
|
||||||
codeTemplateC + "\n\n"
|
|
||||||
+ dynCode.libTarget()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Write Make/options
|
// define Make/options
|
||||||
dynCode.addCreateFile
|
dynCode.setMakeOptions
|
||||||
(
|
(
|
||||||
"Make/options",
|
|
||||||
"EXE_INC = -g \\\n"
|
"EXE_INC = -g \\\n"
|
||||||
+ context.options()
|
+ context.options()
|
||||||
+ "\n\nLIB_LIBS ="
|
+ "\n\nLIB_LIBS ="
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!dynCode.copyFilesContents())
|
if (!dynCode.copyOrCreateFiles(true))
|
||||||
{
|
{
|
||||||
FatalIOErrorIn
|
FatalIOErrorIn
|
||||||
(
|
(
|
||||||
"functionEntries::codeStream::execute(..)",
|
"functionEntries::codeStream::execute(..)",
|
||||||
parentDict
|
parentDict
|
||||||
) << "Failed writing " << nl
|
) << "Failed writing files for" << nl
|
||||||
// << copyFiles << endl
|
<< dynCode.libPath() << nl
|
||||||
// << filesContents
|
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,8 +154,8 @@ bool Foam::functionEntries::codeStream::execute
|
|||||||
}
|
}
|
||||||
|
|
||||||
// all processes must wait for compile
|
// all processes must wait for compile
|
||||||
bool dummy = true;
|
bool waiting = true;
|
||||||
reduce(dummy, orOp<bool>());
|
reduce(waiting, orOp<bool>());
|
||||||
|
|
||||||
if (!dlLibraryTable::open(libPath, false))
|
if (!dlLibraryTable::open(libPath, false))
|
||||||
{
|
{
|
||||||
@ -175,15 +169,15 @@ bool Foam::functionEntries::codeStream::execute
|
|||||||
|
|
||||||
lib = dlLibraryTable::findLibrary(libPath);
|
lib = dlLibraryTable::findLibrary(libPath);
|
||||||
}
|
}
|
||||||
else
|
else if (reuseLib)
|
||||||
{
|
{
|
||||||
Info<< "Reusing library in " << libPath << endl;
|
Info<< "Reusing library in " << libPath << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find the library handle.
|
// Find the function handle in the library
|
||||||
void (*function)(const dictionary&, Ostream&);
|
void (*function)(Ostream&, const dictionary&);
|
||||||
function = reinterpret_cast<void(*)(const dictionary&, Ostream&)>
|
function = reinterpret_cast<void(*)(Ostream&, const dictionary&)>
|
||||||
(
|
(
|
||||||
dlSym(lib, dynCode.codeName())
|
dlSym(lib, dynCode.codeName())
|
||||||
);
|
);
|
||||||
@ -199,8 +193,11 @@ bool Foam::functionEntries::codeStream::execute
|
|||||||
<< " in library " << lib << exit(FatalIOError);
|
<< " in library " << lib << exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use function to write stream
|
||||||
OStringStream os(is.format());
|
OStringStream os(is.format());
|
||||||
(*function)(parentDict, os);
|
(*function)(os, parentDict);
|
||||||
|
|
||||||
|
// get the entry from this stream
|
||||||
IStringStream resultStream(os.str());
|
IStringStream resultStream(os.str());
|
||||||
entry.read(parentDict, resultStream);
|
entry.read(parentDict, resultStream);
|
||||||
|
|
||||||
|
|||||||
@ -135,8 +135,8 @@ public:
|
|||||||
static bool execute
|
static bool execute
|
||||||
(
|
(
|
||||||
const dictionary& parentDict,
|
const dictionary& parentDict,
|
||||||
primitiveEntry& entry,
|
primitiveEntry&,
|
||||||
Istream& is
|
Istream&
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -33,6 +33,7 @@ License
|
|||||||
#include "dictionary.H"
|
#include "dictionary.H"
|
||||||
#include "dlLibraryTable.H"
|
#include "dlLibraryTable.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
int Foam::dynamicCode::allowSystemOperations
|
int Foam::dynamicCode::allowSystemOperations
|
||||||
@ -47,6 +48,9 @@ const Foam::word Foam::dynamicCode::codeTemplateEnvName
|
|||||||
const Foam::fileName Foam::dynamicCode::codeTemplateDirName
|
const Foam::fileName Foam::dynamicCode::codeTemplateDirName
|
||||||
= "codeTemplates/dynamicCode";
|
= "codeTemplates/dynamicCode";
|
||||||
|
|
||||||
|
const char* Foam::dynamicCode::libTargetRoot =
|
||||||
|
"LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib";
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -78,7 +82,7 @@ void Foam::dynamicCode::copyAndFilter
|
|||||||
ISstream& is,
|
ISstream& is,
|
||||||
OSstream& os,
|
OSstream& os,
|
||||||
const HashTable<string>& mapping
|
const HashTable<string>& mapping
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
if (!is.good())
|
if (!is.good())
|
||||||
{
|
{
|
||||||
@ -110,27 +114,26 @@ void Foam::dynamicCode::copyAndFilter
|
|||||||
// expanding according to env variables might cause too many
|
// expanding according to env variables might cause too many
|
||||||
// surprises
|
// surprises
|
||||||
stringOps::inplaceExpand(line, mapping);
|
stringOps::inplaceExpand(line, mapping);
|
||||||
|
os.writeQuoted(line, false) << nl;
|
||||||
os << line.c_str() << nl;
|
|
||||||
}
|
}
|
||||||
while (is.good());
|
while (is.good());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::List<Foam::fileName>
|
bool Foam::dynamicCode::resolveTemplates
|
||||||
Foam::dynamicCode::resolveTemplates(const UList<fileName>& names)
|
(
|
||||||
|
const UList<fileName>& templateNames,
|
||||||
|
DynamicList<fileName>& resolvedFiles,
|
||||||
|
DynamicList<fileName>& badFiles
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// try to get template from FOAM_CODESTREAM_TEMPLATES
|
// try to get template from FOAM_CODESTREAM_TEMPLATES
|
||||||
const fileName templateDir(Foam::getEnv(codeTemplateEnvName));
|
const fileName templateDir(Foam::getEnv(codeTemplateEnvName));
|
||||||
|
|
||||||
DynamicList<fileName> badFiles(names.size());
|
bool allOkay = true;
|
||||||
List<fileName> resolved(names.size());
|
forAll(templateNames, fileI)
|
||||||
|
|
||||||
label nResolved = 0;
|
|
||||||
|
|
||||||
forAll(names, fileI)
|
|
||||||
{
|
{
|
||||||
const fileName& templateName = names[fileI];
|
const fileName& templateName = templateNames[fileI];
|
||||||
|
|
||||||
fileName file;
|
fileName file;
|
||||||
if (!templateDir.empty() && isDir(templateDir))
|
if (!templateDir.empty() && isDir(templateDir))
|
||||||
@ -151,73 +154,186 @@ Foam::dynamicCode::resolveTemplates(const UList<fileName>& names)
|
|||||||
if (file.empty())
|
if (file.empty())
|
||||||
{
|
{
|
||||||
badFiles.append(templateName);
|
badFiles.append(templateName);
|
||||||
|
allOkay = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resolved[nResolved++] = file;
|
resolvedFiles.append(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved.setSize(nResolved);
|
return allOkay;
|
||||||
|
}
|
||||||
|
|
||||||
if (!badFiles.empty())
|
|
||||||
|
bool Foam::dynamicCode::writeCommentSHA1(Ostream& os) const
|
||||||
|
{
|
||||||
|
const bool hasSHA1 = filterVars_.found("SHA1sum");
|
||||||
|
|
||||||
|
if (hasSHA1)
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
os << "/* dynamicCode:\n * SHA1 = ";
|
||||||
(
|
os.writeQuoted(filterVars_["SHA1sum"], false) << "\n */\n";
|
||||||
"dynamicCode::resolveTemplates(..)"
|
|
||||||
) << "Could not find the code template(s): "
|
|
||||||
<< badFiles << nl
|
|
||||||
<< "Under the $" << codeTemplateDirName
|
|
||||||
<< " directory or via via the ~OpenFOAM/"
|
|
||||||
<< codeTemplateDirName << " expansion"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolved;
|
return hasSHA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::dynamicCode::createMakeFiles() const
|
||||||
|
{
|
||||||
|
// Create Make/files
|
||||||
|
if (compileFiles_.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileName dstFile(this->codePath()/"Make/files");
|
||||||
|
|
||||||
|
// Create dir
|
||||||
|
mkDir(dstFile.path());
|
||||||
|
|
||||||
|
OFstream os(dstFile);
|
||||||
|
//Info<< "Writing to " << dstFile << endl;
|
||||||
|
if (!os.good())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"dynamicCode::createMakeFiles()"
|
||||||
|
" const"
|
||||||
|
) << "Failed writing " << dstFile
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCommentSHA1(os);
|
||||||
|
|
||||||
|
// Write compile files
|
||||||
|
forAll(compileFiles_, fileI)
|
||||||
|
{
|
||||||
|
os.writeQuoted(compileFiles_[fileI], false) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << nl
|
||||||
|
<< libTargetRoot << codeName_.c_str() << nl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::dynamicCode::createMakeOptions() const
|
||||||
|
{
|
||||||
|
// Create Make/options
|
||||||
|
if (compileFiles_.empty() || makeOptions_.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileName dstFile(this->codePath()/"Make/options");
|
||||||
|
|
||||||
|
// Create dir
|
||||||
|
mkDir(dstFile.path());
|
||||||
|
|
||||||
|
OFstream os(dstFile);
|
||||||
|
//Info<< "Writing to " << dstFile << endl;
|
||||||
|
if (!os.good())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"dynamicCode::createMakeOptions()"
|
||||||
|
" const"
|
||||||
|
) << "Failed writing " << dstFile
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCommentSHA1(os);
|
||||||
|
os.writeQuoted(makeOptions_, false) << nl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::dynamicCode::writeDigest(const SHA1Digest& sha1) const
|
||||||
|
{
|
||||||
|
const fileName file = digestFile();
|
||||||
|
mkDir(file.path());
|
||||||
|
|
||||||
|
OFstream os(file);
|
||||||
|
sha1.write(os, true) << nl;
|
||||||
|
|
||||||
|
return os.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::dynamicCode::writeDigest(const std::string& sha1) const
|
||||||
|
{
|
||||||
|
const fileName file = digestFile();
|
||||||
|
mkDir(file.path());
|
||||||
|
|
||||||
|
OFstream os(file);
|
||||||
|
os << '_';
|
||||||
|
os.writeQuoted(sha1, false) << nl;
|
||||||
|
|
||||||
|
return os.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::dynamicCode::dynamicCode(const word& codeName)
|
|
||||||
:
|
|
||||||
codeName_(codeName),
|
|
||||||
codeDirName_(codeName)
|
|
||||||
{
|
|
||||||
filterVars_.set("typeName", codeName_);
|
|
||||||
filterVars_.set("SHA1sum", SHA1Digest().str());
|
|
||||||
}
|
|
||||||
|
|
||||||
Foam::dynamicCode::dynamicCode(const word& codeName, const word& codeDirName)
|
Foam::dynamicCode::dynamicCode(const word& codeName, const word& codeDirName)
|
||||||
:
|
:
|
||||||
|
codeRoot_(stringOps::expand("$FOAM_CASE/dynamicCode")),
|
||||||
|
libSubDir_(stringOps::expand("platforms/$WM_OPTIONS/lib")),
|
||||||
codeName_(codeName),
|
codeName_(codeName),
|
||||||
codeDirName_(codeDirName)
|
codeDirName_(codeDirName)
|
||||||
{
|
{
|
||||||
filterVars_.set("typeName", codeName_);
|
if (codeDirName_.empty())
|
||||||
filterVars_.set("SHA1sum", SHA1Digest().str());
|
{
|
||||||
|
codeDirName_ = codeName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Foam::dynamicCode::dynamicCode(const dynamicCode& dc)
|
|
||||||
// :
|
|
||||||
// codeName_(dc.codeName_),
|
|
||||||
// copyFiles_(dc.copyFiles_),
|
|
||||||
// filesContents_(dc.filesContents_)
|
|
||||||
// {}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::dynamicCode::clear()
|
void Foam::dynamicCode::clear()
|
||||||
{
|
{
|
||||||
filterVars_.clear();
|
compileFiles_.clear();
|
||||||
filterFiles_.clear();
|
copyFiles_.clear();
|
||||||
createFiles_.clear();
|
createFiles_.clear();
|
||||||
|
filterVars_.clear();
|
||||||
filterVars_.set("typeName", codeName_);
|
filterVars_.set("typeName", codeName_);
|
||||||
filterVars_.set("SHA1sum", SHA1Digest().str());
|
filterVars_.set("SHA1sum", SHA1Digest().str());
|
||||||
|
|
||||||
|
// provide default Make/options
|
||||||
|
makeOptions_ =
|
||||||
|
"EXE_INC = -g\n"
|
||||||
|
"\n\nLIB_LIBS = ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::dynamicCode::reset
|
||||||
|
(
|
||||||
|
const dynamicCodeContext& context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
setFilterContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::dynamicCode::addCompileFile(const fileName& name)
|
||||||
|
{
|
||||||
|
compileFiles_.append(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::dynamicCode::addCopyFile(const fileName& name)
|
||||||
|
{
|
||||||
|
copyFiles_.append(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::dynamicCode::addCreateFile
|
void Foam::dynamicCode::addCreateFile
|
||||||
(
|
(
|
||||||
@ -229,15 +345,6 @@ void Foam::dynamicCode::addCreateFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::dynamicCode::addFilterFile
|
|
||||||
(
|
|
||||||
const fileName& name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
filterFiles_.append(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::dynamicCode::setFilterContext
|
void Foam::dynamicCode::setFilterContext
|
||||||
(
|
(
|
||||||
const dynamicCodeContext& context
|
const dynamicCodeContext& context
|
||||||
@ -252,46 +359,31 @@ void Foam::dynamicCode::setFilterContext
|
|||||||
void Foam::dynamicCode::setFilterVariable
|
void Foam::dynamicCode::setFilterVariable
|
||||||
(
|
(
|
||||||
const word& key,
|
const word& key,
|
||||||
const string& value
|
const std::string& value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
filterVars_.set(key, value);
|
filterVars_.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::fileName Foam::dynamicCode::codePath() const
|
void Foam::dynamicCode::setMakeOptions(const std::string& content)
|
||||||
{
|
{
|
||||||
return stringOps::expand("$FOAM_CASE/dynamicCode/" + codeDirName_);
|
makeOptions_ = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::fileName Foam::dynamicCode::libPath() const
|
bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
|
||||||
{
|
{
|
||||||
return
|
if (verbose)
|
||||||
(
|
{
|
||||||
stringOps::expand
|
Info<< "Creating new library in " << this->libPath() << endl;
|
||||||
(
|
}
|
||||||
"$FOAM_CASE/dynamicCode/platforms/$WM_OPTIONS/lib/lib"
|
|
||||||
)
|
|
||||||
+ codeName_ + ".so"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::string Foam::dynamicCode::libTarget() const
|
|
||||||
{
|
|
||||||
return "LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib" + codeName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::dynamicCode::copyFilesContents() const
|
|
||||||
{
|
|
||||||
if (!allowSystemOperations)
|
if (!allowSystemOperations)
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"dynamicCode::copyFilesContents(const fileName&) const"
|
"dynamicCode::copyOrCreateFiles() const"
|
||||||
) << "Loading a shared library using case-supplied code is not"
|
) << "Loading a shared library using case-supplied code is not"
|
||||||
<< " enabled by default" << nl
|
<< " enabled by default" << nl
|
||||||
<< "because of security issues. If you trust the code you can"
|
<< "because of security issues. If you trust the code you can"
|
||||||
@ -307,7 +399,29 @@ bool Foam::dynamicCode::copyFilesContents() const
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<fileName> resolvedFiles = resolveTemplates(filterFiles_);
|
const label nFiles = compileFiles_.size() + copyFiles_.size();
|
||||||
|
|
||||||
|
DynamicList<fileName> resolvedFiles(nFiles);
|
||||||
|
DynamicList<fileName> badFiles(nFiles);
|
||||||
|
|
||||||
|
// resolve template, or add to bad-files
|
||||||
|
resolveTemplates(compileFiles_, resolvedFiles, badFiles);
|
||||||
|
resolveTemplates(copyFiles_, resolvedFiles, badFiles);
|
||||||
|
|
||||||
|
if (!badFiles.empty())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"dynamicCode::copyFilesContents(..)"
|
||||||
|
) << "Could not find the code template(s): "
|
||||||
|
<< badFiles << nl
|
||||||
|
<< "Under the $" << codeTemplateEnvName
|
||||||
|
<< " directory or via via the ~OpenFOAM/"
|
||||||
|
<< codeTemplateDirName << " expansion"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create dir
|
// Create dir
|
||||||
const fileName outputDir = this->codePath();
|
const fileName outputDir = this->codePath();
|
||||||
@ -345,7 +459,7 @@ bool Foam::dynamicCode::copyFilesContents() const
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// variables mapping
|
// Copy lines while expanding variables
|
||||||
copyAndFilter(is, os, filterVars_);
|
copyAndFilter(is, os, filterVars_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,14 +479,21 @@ bool Foam::dynamicCode::copyFilesContents() const
|
|||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"dynamicCode::copyFilesContents()"
|
"dynamicCode::copyOrCreateFiles()"
|
||||||
" const"
|
" const"
|
||||||
) << "Failed writing " << dstFile
|
) << "Failed writing " << dstFile
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
os << createFiles_[fileI].second().c_str() << endl;
|
os.writeQuoted(createFiles_[fileI].second(), false) << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create Make/files + Make/options
|
||||||
|
createMakeFiles();
|
||||||
|
createMakeOptions();
|
||||||
|
|
||||||
|
writeDigest(filterVars_["SHA1sum"]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,38 +514,16 @@ bool Foam::dynamicCode::wmakeLibso() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::dynamicCode::writeDigest
|
|
||||||
(
|
|
||||||
const fileName& dirName,
|
|
||||||
const SHA1Digest& sha1
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
mkDir(dirName);
|
|
||||||
OFstream os(dirName/"SHA1Digest");
|
|
||||||
os << sha1;
|
|
||||||
return os.good();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::SHA1Digest Foam::dynamicCode::readDigest(const fileName& dirName) const
|
|
||||||
{
|
|
||||||
IFstream is(dirName/"SHA1Digest");
|
|
||||||
return SHA1Digest(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::dynamicCode::upToDate(const SHA1Digest& sha1) const
|
bool Foam::dynamicCode::upToDate(const SHA1Digest& sha1) const
|
||||||
{
|
{
|
||||||
const fileName dirName = this->codePath();
|
const fileName file = digestFile();
|
||||||
if (!exists(dirName/"SHA1Digest") || readDigest(dirName) != sha1)
|
|
||||||
|
if (!exists(file, false) || SHA1Digest(IFstream(file)()) != sha1)
|
||||||
{
|
{
|
||||||
writeDigest(dirName, sha1);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -452,28 +551,4 @@ bool Foam::dynamicCode::upToDate(const dynamicCodeContext& context) const
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// bool Foam::dynamicCode::read(const dictionary& dict)
|
|
||||||
// {
|
|
||||||
// dict.lookup("createFiles") >> createFiles_;
|
|
||||||
// dict.lookup("filterFiles") >> filterFiles_;
|
|
||||||
// dict.lookup("filterVariables") >> filterVariables_;
|
|
||||||
//
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// void Foam::dynamicCode::writeDict(Ostream& os) const
|
|
||||||
// {
|
|
||||||
// os.writeKeyword("createFiles") << createFiles_
|
|
||||||
// << token::END_STATEMENT << nl;
|
|
||||||
//
|
|
||||||
// os.writeKeyword("filterFiles") << filterFiles_
|
|
||||||
// << token::END_STATEMENT << nl;
|
|
||||||
//
|
|
||||||
// os.writeKeyword("filterVariables") << filterVariables_
|
|
||||||
// << token::END_STATEMENT << nl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -64,41 +64,86 @@ public:
|
|||||||
private:
|
private:
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Root for dynamic code compilation
|
||||||
|
fileName codeRoot_;
|
||||||
|
|
||||||
|
//- Subdirectory name for loading libraries
|
||||||
|
const fileName libSubDir_;
|
||||||
|
|
||||||
//- Name for code
|
//- Name for code
|
||||||
word codeName_;
|
word codeName_;
|
||||||
|
|
||||||
//- Name for code subdirectory
|
//- Name for code subdirectory
|
||||||
mutable word codeDirName_;
|
word codeDirName_;
|
||||||
|
|
||||||
//- Variables to use during filtering
|
//- Files to copy and filter
|
||||||
HashTable<string> filterVars_;
|
DynamicList<fileName> compileFiles_;
|
||||||
|
|
||||||
|
//- Files to copy and filter
|
||||||
|
DynamicList<fileName> copyFiles_;
|
||||||
|
|
||||||
//- Direct contents for files
|
//- Direct contents for files
|
||||||
DynamicList<fileAndContent> createFiles_;
|
DynamicList<fileAndContent> createFiles_;
|
||||||
|
|
||||||
//- Files to copy and filter
|
//- Variables to use during filtering
|
||||||
DynamicList<fileName> filterFiles_;
|
HashTable<string> filterVars_;
|
||||||
|
|
||||||
|
//- Contents for Make/options
|
||||||
|
std::string makeOptions_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
dynamicCode(const dynamicCode&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const dynamicCode&);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void copyAndFilter
|
// Static data members
|
||||||
|
|
||||||
|
//- Root of the LIB target for Make/files
|
||||||
|
static const char* libTargetRoot;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Copy lines while expanding variables
|
||||||
|
static void copyAndFilter
|
||||||
(
|
(
|
||||||
ISstream&,
|
ISstream&,
|
||||||
OSstream&,
|
OSstream&,
|
||||||
const HashTable<string>& mapping
|
const HashTable<string>& mapping
|
||||||
) const;
|
);
|
||||||
|
|
||||||
//- Resolve code-templates via the codeTemplateEnvName
|
//- Resolve code-templates via the codeTemplateEnvName
|
||||||
// alternatively in the codeTemplateDirName via Foam::findEtcFile
|
// alternatively in the codeTemplateDirName via Foam::findEtcFile
|
||||||
static List<fileName> resolveTemplates
|
static bool resolveTemplates
|
||||||
(
|
(
|
||||||
const UList<fileName>& names
|
const UList<fileName>& templateNames,
|
||||||
|
DynamicList<fileName>& resolvedFiles,
|
||||||
|
DynamicList<fileName>& badFiles
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Write SHA1 value as C-comment
|
||||||
|
bool writeCommentSHA1(Ostream&) const;
|
||||||
|
|
||||||
|
//- Copy/create Make/files prior to compilation
|
||||||
|
bool createMakeFiles() const;
|
||||||
|
|
||||||
|
//- Copy/create Make/options prior to compilation
|
||||||
|
bool createMakeOptions() const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Write digest to Make/SHA1Digest
|
||||||
|
bool writeDigest(const SHA1Digest&) const;
|
||||||
|
|
||||||
|
//- Write digest to Make/SHA1Digest
|
||||||
|
bool writeDigest(const std::string&) const;
|
||||||
|
|
||||||
bool writeDigest(const fileName& dir, const SHA1Digest& sha1) const;
|
|
||||||
SHA1Digest readDigest(const fileName& dir) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -112,26 +157,25 @@ public:
|
|||||||
// Used when locating the codeTemplateName via Foam::findEtcFile
|
// Used when locating the codeTemplateName via Foam::findEtcFile
|
||||||
static const fileName codeTemplateDirName;
|
static const fileName codeTemplateDirName;
|
||||||
|
|
||||||
|
//- Flag if system operations are allowed
|
||||||
static int allowSystemOperations;
|
static int allowSystemOperations;
|
||||||
|
|
||||||
|
|
||||||
// Static Member functions
|
// Static Member functions
|
||||||
|
|
||||||
//- Check security for creating dynamic code
|
//- Check security for creating dynamic code
|
||||||
static void checkSecurity
|
static void checkSecurity(const char* title, const dictionary&);
|
||||||
(
|
|
||||||
const char* title,
|
|
||||||
const dictionary& dict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct for a specified code name
|
//- Construct for a specified code name and code directory name
|
||||||
dynamicCode(const word& codeName);
|
// Defaults to using the code name for the code directory name
|
||||||
|
dynamicCode
|
||||||
//- Construct for a specified code name and directory name
|
(
|
||||||
dynamicCode(const word& codeName, const word& dirName);
|
const word& codeName,
|
||||||
|
const word& codeDirName = ""
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
@ -148,43 +192,76 @@ public:
|
|||||||
return codeDirName_;
|
return codeDirName_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Clear variables and files
|
//- Root for dynamic code compilation
|
||||||
|
// Expanded from \$FOAM_CASE/dynamicCode
|
||||||
|
const fileName& codeRoot() const
|
||||||
|
{
|
||||||
|
return codeRoot_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Subdirectory name for loading libraries
|
||||||
|
// Expanded from platforms/\$WM_OPTIONS/lib
|
||||||
|
fileName libSubDir() const
|
||||||
|
{
|
||||||
|
return libSubDir_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Path for specified code name
|
||||||
|
// Corresponds to codeRoot()/codeDirName()
|
||||||
|
fileName codePath() const
|
||||||
|
{
|
||||||
|
return codeRoot_/codeDirName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Library path for specified code name
|
||||||
|
// Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so
|
||||||
|
fileName libPath() const
|
||||||
|
{
|
||||||
|
return codeRoot_/libSubDir_/"lib" + codeName_ + ".so";
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Path for SHA1Digest
|
||||||
|
// Corresponds to codePath()/Make/SHA1Digest
|
||||||
|
fileName digestFile() const
|
||||||
|
{
|
||||||
|
return codeRoot_/codeDirName_/"Make/SHA1Digest";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Clear files and variables
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
//- Clear files and reset variables to specified context
|
||||||
|
void reset(const dynamicCodeContext&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Add a file template name, which will be found and filtered
|
||||||
|
void addCompileFile(const fileName& name);
|
||||||
|
|
||||||
|
//- Add a file template name, which will be found and filtered
|
||||||
|
void addCopyFile(const fileName& name);
|
||||||
|
|
||||||
//- Add a file to create with its contents. Will not be filtered
|
//- Add a file to create with its contents. Will not be filtered
|
||||||
void addCreateFile(const fileName& name, const string& contents);
|
void addCreateFile(const fileName& name, const string& contents);
|
||||||
|
|
||||||
//- Add a file template name, which will be found and filtered
|
|
||||||
void addFilterFile(const fileName& name);
|
|
||||||
|
|
||||||
//- Define filter variables for code, codeInclude, SHA1sum
|
//- Define filter variables for code, codeInclude, SHA1sum
|
||||||
void setFilterContext(const dynamicCodeContext&);
|
void setFilterContext(const dynamicCodeContext&);
|
||||||
|
|
||||||
//- Define a filter variable
|
//- Define a filter variable
|
||||||
void setFilterVariable(const word& key, const string& value);
|
void setFilterVariable(const word& key, const std::string& value);
|
||||||
|
|
||||||
|
//- Define contents for Make/options
|
||||||
|
void setMakeOptions(const std::string& content);
|
||||||
|
|
||||||
|
|
||||||
//- Local path for specified code name
|
//- Verify if the copied code is up-to-date, based on Make/SHA1Digest
|
||||||
// Expanded from \$FOAM_CASE/dynamicCode/codeDirName
|
|
||||||
fileName codePath() const;
|
|
||||||
|
|
||||||
//- Local library path for specified code name
|
|
||||||
// Expanded from \$FOAM_CASE/dynamicCode/platforms/\$WM_OPTIONS/lib
|
|
||||||
fileName libPath() const;
|
|
||||||
|
|
||||||
//- The library target path for Make/files
|
|
||||||
string libTarget() const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Verify if the copied code is up-to-date
|
|
||||||
bool upToDate(const dynamicCodeContext& context) const;
|
bool upToDate(const dynamicCodeContext& context) const;
|
||||||
|
|
||||||
//- Verify if the copied code is up-to-date
|
//- Verify if the copied code is up-to-date, based on Make/SHA1Digest
|
||||||
bool upToDate(const SHA1Digest& sha1) const;
|
bool upToDate(const SHA1Digest& sha1) const;
|
||||||
|
|
||||||
//- Copy/create files prior to compilation
|
//- Copy/create files prior to compilation
|
||||||
bool copyFilesContents() const;
|
bool copyOrCreateFiles(const bool verbose = false) const;
|
||||||
|
|
||||||
//- Compile a libso
|
//- Compile a libso
|
||||||
bool wmakeLibso() const;
|
bool wmakeLibso() const;
|
||||||
@ -198,8 +275,6 @@ public:
|
|||||||
// //- Find the handle of the libPath() library
|
// //- Find the handle of the libPath() library
|
||||||
// void* findLibrary() const;
|
// void* findLibrary() const;
|
||||||
|
|
||||||
// bool read(const dictionary&);
|
|
||||||
// void writeDict(Ostream&) const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -82,55 +82,47 @@ void Foam::codedFixedValueFvPatchScalarField::createLibrary
|
|||||||
(
|
(
|
||||||
dynamicCode& dynCode,
|
dynamicCode& dynCode,
|
||||||
const dynamicCodeContext& context
|
const dynamicCodeContext& context
|
||||||
)
|
) const
|
||||||
{
|
{
|
||||||
// Write files for new library
|
// Write files for new library
|
||||||
if (Pstream::master() && !dynCode.upToDate(context))
|
if (Pstream::master() && !dynCode.upToDate(context))
|
||||||
{
|
{
|
||||||
Info<< "Creating new library in " << dynCode.libPath() << endl;
|
|
||||||
dynCode.clear();
|
|
||||||
|
|
||||||
// filter with this context
|
// filter with this context
|
||||||
dynCode.setFilterContext(context);
|
dynCode.reset(context);
|
||||||
|
|
||||||
// filter C/H template
|
// compile filtered C template
|
||||||
dynCode.addFilterFile(codeTemplateC);
|
dynCode.addCompileFile(codeTemplateC);
|
||||||
dynCode.addFilterFile(codeTemplateH);
|
|
||||||
|
|
||||||
// Make/files
|
// copy filtered H template
|
||||||
dynCode.addCreateFile
|
dynCode.addCopyFile(codeTemplateH);
|
||||||
|
|
||||||
|
// define Make/options
|
||||||
|
dynCode.setMakeOptions
|
||||||
(
|
(
|
||||||
"Make/files",
|
|
||||||
codeTemplateC + "\n\n"
|
|
||||||
+ dynCode.libTarget()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Make/options
|
|
||||||
dynCode.addCreateFile
|
|
||||||
(
|
|
||||||
"Make/options",
|
|
||||||
"EXE_INC = -g \\\n"
|
"EXE_INC = -g \\\n"
|
||||||
"-I$(LIB_SRC)/finiteVolume/lnInclude\\\n"
|
"-I$(LIB_SRC)/finiteVolume/lnInclude\\\n"
|
||||||
+ context.options()
|
+ context.options()
|
||||||
+ "\n\nLIB_LIBS = "
|
+ "\n\nLIB_LIBS = "
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!dynCode.copyFilesContents())
|
if (!dynCode.copyOrCreateFiles(true))
|
||||||
{
|
{
|
||||||
FatalIOErrorIn
|
FatalIOErrorIn
|
||||||
(
|
(
|
||||||
"codedFixedValueFvPatchScalarField::writeLibrary(..)",
|
"codedFixedValueFvPatchScalarField::writeLibrary(..)",
|
||||||
context.dict()
|
context.dict()
|
||||||
) << "Failed writing " << nl
|
) << "Failed writing files for" << nl
|
||||||
// << copyFiles << nl
|
<< dynCode.libPath() << nl
|
||||||
// << filesContents
|
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::codedFixedValueFvPatchScalarField::updateLibrary()
|
void Foam::codedFixedValueFvPatchScalarField::updateLibrary
|
||||||
|
(
|
||||||
|
bool firstTime
|
||||||
|
) const
|
||||||
{
|
{
|
||||||
dynamicCode::checkSecurity
|
dynamicCode::checkSecurity
|
||||||
(
|
(
|
||||||
@ -138,97 +130,124 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary()
|
|||||||
dict_
|
dict_
|
||||||
);
|
);
|
||||||
|
|
||||||
// use in-line or via codeProperties
|
// use codeProperties or in-line
|
||||||
const bool useInlineDict = dict_.found("code");
|
const bool useCodeProps = !dict_.found("code");
|
||||||
|
|
||||||
// determine code context (code, codeInclude, codeOptions)
|
const dictionary& codeDict =
|
||||||
dynamicCodeContext context
|
|
||||||
(
|
(
|
||||||
useInlineDict
|
useCodeProps
|
||||||
? dict_
|
? this->dict().subDict(redirectType_)
|
||||||
: this->dict().subDict(redirectType_)
|
: dict_
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// NOTE: probably don't need codeProperties anymore
|
autoPtr<dynamicCodeContext> contextPtr;
|
||||||
// since we use the sha1 directly
|
|
||||||
if (!useInlineDict)
|
|
||||||
{
|
|
||||||
this->dict().setUnmodified();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// write code into redirectType_ subdir as well
|
// write code into redirectType_ subdir as well
|
||||||
dynamicCode dynCode(redirectType_);
|
dynamicCode dynCode(redirectType_);
|
||||||
|
|
||||||
// The version function name - based on the SHA1
|
|
||||||
const string checkFuncName
|
|
||||||
(
|
|
||||||
dynCode.codeName() + "_" + context.sha1().str()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const fileName libPath = dynCode.libPath();
|
const fileName libPath = dynCode.libPath();
|
||||||
|
|
||||||
|
// see if library is loaded
|
||||||
void* lib = dlLibraryTable::findLibrary(libPath);
|
void* lib = dlLibraryTable::findLibrary(libPath);
|
||||||
|
|
||||||
// Load library if not already loaded
|
bool reuseLib = false;
|
||||||
bool reusing = false;
|
|
||||||
if (!lib && dlLibraryTable::open(libPath, false))
|
|
||||||
{
|
|
||||||
lib = dlLibraryTable::findLibrary(libPath);
|
|
||||||
reusing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// library may have loaded, the version may not be correct
|
|
||||||
bool waiting = false;
|
bool waiting = false;
|
||||||
if (lib)
|
|
||||||
|
if (useCodeProps)
|
||||||
{
|
{
|
||||||
// Unload library if needed
|
// library may be loaded, but out-of-date
|
||||||
if (!dlSym(lib, checkFuncName))
|
const codeProperties& codeProps = this->dict();
|
||||||
|
if (codeProps.modified())
|
||||||
{
|
{
|
||||||
reusing = false;
|
codeProps.setUnmodified();
|
||||||
waiting = true;
|
|
||||||
if (!dlLibraryTable::close(libPath, false))
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"codedFixedValueFvPatchScalarField::updateLibrary(..)",
|
|
||||||
context.dict()
|
|
||||||
) << "Failed unloading library "
|
|
||||||
<< libPath
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
lib = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unload from all processes
|
|
||||||
reduce(waiting, orOp<bool>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// create library
|
|
||||||
if (!lib)
|
|
||||||
{
|
|
||||||
if (useInlineDict)
|
|
||||||
{
|
|
||||||
createLibrary(dynCode, context);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove instantiation of fvPatchField provided by library
|
// Remove instantiation of fvPatchField provided by library
|
||||||
redirectPatchFieldPtr_.clear();
|
redirectPatchFieldPtr_.clear();
|
||||||
createLibrary(dynCode, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
contextPtr.reset(new dynamicCodeContext(codeDict));
|
||||||
|
|
||||||
|
// unload code
|
||||||
|
if (lib)
|
||||||
|
{
|
||||||
|
firstTime = false;
|
||||||
|
reuseLib = false;
|
||||||
|
lib = 0;
|
||||||
|
|
||||||
|
if (!dlLibraryTable::close(libPath, false))
|
||||||
|
{
|
||||||
|
FatalIOErrorIn
|
||||||
|
(
|
||||||
|
"codedFixedValueFvPatchScalarField::"
|
||||||
|
"updateLibrary()",
|
||||||
|
contextPtr().dict()
|
||||||
|
) << "Failed unloading library "
|
||||||
|
<< libPath
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// library exists (and was not unloaded) - we can leave now
|
||||||
|
if (lib)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Remove instantiation of fvPatchField provided by library
|
||||||
|
redirectPatchFieldPtr_.clear();
|
||||||
|
|
||||||
|
if (contextPtr.empty())
|
||||||
|
{
|
||||||
|
contextPtr.reset(new dynamicCodeContext(codeDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
// function name serving as version control - based on the SHA1
|
||||||
|
const string sentinelName
|
||||||
|
= dynCode.codeName() + contextPtr().sha1().str(true);
|
||||||
|
|
||||||
|
// avoid compilation (first time only) by loading an existing library
|
||||||
|
if (firstTime && dlLibraryTable::open(libPath, false))
|
||||||
|
{
|
||||||
|
lib = dlLibraryTable::findLibrary(libPath);
|
||||||
|
|
||||||
|
// verify the loaded version and unload if needed
|
||||||
|
if (lib)
|
||||||
|
{
|
||||||
|
reuseLib = dlSymFound(lib, sentinelName);
|
||||||
|
if (!reuseLib)
|
||||||
|
{
|
||||||
|
lib = 0;
|
||||||
|
if (!dlLibraryTable::close(libPath, false))
|
||||||
|
{
|
||||||
|
FatalIOErrorIn
|
||||||
|
(
|
||||||
|
"codedFixedValueFvPatchScalarField::updateLibrary()",
|
||||||
|
contextPtr().dict()
|
||||||
|
) << "Failed unloading library "
|
||||||
|
<< libPath
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// really do need to create library
|
||||||
|
if (!lib)
|
||||||
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
|
createLibrary(dynCode, contextPtr());
|
||||||
|
|
||||||
if (!dynCode.wmakeLibso())
|
if (!dynCode.wmakeLibso())
|
||||||
{
|
{
|
||||||
FatalIOErrorIn
|
FatalIOErrorIn
|
||||||
(
|
(
|
||||||
"codedFixedValueFvPatchScalarField::updateLibrary()",
|
"codedFixedValueFvPatchScalarField::updateLibrary()",
|
||||||
dict_
|
contextPtr().dict()
|
||||||
) << "Failed wmake " << libPath
|
) << "Failed wmake " << libPath
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
@ -243,33 +262,43 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary()
|
|||||||
FatalIOErrorIn
|
FatalIOErrorIn
|
||||||
(
|
(
|
||||||
"codedFixedValueFvPatchScalarField::updateLibrary()",
|
"codedFixedValueFvPatchScalarField::updateLibrary()",
|
||||||
dict_
|
contextPtr().dict()
|
||||||
) << "Failed loading library " << libPath
|
) << "Failed loading library " << libPath
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// paranoid - check that signature function is really there
|
|
||||||
lib = dlLibraryTable::findLibrary(libPath);
|
lib = dlLibraryTable::findLibrary(libPath);
|
||||||
if (lib)
|
if (!lib)
|
||||||
{
|
{
|
||||||
if (!dlSym(lib, checkFuncName))
|
FatalIOErrorIn
|
||||||
{
|
(
|
||||||
FatalIOErrorIn
|
"codedFixedValueFvPatchScalarField::"
|
||||||
(
|
"updateLibrary()",
|
||||||
"codedFixedValueFvPatchScalarField::updateLibrary(..)",
|
contextPtr().dict()
|
||||||
dict_
|
) << "Failed to load library " << libPath
|
||||||
) << "Library loaded - but wrong version!"
|
<< exit(FatalIOError);
|
||||||
<< libPath
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
lib = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#if 0
|
||||||
|
// Info<<"check " << libPath << " for " << sentinelName << nl;
|
||||||
|
// // paranoid - check that signature function is really there
|
||||||
|
// lib = dlLibraryTable::findLibrary(libPath);
|
||||||
|
// if (!lib || !dlSymFound(lib, sentinelName))
|
||||||
|
// {
|
||||||
|
// FatalIOErrorIn
|
||||||
|
// (
|
||||||
|
// "codedFixedValueFvPatchScalarField::"
|
||||||
|
// "updateLibrary()",
|
||||||
|
// contextPtr().dict()
|
||||||
|
// ) << "Failed to load library with correct signature "
|
||||||
|
// << libPath
|
||||||
|
// << exit(FatalIOError);
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
else if (reusing)
|
else if (reuseLib)
|
||||||
{
|
{
|
||||||
Info<< "Reusing library in " << libPath << nl
|
Info<< "Reusing library in " << libPath << nl;
|
||||||
<< " with " << context.sha1().str() << nl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +313,7 @@ codedFixedValueFvPatchScalarField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<scalar>(p, iF),
|
fixedValueFvPatchField<scalar>(p, iF),
|
||||||
redirectPatchFieldPtr_(NULL)
|
redirectPatchFieldPtr_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -300,7 +329,7 @@ codedFixedValueFvPatchScalarField
|
|||||||
fixedValueFvPatchField<scalar>(ptf, p, iF, mapper),
|
fixedValueFvPatchField<scalar>(ptf, p, iF, mapper),
|
||||||
dict_(ptf.dict_),
|
dict_(ptf.dict_),
|
||||||
redirectType_(ptf.redirectType_),
|
redirectType_(ptf.redirectType_),
|
||||||
redirectPatchFieldPtr_(NULL)
|
redirectPatchFieldPtr_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -315,9 +344,9 @@ codedFixedValueFvPatchScalarField
|
|||||||
fixedValueFvPatchField<scalar>(p, iF, dict),
|
fixedValueFvPatchField<scalar>(p, iF, dict),
|
||||||
dict_(dict),
|
dict_(dict),
|
||||||
redirectType_(dict.lookup("redirectType")),
|
redirectType_(dict.lookup("redirectType")),
|
||||||
redirectPatchFieldPtr_(NULL)
|
redirectPatchFieldPtr_()
|
||||||
{
|
{
|
||||||
updateLibrary();
|
updateLibrary(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -330,7 +359,7 @@ codedFixedValueFvPatchScalarField
|
|||||||
fixedValueFvPatchField<scalar>(ptf),
|
fixedValueFvPatchField<scalar>(ptf),
|
||||||
dict_(ptf.dict_),
|
dict_(ptf.dict_),
|
||||||
redirectType_(ptf.redirectType_),
|
redirectType_(ptf.redirectType_),
|
||||||
redirectPatchFieldPtr_(NULL)
|
redirectPatchFieldPtr_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -344,7 +373,7 @@ codedFixedValueFvPatchScalarField
|
|||||||
fixedValueFvPatchField<scalar>(ptf, iF),
|
fixedValueFvPatchField<scalar>(ptf, iF),
|
||||||
dict_(ptf.dict_),
|
dict_(ptf.dict_),
|
||||||
redirectType_(ptf.redirectType_),
|
redirectType_(ptf.redirectType_),
|
||||||
redirectPatchFieldPtr_(NULL)
|
redirectPatchFieldPtr_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -366,6 +395,18 @@ Foam::codedFixedValueFvPatchScalarField::redirectPatchField() const
|
|||||||
dictionary dict(is);
|
dictionary dict(is);
|
||||||
Info<< "constructing patchField from :" << dict << endl;
|
Info<< "constructing patchField from :" << dict << endl;
|
||||||
|
|
||||||
|
// if (fvPatchScalarField::dictionaryConstructorTablePtr_)
|
||||||
|
// {
|
||||||
|
// fvPatchScalarField::dictionaryConstructorPtr funcPtr =
|
||||||
|
// (
|
||||||
|
// fvPatchScalarField::dictionaryConstructorTablePtr_->
|
||||||
|
// find(redirectType_)()
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// Info<< redirectType_ << " FunctionPtr => "
|
||||||
|
// << long(funcPtr) << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
redirectPatchFieldPtr_.set
|
redirectPatchFieldPtr_.set
|
||||||
(
|
(
|
||||||
fvPatchScalarField::New
|
fvPatchScalarField::New
|
||||||
|
|||||||
@ -113,19 +113,21 @@ class codedFixedValueFvPatchScalarField
|
|||||||
|
|
||||||
const codeProperties& dict() const;
|
const codeProperties& dict() const;
|
||||||
|
|
||||||
void createLibrary(dynamicCode&, const dynamicCodeContext& dict);
|
void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
|
||||||
|
|
||||||
void updateLibrary();
|
//- Update library as required
|
||||||
|
// Use 'firstTime' to alter behaviour
|
||||||
|
void updateLibrary(bool firstTime=false) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Static data members
|
// Static data members
|
||||||
|
|
||||||
//- Name of the C code template to be used
|
//- Name of the C code template to be used
|
||||||
const static word codeTemplateC;
|
static const word codeTemplateC;
|
||||||
|
|
||||||
//- Name of the H code template to be used
|
//- Name of the H code template to be used
|
||||||
const static word codeTemplateH;
|
static const word codeTemplateH;
|
||||||
|
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -217,7 +219,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
//- Write
|
//- Write
|
||||||
virtual void write(Ostream& os) const;
|
virtual void write(Ostream&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user