CPPGPGPU Library - Reference (Doxygen)

Main Page | General Use | Reference | Examples Info | Get/Download CPPGPGPU | SF.net Page

DynLoad.cpp

Go to the documentation of this file.
00001 #include "DynLoad.h"
00002 #include <dlfcn.h>
00003 #include <vector>
00004 #include <stdlib.h>
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 
00008 using namespace std;
00009 
00010 
00011 vector < string > gAllObjects;
00012 vector < string > gAllCurFNames;
00013 vector < void * > gAllDLHandles;
00014 
00015 vector < int > gRepCounts;
00016 vector < unsigned > gSecTimes;
00017 
00018 
00019 extern "C"
00020 {
00021 typedef int (*LoaderFunction)();
00022 };
00023 
00024 void * OperatingOldVtable;
00025 
00026 //Returns time of modified file, if file cannot be stat'd, -1U is returned.
00027 unsigned DYFileTime( const string sFileName )
00028 {
00029     struct stat sb;
00030     sb.st_mtime = -1;
00031     stat( sFileName.c_str(), &sb );
00032     return sb.st_mtime;
00033 }
00034 
00035 
00036 bool LoadModule( const string FullModuleName, int iPlace )
00037 {
00038     char buf[1024];
00039     char fname[1024];
00040     sprintf( fname, "%s.%d.sox", FullModuleName.c_str(), gRepCounts[iPlace] );
00041 
00042     //We set this time up here, so if we have a compile error or something, we don't continue to try to work on it.
00043     gSecTimes[iPlace] = DYFileTime( FullModuleName + ".cpp" );
00044 
00045     //XXX: Don't re-soxize if it's our first time. (or it's our first time and the sox file is stale)
00046     if( gRepCounts[iPlace] != 0 || ( gRepCounts[iPlace] == 0 && ( DYFileTime( fname ) < gSecTimes[iPlace] || DYFileTime( fname ) == -1 ) ) )
00047     {
00048         //Compile our file.
00049         snprintf( buf, 1023, "./soxizer %s %d", gAllObjects[iPlace].c_str(), gRepCounts[iPlace] );
00050         printf( "Exec: %s\n", buf );
00051         if( system( buf ) != 0 )
00052         {
00053             printf( "Compiling failed.  Not loading new version.\n" );
00054             return false;
00055         }
00056     }
00057 
00058     //We have to make an "Operating Object" so we know what the vtable of an old object looks like.
00059     {
00060         Node TMPX = NODEMAN->Spawn( gAllObjects[iPlace], "TempObject" );
00061         if( TMPX.Get() )
00062             memcpy( &OperatingOldVtable, TMPX.Get(), sizeof( void* ) );
00063     }
00064 
00065     if( gAllDLHandles[iPlace] )
00066     {
00067         dlclose( gAllDLHandles[iPlace] );
00068         if( gAllCurFNames[iPlace].length() > 0 )
00069         {
00070             snprintf( buf, 1023, "rm %s", gAllCurFNames[iPlace].c_str() );
00071             printf( "Exec: %s\n", buf );
00072             system( buf );
00073         }
00074     }
00075 
00076     gAllCurFNames[iPlace] = fname;
00077     gAllCurFNames[iPlace] = "./" + gAllCurFNames[iPlace];
00078 
00079     gRepCounts[iPlace]++;
00080 
00081     gAllDLHandles[iPlace] = dlopen( gAllCurFNames[iPlace].c_str(), RTLD_NOW | RTLD_GLOBAL );
00082     if( !gAllDLHandles[iPlace] )
00083     {
00084         printf( "Error opening: %s\n", gAllCurFNames[iPlace].c_str() );
00085         return false;
00086     }
00087     LoaderFunction T = (LoaderFunction)dlsym( gAllDLHandles[iPlace], "RegisterAllInShared" );
00088     if( !gAllDLHandles[iPlace] )
00089     {
00090         printf( "Error finding: RegisterallInShareD() in %s\n", gAllCurFNames[iPlace].c_str() );
00091         return false;
00092     }
00093     T();
00094 
00095     return true;
00096 }
00097 
00098 //Tricky -- rotatingly look at only one file per frame.
00099 bool UpdateDynLoad()
00100 {
00101     static unsigned cur = 0;
00102     cur = (cur+1)%gAllObjects.size();
00103 
00104     if( gSecTimes[cur] != DYFileTime( gAllObjects[cur] + ".cpp" ) )
00105     {
00106         LoadModule( gAllObjects[cur], cur );
00107     }
00108 }
00109 
00110 bool InitDynLoad()
00111 {
00112     FILE * f = fopen( "modules.lst", "r" );
00113     if( !f )
00114     {
00115         printf( "Error. could not open modules.lst.\n" );
00116         return false;
00117     }
00118 
00119     while( !feof( f ) && !ferror( f ) )
00120     {
00121         char buffer[128];
00122         fscanf( f, "%127s\n", buffer );
00123         gAllObjects.push_back( buffer );
00124         gAllDLHandles.push_back( 0 );
00125         gAllCurFNames.push_back( "" );
00126         gRepCounts.push_back( 0 );
00127         gSecTimes.push_back( 0 );
00128 
00129         if( !LoadModule( (gAllObjects[gAllObjects.size()-1] ), gAllObjects.size()-1 ) )
00130             return false;
00131     }
00132 
00133     fclose( f );
00134     return true;
00135 }
00136 
00137 void RuntimeRegisterObject( const char * sName, ProducerFunct t )
00138 {
00139     //First, update the current state of things
00140     NodeManager::Instance()->RegisterType( sName, t);
00141 
00142     map< string, NodeObject* > * inst = NodeManager::Instance()->GetObjectInstanceMap();
00143 
00144     //Create an object under this new scheme so we can extract it's vtable for grafting
00145     NodeObject * TempObject = t( "TempObject" );
00146     void * newVTable;
00147     memcpy( &newVTable, TempObject, sizeof( void* ) );
00148     delete TempObject;
00149 
00150     //Last, find any existing objects of that type and
00151     //cut their vtable out.
00152     for( map< string, NodeObject * >::iterator i = inst->begin(); 
00153         i != inst->end(); i++ )
00154     {
00155         if( memcmp( (i->second), &OperatingOldVtable, sizeof( void * ) ) == 0 )
00156             memcpy( (i->second), &newVTable, sizeof( void*) );
00157     }
00158 }
00159 
00160 
00161 
00162 /*
00163 Copyright (c) 2008 Charles Lohr
00164 
00165 Permission is hereby granted, free of charge, to any person obtaining a copy
00166 of this software and associated documentation files (the "Software"), to deal
00167 in the Software without restriction, including without limitation the rights
00168 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00169 copies of the Software, and to permit persons to whom the Software is
00170 furnished to do so, subject to the following conditions:
00171 
00172 The above copyright notice and this permission notice shall be included in
00173 all copies or substantial portions of the Software.
00174 
00175 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00176 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00177 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00178 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00179 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00180 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00181 THE SOFTWARE.
00182 */

© 2005-2007 Charles Lohr, Joshua Allen, David Chapman, Andrew Lohr. All material including documentation under the MIT/X11 license.