diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 3e52499e25f7d53c52bda5bc89d72bcf2edb3f40..6e169d64bc54fef0fde90118cdb6ab2b2405bd4f 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -193,6 +193,7 @@ dll = db/dynamicLibrary $(dll)/dlLibraryTable/dlLibraryTable.C $(dll)/dynamicCode/dynamicCode.C $(dll)/dynamicCode/dynamicCodeContext.C +$(dll)/codedBase/codedBase.C db/functionObjects/functionObject/functionObject.C db/functionObjects/functionObjectList/functionObjectList.C diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C new file mode 100644 index 0000000000000000000000000000000000000000..c899b97b595549b06ad603a148e7878fe96904f1 --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C @@ -0,0 +1,288 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "codedBase.H" +#include "SHA1Digest.H" +#include "dynamicCode.H" +#include "dynamicCodeContext.H" +#include "dlLibraryTable.H" +#include "PstreamReduceOps.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +void* Foam::codedBase::loadLibrary +( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict +) const +{ + void* lib = 0; + + // avoid compilation by loading an existing library + if (!libPath.empty()) + { + if (libs().open(libPath, false)) + { + lib = libs().findLibrary(libPath); + + // verify the loaded version and unload if needed + if (lib) + { + // provision for manual execution of code after loading + if (dlSymFound(lib, globalFuncName)) + { + loaderFunctionType function = + reinterpret_cast<loaderFunctionType> + ( + dlSym(lib, globalFuncName) + ); + + if (function) + { + (*function)(true); // force load + } + else + { + FatalIOErrorIn + ( + "codedBase::updateLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName + << nl << "from " << libPath << exit(FatalIOError); + } + } + else + { + FatalIOErrorIn + ( + "codedBase::loadLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath << exit(FatalIOError); + + lib = 0; + if (!libs().close(libPath, false)) + { + FatalIOErrorIn + ( + "codedBase::loadLibrary()", + contextDict + ) << "Failed unloading library " + << libPath + << exit(FatalIOError); + } + } + } + } + } + + return lib; +} + + +void Foam::codedBase::unloadLibrary +( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict +) const +{ + void* lib = 0; + + if (libPath.empty()) + { + return; + } + + lib = libs().findLibrary(libPath); + + if (!lib) + { + return; + } + + // provision for manual execution of code before unloading + if (dlSymFound(lib, globalFuncName)) + { + loaderFunctionType function = + reinterpret_cast<loaderFunctionType> + ( + dlSym(lib, globalFuncName) + ); + + if (function) + { + (*function)(false); // force unload + } + else + { + FatalIOErrorIn + ( + "codedBase::unloadLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath << exit(FatalIOError); + } + } + + if (!libs().close(libPath, false)) + { + FatalIOErrorIn + ( + "codedBase::updateLibrary()", + contextDict + ) << "Failed unloading library " << libPath + << exit(FatalIOError); + } +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::codedBase::createLibrary +( + dynamicCode& dynCode, + const dynamicCodeContext& context +) const +{ + bool create = Pstream::master(); + + if (create) + { + // Write files for new library + if (!dynCode.upToDate(context)) + { + // filter with this context + dynCode.reset(context); + + this->prepare(dynCode, context); + + if (!dynCode.copyOrCreateFiles(true)) + { + FatalIOErrorIn + ( + "codedBase::createLibrary(..)", + context.dict() + ) << "Failed writing files for" << nl + << dynCode.libRelPath() << nl + << exit(FatalIOError); + } + } + + if (!dynCode.wmakeLibso()) + { + FatalIOErrorIn + ( + "codedBase::createLibrary(..)", + context.dict() + ) << "Failed wmake " << dynCode.libRelPath() << nl + << exit(FatalIOError); + } + } + + + // all processes must wait for compile to finish + reduce(create, orOp<bool>()); +} + + +void Foam::codedBase::updateLibrary +( + const word& redirectType +) const +{ + const dictionary& dict = this->codeDict(); + + dynamicCode::checkSecurity + ( + "codedBase::updateLibrary()", + dict + ); + + dynamicCodeContext context(dict); + + // codeName: redirectType + _<sha1> + // codeDir : redirectType + dynamicCode dynCode + ( + redirectType + context.sha1().str(true), + redirectType + ); + const fileName libPath = dynCode.libPath(); + + + // the correct library was already loaded => we are done + if (libs().findLibrary(libPath)) + { + return; + } + + Info<< "Using dynamicCode for " << this->description().c_str() + << " at line " << dict.startLineNumber() + << " in " << dict.name() << endl; + + + // remove instantiation of fvPatchField provided by library + this->clearRedirect(); + + // may need to unload old library + unloadLibrary + ( + oldLibPath_, + dynamicCode::libraryBaseName(oldLibPath_), + context.dict() + ); + + // try loading an existing library (avoid compilation when possible) + if (!loadLibrary(libPath, dynCode.codeName(), context.dict())) + { + createLibrary(dynCode, context); + + loadLibrary(libPath, dynCode.codeName(), context.dict()); + } + + // retain for future reference + oldLibPath_ = libPath; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::codedBase::codedBase() +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::codedBase::~codedBase() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H new file mode 100644 index 0000000000000000000000000000000000000000..391c5267c084011f0ae29de4298206305a366e87 --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::codedBase + +Description + Base class for function objects and boundary conditions using dynamic code + +SourceFiles + codedBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef codedBase_H +#define codedBase_H + +#include "dictionary.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class dynamicCode; +class dynamicCodeContext; +class dlLibraryTable; + +/*---------------------------------------------------------------------------*\ + Class codedBase Declaration +\*---------------------------------------------------------------------------*/ + +class codedBase +{ + // Private data + + //- Previously loaded library + mutable fileName oldLibPath_; + + // Private Member Functions + + //- Global loader/unloader function type + typedef void (*loaderFunctionType)(bool); + + //- Load specified library and execute globalFuncName(true) + void* loadLibrary + ( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict + ) const; + + //- Execute globalFuncName(false) and unload specified library + void unloadLibrary + ( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict + ) const; + + //- Create library based on the dynamicCodeContext + void createLibrary(dynamicCode&, const dynamicCodeContext&) const; + + //- Disallow default bitwise copy construct + codedBase(const codedBase&); + + //- Disallow default bitwise assignment + void operator=(const codedBase&); + + +protected: + + //- Update library as required + void updateLibrary + ( + const word& redirectType + ) const; + + //- get the loaded dynamic libraries + virtual dlLibraryTable& libs() const = 0; + + //- adapt the context for the current object + virtual void prepare + ( + dynamicCode&, + const dynamicCodeContext & + ) const = 0; + + // Return a description (type + name) for the output + virtual string description() const = 0; + + // Clear any redirected objects + virtual void clearRedirect() const = 0; + + // Get the dictionary to initialize the codeContext + virtual const dictionary& codeDict() const = 0; + + +public: + + // Constructors + + //- Construct null + codedBase(); + + + //- Destructor + virtual ~codedBase(); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C index 4b131118d22ba138e4b8cfd922183619c4819d70..acffe1a9b37a4e3fb2126fa47510822e6b350c56 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C @@ -26,19 +26,10 @@ License #include "codedFixedValueFvPatchField.H" #include "addToRunTimeSelectionTable.H" #include "fvPatchFieldMapper.H" -#include "surfaceFields.H" #include "volFields.H" -#include "dlLibraryTable.H" -#include "IFstream.H" -#include "OFstream.H" -#include "SHA1Digest.H" #include "dynamicCode.H" #include "dynamicCodeContext.H" #include "stringOps.H" -#include "IOdictionary.H" - -#include <dlfcn.h> -#include <link.h> // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -53,142 +44,6 @@ const Foam::word Foam::codedFixedValueFvPatchField<Type>::codeTemplateH // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -template<class Type> -void* Foam::codedFixedValueFvPatchField<Type>::loadLibrary -( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict -) const -{ - void* lib = 0; - - // avoid compilation by loading an existing library - if (!libPath.empty()) - { - dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs(); - - if (libs.open(libPath, false)) - { - lib = libs.findLibrary(libPath); - - // verify the loaded version and unload if needed - if (lib) - { - // provision for manual execution of code after loading - if (dlSymFound(lib, globalFuncName)) - { - loaderFunctionType function = - reinterpret_cast<loaderFunctionType> - ( - dlSym(lib, globalFuncName) - ); - - if (function) - { - (*function)(true); // force load - } - else - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::" - "updateLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName - << nl << "from " << libPath << exit(FatalIOError); - } - } - else - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::loadLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName << nl - << "from " << libPath << exit(FatalIOError); - - lib = 0; - if (!libs.close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::loadLibrary()", - contextDict - ) << "Failed unloading library " - << libPath - << exit(FatalIOError); - } - } - } - } - } - - return lib; -} - - -template<class Type> -void Foam::codedFixedValueFvPatchField<Type>::unloadLibrary -( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict -) const -{ - void* lib = 0; - - if (libPath.empty()) - { - return; - } - - dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs(); - - lib = libs.findLibrary(libPath); - - if (!lib) - { - return; - } - - // provision for manual execution of code before unloading - if (dlSymFound(lib, globalFuncName)) - { - loaderFunctionType function = - reinterpret_cast<loaderFunctionType> - ( - dlSym(lib, globalFuncName) - ); - - if (function) - { - (*function)(false); // force unload - } - else - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::unloadLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName << nl - << "from " << libPath << exit(FatalIOError); - } - } - - if (!libs.close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::" - "updateLibrary()", - contextDict - ) << "Failed unloading library " << libPath - << exit(FatalIOError); - } -} - - template<class Type> void Foam::codedFixedValueFvPatchField<Type>::setFieldTemplates ( @@ -238,144 +93,82 @@ const Foam::IOdictionary& Foam::codedFixedValueFvPatchField<Type>::dict() const template<class Type> -void Foam::codedFixedValueFvPatchField<Type>::createLibrary +Foam::dlLibraryTable& Foam::codedFixedValueFvPatchField<Type>::libs() const +{ + return const_cast<dlLibraryTable&>(this->db().time().libs()); +} + + +template<class Type> +void Foam::codedFixedValueFvPatchField<Type>::prepare ( dynamicCode& dynCode, const dynamicCodeContext& context ) const { - bool create = Pstream::master(); - - if (create) - { - // Write files for new library - if (!dynCode.upToDate(context)) - { - // filter with this context - dynCode.reset(context); + // take no chances - typeName must be identical to redirectType_ + dynCode.setFilterVariable("typeName", redirectType_); - // take no chances - typeName must be identical to redirectType_ - dynCode.setFilterVariable("typeName", redirectType_); + // set TemplateType and FieldType filter variables + // (for fvPatchField) + setFieldTemplates(dynCode); - // set TemplateType and FieldType filter variables - // (for fvPatchField) - setFieldTemplates(dynCode); + // compile filtered C template + dynCode.addCompileFile(codeTemplateC); - // compile filtered C template - dynCode.addCompileFile(codeTemplateC); + // copy filtered H template + dynCode.addCopyFile(codeTemplateH); - // copy filtered H template - dynCode.addCopyFile(codeTemplateH); - - - // debugging: make BC verbose - // dynCode.setFilterVariable("verbose", "true"); - // Info<<"compile " << redirectType_ << " sha1: " - // << context.sha1() << endl; - - // define Make/options - dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); - - if (!dynCode.copyOrCreateFiles(true)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::createLibrary(..)", - context.dict() - ) << "Failed writing files for" << nl - << dynCode.libRelPath() << nl - << exit(FatalIOError); - } - } - - if (!dynCode.wmakeLibso()) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchField<Type>::createLibrary(..)", - context.dict() - ) << "Failed wmake " << dynCode.libRelPath() << nl - << exit(FatalIOError); - } - } + // debugging: make BC verbose + // dynCode.setFilterVariable("verbose", "true"); + // Info<<"compile " << redirectType_ << " sha1: " + // << context.sha1() << endl; - // all processes must wait for compile to finish - reduce(create, orOp<bool>()); + // define Make/options + dynCode.setMakeOptions + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + + " -lOpenFOAM \\\n" + + " -lfiniteVolume \\\n" + + context.libs() + ); } template<class Type> -void Foam::codedFixedValueFvPatchField<Type>::updateLibrary() const +const Foam::dictionary& Foam::codedFixedValueFvPatchField<Type>::codeDict() +const { - dynamicCode::checkSecurity - ( - "codedFixedValueFvPatchField<Type>::updateLibrary()", - dict_ - ); - // use system/codeDict or in-line - const dictionary& codeDict = + return ( dict_.found("code") ? dict_ : this->dict().subDict(redirectType_) ); +} - dynamicCodeContext context(codeDict); - - // codeName: redirectType + _<sha1> - // codeDir : redirectType - dynamicCode dynCode - ( - redirectType_ + context.sha1().str(true), - redirectType_ - ); - const fileName libPath = dynCode.libPath(); - - - // the correct library was already loaded => we are done - if (const_cast<Time&>(this->db().time()).libs().findLibrary(libPath)) - { - return; - } - Info<< "Using dynamicCode for patch " << this->patch().name() - << " on field " << this->dimensionedInternalField().name() << nl - << "at line " << codeDict.startLineNumber() - << " in " << codeDict.name() << endl; +template<class Type> +Foam::string Foam::codedFixedValueFvPatchField<Type>::description() const +{ + return + "patch " + + this->patch().name() + + " on field " + + this->dimensionedInternalField().name(); +} +template<class Type> +void Foam::codedFixedValueFvPatchField<Type>::clearRedirect() const +{ // remove instantiation of fvPatchField provided by library redirectPatchFieldPtr_.clear(); - - // may need to unload old library - unloadLibrary - ( - oldLibPath_, - dynamicCode::libraryBaseName(oldLibPath_), - context.dict() - ); - - // try loading an existing library (avoid compilation when possible) - if (!loadLibrary(libPath, dynCode.codeName(), context.dict())) - { - createLibrary(dynCode, context); - - loadLibrary(libPath, dynCode.codeName(), context.dict()); - } - - // retain for future reference - oldLibPath_ = libPath; } @@ -389,7 +182,7 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField ) : fixedValueFvPatchField<Type>(p, iF), - oldLibPath_(), + codedBase(), redirectPatchFieldPtr_() {} @@ -404,9 +197,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField ) : fixedValueFvPatchField<Type>(ptf, p, iF, mapper), + codedBase(), dict_(ptf.dict_), redirectType_(ptf.redirectType_), - oldLibPath_(ptf.oldLibPath_), redirectPatchFieldPtr_() {} @@ -420,12 +213,12 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField ) : fixedValueFvPatchField<Type>(p, iF, dict), + codedBase(), dict_(dict), redirectType_(dict.lookup("redirectType")), - oldLibPath_(), redirectPatchFieldPtr_() { - updateLibrary(); + updateLibrary(redirectType_); } @@ -436,9 +229,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField ) : fixedValueFvPatchField<Type>(ptf), + codedBase(), dict_(ptf.dict_), redirectType_(ptf.redirectType_), - oldLibPath_(ptf.oldLibPath_), redirectPatchFieldPtr_() {} @@ -451,9 +244,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField ) : fixedValueFvPatchField<Type>(ptf, iF), + codedBase(), dict_(ptf.dict_), redirectType_(ptf.redirectType_), - oldLibPath_(ptf.oldLibPath_), redirectPatchFieldPtr_() {} @@ -499,7 +292,7 @@ void Foam::codedFixedValueFvPatchField<Type>::updateCoeffs() } // Make sure library containing user-defined fvPatchField is up-to-date - updateLibrary(); + updateLibrary(redirectType_); const fvPatchField<Type>& fvp = redirectPatchField(); @@ -519,7 +312,7 @@ void Foam::codedFixedValueFvPatchField<Type>::evaluate ) { // Make sure library containing user-defined fvPatchField is up-to-date - updateLibrary(); + updateLibrary(redirectType_); const fvPatchField<Type>& fvp = redirectPatchField(); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H index 86172fe86b66771d91fc78fae2bcf0653d667f0b..56fef9354e49b159835194a49a8e38c2080f38b1 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H @@ -79,9 +79,7 @@ SourceFiles #define codedFixedValueFvPatchField_H #include "fixedValueFvPatchFields.H" - -#include <dlfcn.h> -#include <link.h> +#include "codedBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -100,7 +98,8 @@ class IOdictionary; template<class Type> class codedFixedValueFvPatchField : - public fixedValueFvPatchField<Type> + public fixedValueFvPatchField<Type>, + public codedBase { // Private data @@ -109,51 +108,29 @@ class codedFixedValueFvPatchField const word redirectType_; - //- Previously loaded library - mutable fileName oldLibPath_; - mutable autoPtr<fvPatchField<Type> > redirectPatchFieldPtr_; - // Private Member Functions const IOdictionary& dict() const; - //- Global loader/unloader function type - typedef void (*loaderFunctionType)(bool); - - static int collectLibsCallback - ( - struct dl_phdr_info *info, - size_t size, - void *data - ); - - //- Load specified library and execute globalFuncName(true) - void* loadLibrary - ( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict - ) const; - - //- Execute globalFuncName(false) and unload specified library - void unloadLibrary - ( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict - ) const; - //- Set the rewrite vars controlling the Type static void setFieldTemplates(dynamicCode& dynCode); - //- Create library based on the dynamicCodeContext - void createLibrary(dynamicCode&, const dynamicCodeContext&) const; + //- get the loaded dynamic libraries + virtual dlLibraryTable& libs() const; + + //- adapt the context for the current object + virtual void prepare(dynamicCode&, const dynamicCodeContext&) const; + + // Return a description (type + name) for the output + virtual string description() const; - //- Update library as required - void updateLibrary() const; + // Clear the ptr to the redirected object + virtual void clearRedirect() const; + // Get the dictionary to initialize the codeContext + virtual const dictionary& codeDict() const; public: diff --git a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C index c50fa7b64f8de12cf76e6c23f052a2f906acb408..45a915456acfecba35756ab3961db6dd692361dd 100644 --- a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C +++ b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C @@ -49,271 +49,71 @@ namespace Foam // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -void* Foam::codedFunctionObject::loadLibrary -( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict -) const -{ - void* lib = 0; - - // avoid compilation by loading an existing library - if (!libPath.empty()) - { - dlLibraryTable& libs = const_cast<Time&>(time_).libs(); - - if (libs.open(libPath, false)) - { - lib = libs.findLibrary(libPath); - - // verify the loaded version and unload if needed - if (lib) - { - // provision for manual execution of code after loading - if (dlSymFound(lib, globalFuncName)) - { - loaderFunctionType function = - reinterpret_cast<loaderFunctionType> - ( - dlSym(lib, globalFuncName) - ); - - if (function) - { - (*function)(true); // force load - } - else - { - FatalIOErrorIn - ( - "codedFunctionObject::updateLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName - << nl << "from " << libPath << exit(FatalIOError); - } - } - else - { - FatalIOErrorIn - ( - "codedFunctionObject::loadLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName << nl - << "from " << libPath << exit(FatalIOError); - - lib = 0; - if (!libs.close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFunctionObject::loadLibrary()", - contextDict - ) << "Failed unloading library " - << libPath - << exit(FatalIOError); - } - } - } - } - } - - return lib; -} - - -void Foam::codedFunctionObject::unloadLibrary -( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict -) const -{ - void* lib = 0; - - if (libPath.empty()) - { - return; - } - - dlLibraryTable& libs = const_cast<Time&>(time_).libs(); - - lib = libs.findLibrary(libPath); - - if (!lib) - { - return; - } - - // provision for manual execution of code before unloading - if (dlSymFound(lib, globalFuncName)) - { - loaderFunctionType function = - reinterpret_cast<loaderFunctionType> - ( - dlSym(lib, globalFuncName) - ); - - if (function) - { - (*function)(false); // force unload - } - else - { - FatalIOErrorIn - ( - "codedFunctionObject::unloadLibrary()", - contextDict - ) << "Failed looking up symbol " << globalFuncName << nl - << "from " << libPath << exit(FatalIOError); - } - } - - if (!libs.close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFunctionObject::" - "updateLibrary()", - contextDict - ) << "Failed unloading library " << libPath - << exit(FatalIOError); - } -} - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::codedFunctionObject::createLibrary +void Foam::codedFunctionObject::prepare ( dynamicCode& dynCode, const dynamicCodeContext& context ) const { - bool create = Pstream::master(); - - if (create) - { - // Write files for new library - if (!dynCode.upToDate(context)) - { - // filter with this context - dynCode.reset(context); - - // Set additional rewrite rules - dynCode.setFilterVariable("typeName", redirectType_); - dynCode.setFilterVariable("codeRead", codeRead_); - dynCode.setFilterVariable("codeExecute", codeExecute_); - dynCode.setFilterVariable("codeEnd", codeEnd_); - //dynCode.setFilterVariable("codeWrite", codeWrite_); - - // compile filtered C template - dynCode.addCompileFile("functionObjectTemplate.C"); - dynCode.addCompileFile("FilterFunctionObjectTemplate.C"); - - // copy filtered H template - dynCode.addCopyFile("FilterFunctionObjectTemplate.H"); - dynCode.addCopyFile("functionObjectTemplate.H"); - dynCode.addCopyFile("IOfunctionObjectTemplate.H"); - - // debugging: make BC verbose - // dynCode.setFilterVariable("verbose", "true"); - // Info<<"compile " << redirectType_ << " sha1: " - // << context.sha1() << endl; - - // define Make/options - dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); - - if (!dynCode.copyOrCreateFiles(true)) - { - FatalIOErrorIn - ( - "codedFunctionObject::createLibrary(..)", - context.dict() - ) << "Failed writing files for" << nl - << dynCode.libRelPath() << nl - << exit(FatalIOError); - } - } - - if (!dynCode.wmakeLibso()) - { - FatalIOErrorIn - ( - "codedFunctionObject::createLibrary(..)", - context.dict() - ) << "Failed wmake " << dynCode.libRelPath() << nl - << exit(FatalIOError); - } - } - - - // all processes must wait for compile to finish - reduce(create, orOp<bool>()); + // Set additional rewrite rules + dynCode.setFilterVariable("typeName", redirectType_); + dynCode.setFilterVariable("codeRead", codeRead_); + dynCode.setFilterVariable("codeExecute", codeExecute_); + dynCode.setFilterVariable("codeEnd", codeEnd_); + //dynCode.setFilterVariable("codeWrite", codeWrite_); + + // compile filtered C template + dynCode.addCompileFile("functionObjectTemplate.C"); + dynCode.addCompileFile("FilterFunctionObjectTemplate.C"); + + // copy filtered H template + dynCode.addCopyFile("FilterFunctionObjectTemplate.H"); + dynCode.addCopyFile("functionObjectTemplate.H"); + dynCode.addCopyFile("IOfunctionObjectTemplate.H"); + + // debugging: make BC verbose + // dynCode.setFilterVariable("verbose", "true"); + // Info<<"compile " << redirectType_ << " sha1: " + // << context.sha1() << endl; + + // define Make/options + dynCode.setMakeOptions + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + + " -lOpenFOAM \\\n" + + " -lfiniteVolume \\\n" + + context.libs() + ); } -void Foam::codedFunctionObject::updateLibrary() const +Foam::dlLibraryTable& Foam::codedFunctionObject::libs() const { - dynamicCode::checkSecurity - ( - "codedFunctionObject::updateLibrary()", - dict_ - ); - - dynamicCodeContext context(dict_); - - // codeName: redirectType + _<sha1> - // codeDir : redirectType - dynamicCode dynCode - ( - redirectType_ + context.sha1().str(true), - redirectType_ - ); - const fileName libPath = dynCode.libPath(); - + return const_cast<Time&>(time_).libs(); +} - // the correct library was already loaded => we are done - if (const_cast<Time&>(time_).libs().findLibrary(libPath)) - { - return; - } - Info<< "Using dynamicCode for functionObject " << name() - << " at line " << dict_.startLineNumber() - << " in " << dict_.name() << endl; +Foam::string Foam::codedFunctionObject::description() const +{ + return "functionObject " + name(); +} - // remove instantiation of fvPatchField provided by library +void Foam::codedFunctionObject::clearRedirect() const +{ redirectFunctionObjectPtr_.clear(); +} - // may need to unload old library - unloadLibrary - ( - oldLibPath_, - dynamicCode::libraryBaseName(oldLibPath_), - context.dict() - ); - - // try loading an existing library (avoid compilation when possible) - if (!loadLibrary(libPath, dynCode.codeName(), context.dict())) - { - createLibrary(dynCode, context); - - loadLibrary(libPath, dynCode.codeName(), context.dict()); - } - // retain for future reference - oldLibPath_ = libPath; +const Foam::dictionary& Foam::codedFunctionObject::codeDict() const +{ + return dict_; } @@ -323,14 +123,18 @@ Foam::codedFunctionObject::codedFunctionObject ( const word& name, const Time& time, - const dictionary& dict + const dictionary& dict, + bool readNow ) : functionObject(name), - time_(time), - dict_(dict) + codedBase(), + time_(time) { - read(dict_); + if (readNow) + { + read(dict_); + } } @@ -363,21 +167,21 @@ Foam::codedFunctionObject::redirectFunctionObject() const bool Foam::codedFunctionObject::start() { - updateLibrary(); + updateLibrary(redirectType_); return redirectFunctionObject().start(); } bool Foam::codedFunctionObject::execute(const bool forceWrite) { - updateLibrary(); + updateLibrary(redirectType_); return redirectFunctionObject().execute(forceWrite); } bool Foam::codedFunctionObject::end() { - updateLibrary(); + updateLibrary(redirectType_); return redirectFunctionObject().end(); } @@ -440,7 +244,7 @@ bool Foam::codedFunctionObject::read(const dictionary& dict) ); } - updateLibrary(); + updateLibrary(redirectType_); return redirectFunctionObject().read(dict); } diff --git a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H index c950ea2ab6fce7850d7a63ef9f0bb2731377fd59..9f0659ac72dfe044391c7b7c4c59ea02acb1759a 100644 --- a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H +++ b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H @@ -35,30 +35,22 @@ SourceFiles #ifndef codedFunctionObject_H #define codedFunctionObject_H -#include "pointFieldFwd.H" #include "functionObject.H" -#include "dictionary.H" +#include "codedBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -// Forward declaration of classes -class objectRegistry; -class dictionary; -class mapPolyMesh; -class dynamicCode; -class dynamicCodeContext; -class IOdictionary; - /*---------------------------------------------------------------------------*\ Class codedFunctionObject Declaration \*---------------------------------------------------------------------------*/ class codedFunctionObject : - public functionObject + public functionObject, + public codedBase { protected: @@ -76,42 +68,28 @@ protected: string codeExecute_; string codeEnd_; - //- Previously loaded library - mutable fileName oldLibPath_; - //- Underlying functionObject mutable autoPtr<functionObject> redirectFunctionObjectPtr_; - // Private Member Functions - //- Global loader/unloader function type - typedef void (*loaderFunctionType)(bool); + // Protected Member Functions - //- Load specified library and execute globalFuncName(true) - void* loadLibrary - ( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict - ) const; + //- get the loaded dynamic libraries + virtual dlLibraryTable& libs() const; - //- Execute globalFuncName(false) and unload specified library - void unloadLibrary - ( - const fileName& libPath, - const string& globalFuncName, - const dictionary& contextDict - ) const; + //- adapt the context for the current object + virtual void prepare(dynamicCode &,const dynamicCodeContext&) const; + // Return a description (type + name) for the output + virtual string description() const; - //- Create library based on the dynamicCodeContext - void createLibrary(dynamicCode&, const dynamicCodeContext&) const; + // Clear any redirected objects + virtual void clearRedirect() const; - //- Update library as required - void updateLibrary() const; + // Get the dictionary to initialize the codeContext + virtual const dictionary& codeDict() const; - //- Read relevant dictionary entries - void readDict(); +private: //- Disallow default bitwise copy construct codedFunctionObject(const codedFunctionObject&); @@ -134,7 +112,8 @@ public: ( const word& name, const Time& time, - const dictionary& dict + const dictionary& dict, + bool readNow=true // allow child-classes to avoid compilation );