00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 #include "PsMultiThreadedPvmController.h" 00019 00020 #include "PsnMultiThreadedAsynchronousScheduler.h" 00021 #include "PsnMultiThreadedScheduler.h" 00022 #include "PsConfigurationParameterDescriptor.h" 00023 #include "PsMultipleConfigurationParameter.h" 00024 #include "PsNoRefCountingNameServer.h" 00025 #include "PsnDescriptorMemoryManager.h" 00026 #include "PsnThreadMemoryManager.h" 00027 #include "PsnSystemMemoryManager.h" 00028 00029 00030 PsMultiThreadedPvmController::PsMultiThreadedPvmController (PsObjectDescriptor & initialObjects, 00031 const PsDate & initialDate, 00032 int argc, 00033 char * argv []) : 00034 PsPvmController(initialObjects, 00035 initialDate, 00036 argc, 00037 argv), 00038 _numberOfThreads (2), 00039 _accessingThread ( 0 ) 00040 { 00041 assert ( _accessingThread != pthread_self() ) ; 00042 00043 if ( getObjectDescriptor().getSchedulingParameters() != NULL ) 00044 { 00045 const PsConfigurationParameterDescriptor * param = getObjectDescriptor().getSchedulingParameters()->getSubDescriptorByName("NumberOfThreads") ; 00046 if (param != NULL ) 00047 { 00048 // if the sheduling parameter named NumberOfThreads if a uniqueConfigurationParameter, then all processes should be spawned with the same number of threads, 00049 //otherwise read the number of threads from the appriate subdescriptor (the one with the name of the process, or default 00050 const PsMultipleConfigurationParameter * complexParam ; 00051 complexParam = dynamic_cast< const PsMultipleConfigurationParameter *> (param) ; 00052 if ( complexParam != NULL ) 00053 { 00054 // a multithreading value could by defined for each process 00055 00056 //find the value for this process 00057 param = complexParam->getSubDescriptorByName (getObjectDescriptor().getProcess().getCString() ) ; 00058 00059 if (param == NULL) 00060 { //no value has been defined for this process 00061 param = complexParam->getSubDescriptorByName ("default") ; 00062 00063 if (param == NULL) 00064 {//no default value has been defined 00065 _numberOfThreads = 2 ; 00066 } 00067 else 00068 {// a default value has been defined 00069 _numberOfThreads = atoi (param->getAssociatedString().c_str() ) ; 00070 } 00071 } 00072 else 00073 {// a value has been defined for this process 00074 _numberOfThreads = atoi (param->getAssociatedString().c_str() ) ; 00075 } 00076 } 00077 else 00078 {// all processes use the same number of threads 00079 _numberOfThreads = atoi (param->getAssociatedString().c_str() ) ; 00080 } 00081 } 00082 } 00083 00084 } 00085 00086 PsMultiThreadedPvmController::~PsMultiThreadedPvmController() { 00087 00088 } 00089 00090 PsnScheduler * PsMultiThreadedPvmController::createScheduler() 00091 { 00092 return new PsnMultiThreadedScheduler( _nbStepsByCycle , _numberOfThreads, true ) ; 00093 } 00094 00095 void PsMultiThreadedPvmController::run () 00096 { 00097 PsnMemoryManager * currentMemoryManager = HeapStackTop::getSystemMemoryManager() ; 00098 00099 assert ( currentMemoryManager != 0 ) ; 00100 00101 // commented out because a thread memory manager doesn't seem performant : confirmed : our implementation performs very poorly compared to the malloc implementation on the demarshalling phase 00102 00103 //size_t initialAllocatatedMemory = 1024 * 1024 ; 00104 00105 //void * startMemory = currentMemoryManager->allocateSizeRemembered ( initialAllocatatedMemory ) ; 00106 00107 //PsnDescriptorMemoryManager * descriptorMemoryManager = new PsnDescriptorMemoryManager ( *currentMemoryManager ) ; 00108 00109 //descriptorMemoryManager->init() ; 00110 00111 //PsnThreadMemoryManager * memoryManagerForThisThread ; 00112 00113 //memoryManagerForThisThread = new PsnThreadMemoryManager ( startMemory, 00114 // initialAllocatatedMemory, 00115 // *currentMemoryManager, 00116 // *descriptorMemoryManager ) ; 00117 //memoryManagerForThisThread -> init() ; 00118 00119 //HeapStackTop allocationContextForThisThread ( memoryManagerForThisThread ) ; 00120 00121 PsPvmController::run() ; 00122 } 00123 00124 00125 PsSimulatedObject * PsMultiThreadedPvmController::getPointerToSimulatedObjectNamed (const PsName & objectName ) 00126 { 00127 00128 PsSimulatedObject * result ; 00129 00130 map<PsName, PsSimulatedObject * >::iterator i = _pointerToObjectCache.find ( objectName ) ; 00131 if ( i != _pointerToObjectCache.end() ) 00132 { 00133 result = i->second ; 00134 } 00135 else 00136 { 00137 _dataLock.protect() ; 00138 i = _addToCache.find (objectName) ; 00139 if ( i != _addToCache.end() ) 00140 { 00141 result = i->second ; 00142 _dataLock.unprotect() ; 00143 } 00144 else 00145 { 00146 if ( _accessingThread == pthread_self() ) 00147 { 00148 _dataLock.unprotect() ; 00149 result = PsPvmController::getPointerToSimulatedObjectNamed ( objectName ) ; 00150 } 00151 else if ( _accessingThread == 0 ) 00152 { 00153 _accessingThread = pthread_self() ; 00154 _dataLock.unprotect() ; 00155 00156 result = PsPvmController::getPointerToSimulatedObjectNamed ( objectName ) ; 00157 00158 _dataLock.protect() ; 00159 _accessingThread = 0 ; 00160 _dataLock.unprotect() ; 00161 _accessCondition.signalChange() ; 00162 } 00163 else 00164 { //other thread is accessing: wait 00165 _accessCondition.waitForChange ( _dataLock ) ; 00166 00167 _dataLock.unprotect() ; 00168 00169 result = getPointerToSimulatedObjectNamed ( objectName ) ; 00170 } 00171 _dataLock.protect() ; 00172 _addToCache.insert ( make_pair(objectName,result) ) ; 00173 _dataLock.unprotect() ; 00174 } 00175 } 00176 return result ; 00177 } 00178 00179 00180 void PsMultiThreadedPvmController::computeNextSimulationStep () 00181 { 00182 _pointerToObjectCache.insert (_addToCache.begin() , _addToCache.end() ) ; 00183 _addToCache.clear() ; 00184 PsPvmController::computeNextSimulationStep () ; 00185 }
| Documentation generated on Mon Nov 25 15:25:00 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |