PCMHost.cpp

Go to the documentation of this file.
00001 //
00002 // This source file is a part of ParCompMark
00003 // Parallel Compositing Benchmark Framework
00004 //
00005 // for latest info see http://parcompmark.sourceforge.net
00006 
00007 //
00008 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00009 // 
00010 // This program is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation; either version 2
00013 // of the License, or (at your option) any later version.
00014 // 
00015 // This program is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 // GNU General Public License for more details.
00019 // 
00020 // You should have received a copy of the GNU General Public License
00021 // along with this program; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023 
00024 //
00025 // Inner includes
00026 //
00027 
00028 #include "../include/PCMHost.h"
00029 
00030 #include "../include/PCMNetClient.h"
00031 
00032 #include "../include/PCMApplication.h"
00033 
00034 #include "../include/PCMStringConverter.h"
00035 
00036 namespace ParCompMark
00037 {
00038 
00039   template <> Host * Singleton < Host >::mInstance = 0;
00040 
00041   //
00042   // Class constants
00043   //
00044 
00045   const std::string Host::HOSTINITNUT = "scripts/framework/host-init.nut";
00046 
00047   //
00048   // Constructors & destructor
00049   //
00050 
00051    Host::Host(const std::string & name, NetClient * netClient)
00052         // You have to initialize the following attributes:
00053         // - mWait
00054         // - mName
00055         // - mSqVM
00056         // - mLowLevelScript
00057         // - mXDisplays
00058         // - mNodes
00059         // - mInitialized
00060         // - mOutputDocument
00061         // - mSessionID
00062         // - mNetClient
00063         // - mEndProcessCount
00064         // - mProcessCount
00065         // - mID
00066         // - mMessageSendingTime
00067   {
00068         mName = name;
00069         mNetClient = netClient;
00070 
00071         mEndProcessCount = IntPointer(new int);
00072          *mEndProcessCount.getPtr() = 0;
00073 
00074         mProcessCount = -1;
00075 
00076         mLowLevelScript = "";
00077 
00078         mInitialized = false;
00079 
00080         mSessionID = 0;
00081 
00082         // Create displays
00083         mXDisplays = new Container < XDisplay, Mutex >;
00084 
00085         Logger::getInstance()->log(Logger::NOTICE, "Host `" + mName + "\' has been created.");
00086   }
00087 
00088  /*----------------------------------------------------------------------*/
00089 
00090   Host::~Host()
00091   {
00092 
00093         if(mInitialized)
00094          finalize();
00095 
00096         mXDisplays.kill();
00097 
00098         Logger::getInstance()->log(Logger::NOTICE, "Host `" + mName + "\' has been destroyed.");
00099 
00100   }
00101 
00102  /*----------------------------------------------------------------------*/
00103 
00104   //
00105   // Class methods
00106   //
00107 
00108   Host *Host::getInstance()
00109   {
00110         return Singleton < Host >::getInstance();
00111   }
00112 
00113  /*----------------------------------------------------------------------*/
00114 
00115   //
00116   // Methods
00117   //
00118 
00119   XDisplay::Pointer Host::openXDisplay(const std::string & displayName)
00120   {
00121         mXDisplays.lock();
00122 
00123         // Return existing opened display
00124         if(mXDisplays->has(displayName))
00125         {
00126          XDisplay::Pointer display(mXDisplays->get(displayName));
00127          mXDisplays.unlock();
00128 
00129          // Initialize if needed
00130          if(!display->getInitialized())
00131                 display->initialize();
00132 
00133          Logger::getInstance()->log(Logger::NOTICE,
00134                                    "Display `" + displayName + "\' has been (re)opened on host `" + mName + "\'.");
00135          return display;
00136         }
00137         // Open new display 
00138         XDisplay::Pointer display(new XDisplay(displayName));
00139         display->initialize();
00140 
00141         mXDisplays->add(displayName, display);
00142         mXDisplays.unlock();
00143 
00144         Logger::getInstance()->log(Logger::NOTICE,
00145                                  "Display `" + displayName + "\' has been created and opened on host `" + mName +
00146                                  "\'.");
00147         return display;
00148   }
00149 
00150  /*----------------------------------------------------------------------*/
00151 
00152   XDisplay::Pointer Host::getFirstXDisplay()
00153   {
00154         Container < XDisplay, Mutex >::Iterator i = mXDisplays->begin();
00155         if(i != mXDisplays->end())
00156          return i->second;
00157         else
00158          return XDisplay::Pointer();
00159   }
00160 
00161  /*----------------------------------------------------------------------*/
00162 
00163   void Host::openXDisplays()
00164   {
00165         // TODO: scan displays
00166         openXDisplay();
00167   }
00168 
00169  /*----------------------------------------------------------------------*/
00170 
00171   void Host::closeXDisplays()
00172   {
00173         for(Container < XDisplay, Mutex >::Iterator i = mXDisplays->begin(); i != mXDisplays->end(); i++)
00174         {
00175          i->second->finalize();
00176         }
00177   }
00178 
00179  /*----------------------------------------------------------------------*/
00180 
00181   void Host::initialize()
00182   {
00183         //Assert(!mInitialized, INVALID_OPERATION_ERROR, "Host::initialize()");
00184 
00185         //fprintf(stderr, "Host init: %s\n", mName.c_str());
00186 
00187         if(mInitialized)
00188          finalize();
00189 
00190         // Create output document
00191         mOutputDocument = new OutputNode("host", OutputNode::INFORMATION);
00192 
00193         //Create nodes
00194         mNodes = new Container < Node, Mutex >;
00195 
00196         // Initialize time correction
00197         Timer::setTimeCorrection(0.0);
00198 
00199         // Automatically scan available X displays on this host and open them.
00200         //openXDisplays();
00201 
00207         // Create session
00208         //if(PCerr err = pcSessionCreate(0) != PC_NO_ERROR)
00209         //Except(INTERNAL_ERROR, "Host::initialize()", pcGetErrorString(err));
00210 
00211         Logger::getInstance()->log(Logger::DEBUG,
00212                                  "Session #" + StringConverter::toString(mSessionID) + " has been created on host `" +
00213                                  mName + "\'.");
00214 
00215         // Initialize host from squirrel
00216         mSqVM = new SqVM("Host-" + mName + "-VM");
00217         mSqVM.lock();
00218         // Load PC API, ParCompMark API, and utils
00219         mSqVM->runScriptFromFile(FileSystemManager::getInstance()->getPathDataFile(Application::PCAPINUT),
00220                                  SqVM::NOMAINMETHOD);
00221         mSqVM->runScriptFromFile(FileSystemManager::getInstance()->getPathDataFile(Application::PARCOMPMARKNUT),
00222                                  SqVM::NOMAINMETHOD);
00223         mSqVM->runScriptFromFile(FileSystemManager::getInstance()->getPathDataFile(Application::UTILSNUT),
00224                                  SqVM::NOMAINMETHOD);
00225 
00226         std::list < std::string > params;
00227         params.push_back(mName);
00228         params.push_back(mLowLevelScript);
00229         mSqVM->runScriptFromFile(FileSystemManager::getInstance()->getPathDataFile(HOSTINITNUT), "main", params);
00230         mSqVM.unlock();
00231 
00232         // Set name in output document
00233         mOutputDocument->setAttribute("name", mName);
00234 
00235         // Initialize nodes
00236         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00237          if(!i->second->getInitialized())
00238                 i->second->initialize();
00239 
00240         mEndProcessCount.lock();
00241         *mEndProcessCount.getPtr() = 0;
00242         mEndProcessCount.unlock();
00243 
00244         mProcessCount = 0;
00245 
00246         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00247          mProcessCount += i->second->getProcesses()->getSize();
00248 
00249         mInitialized = true;
00250 
00251         Logger::getInstance()->log(Logger::DEBUG, "Host `" + mName + "\' has been initialized.");
00252   }
00253 
00254  /*----------------------------------------------------------------------*/
00255 
00256   void Host::finalize()
00257   {
00258         Assert(mInitialized, INVALID_OPERATION_ERROR, "Host::finalize()");
00259 
00260         // Kill nodes
00261         mNodes.kill();
00262 
00263         mSqVM.kill();
00264 
00265         mProcessCount = -1;
00266 
00267         if(mOutputDocument.isNotNull())
00268          mOutputDocument.kill();
00269 
00270         // Close all opened X displays
00271         //closeXDisplays();
00272 
00273         //if(PCerr err = pcSessionDestroy() != PC_NO_ERROR)
00274         //Except(INTERNAL_ERROR, "Host::finalize()", pcGetErrorString(err));
00275 
00284         mInitialized = false;
00285 
00286         Logger::getInstance()->log(Logger::DEBUG, "Host `" + mName + "\' has been finalized.");
00287 
00288   }
00289 
00290  /*----------------------------------------------------------------------*/
00291 
00292   Node *Host::createNode(const char *nodeName)
00293   {
00294         mNodes.lock();
00295 
00296         Node::Pointer node(new Node(nodeName, this));
00297 
00298         mNodes->add(nodeName, node);
00299 
00300         mNodes.unlock();
00301 
00302         return node.getPtr();
00303   }
00304 
00305  /*----------------------------------------------------------------------*/
00306 
00307   void Host::start()
00308   {
00309 
00310         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00311          i->second->start();
00312 
00313         Logger::getInstance()->log(Logger::NOTICE, "Nodes has been started on host `" + mName + "\'.");
00314   }
00315 
00316  /*----------------------------------------------------------------------*/
00317 
00318   u32 Host::stop()
00319   {
00320         u32 result = 0;
00321         u32 u;
00322 
00323         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00324         {
00325          u = i->second->stop();
00326          if(u > result)
00327          {
00328                 result = u;
00329          }
00330         }
00331 
00332         Logger::getInstance()->log(Logger::NOTICE, "Nodes has been stopped on host `" + mName + "\'.");
00333 
00334         return result;
00335   }
00336 
00337  /*----------------------------------------------------------------------*/
00338 
00339   void Host::collectData()
00340   {
00341         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00342         {
00343          i->second->collectData();
00344          mOutputDocument->addChildNode(i->second->getOutputDocument());
00345         }
00346   }
00347 
00348  /*----------------------------------------------------------------------*/
00349 
00350   void Host::setFrameID(const u32 & frameID)
00351   {
00352 
00353         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00354         {
00355          i->second->setFrameID(frameID);
00356         }
00357         for(Container < Node, Mutex >::Iterator i = mNodes->begin(); i != mNodes->end(); i++)
00358 
00359          for(Container < Process, Mutex >::Iterator j = i->second->getProcesses()->begin();
00360                 j != i->second->getProcesses()->end(); j++)
00361          {
00362                 j->second->joinThread();
00363          }
00364 
00365   }
00366 
00367  /*----------------------------------------------------------------------*/
00368 
00369 }