00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef __peoSyncIslandMig_h
00038 #define __peoSyncIslandMig_h
00039
00040
00041 #include <queue>
00042 #include <cassert>
00043
00044 #include <eoPeriodicContinue.h>
00045
00046 #include <utils/eoUpdater.h>
00047
00048 #include <eoContinue.h>
00049 #include <eoSelect.h>
00050 #include <eoReplacement.h>
00051 #include <eoPop.h>
00052
00053 #include "core/topology.h"
00054 #include "core/thread.h"
00055 #include "core/eoPop_comm.h"
00056 #include "core/peo_debug.h"
00057
00058
00060
00142 template< class EOT > class peoSyncIslandMig : public Cooperative, public eoUpdater {
00143
00144 public:
00145
00155 peoSyncIslandMig(
00156 unsigned __frequency,
00157 eoSelect< EOT >& __select,
00158 eoReplacement< EOT >& __replace,
00159 Topology& __topology,
00160 eoPop< EOT >& __source,
00161 eoPop< EOT >& __destination
00162 );
00163
00168 void operator()();
00169
00171 void pack();
00173 void unpack();
00174
00176 void notifySending();
00177
00178
00179 private:
00180
00181 void emigrate();
00182 void immigrate();
00183
00184
00185 private:
00186
00187 eoPeriodicContinue< EOT > cont;
00188 eoSelect< EOT >& select;
00189 eoReplacement< EOT >& replace;
00190 Topology& topology;
00191
00192
00193 eoPop< EOT >& source;
00194 eoPop< EOT >& destination;
00195
00196
00197 std :: queue< eoPop< EOT > > imm;
00198 std :: queue< eoPop< EOT > > em;
00199
00200 std :: queue< Cooperative* > coop_em;
00201
00202 sem_t sync;
00203 };
00204
00205
00206 template< class EOT > peoSyncIslandMig< EOT > :: peoSyncIslandMig(
00207
00208 unsigned __frequency,
00209 eoSelect< EOT >& __select,
00210 eoReplacement< EOT >& __replace,
00211 Topology& __topology,
00212 eoPop< EOT >& __source,
00213 eoPop< EOT >& __destination
00214
00215 ) : cont( __frequency ), select( __select ), replace( __replace ), topology( __topology ), source( __source ), destination( __destination )
00216 {
00217
00218 __topology.add( *this );
00219 sem_init( &sync, 0, 0 );
00220 }
00221
00222
00223 template< class EOT > void peoSyncIslandMig< EOT > :: pack() {
00224
00225 lock(); {
00226
00227 :: pack( coop_em.front()->getKey() );
00228 :: pack( em.front() );
00229 coop_em.pop();
00230 em.pop();
00231 }
00232 unlock();
00233 }
00234
00235
00236 template< class EOT > void peoSyncIslandMig< EOT > :: unpack() {
00237
00238 lock(); {
00239
00240 eoPop< EOT > mig;
00241 :: unpack( mig );
00242 imm.push( mig );
00243 }
00244 unlock();
00245
00246 sem_post( &sync );
00247 }
00248
00249
00250 template< class EOT > void peoSyncIslandMig< EOT > :: emigrate() {
00251
00252 std :: vector< Cooperative* > in, out;
00253 topology.setNeighbors( this, in, out );
00254
00255 for ( unsigned i = 0; i < out.size(); i ++ ) {
00256
00257 eoPop< EOT > mig;
00258 select( source, mig );
00259 em.push( mig );
00260 coop_em.push( out[ i ] );
00261 send( out[ i ] );
00262 printDebugMessage( "sending some emigrants." );
00263 }
00264 }
00265
00266
00267 template< class EOT > void peoSyncIslandMig< EOT > :: immigrate() {
00268
00269 lock(); {
00270
00271 assert( imm.size() );
00272 replace( destination, imm.front() ) ;
00273 imm.pop();
00274 printDebugMessage( "receiving some immigrants." );
00275 }
00276 unlock();
00277 }
00278
00279
00280 template< class EOT > void peoSyncIslandMig< EOT > :: operator()() {
00281
00282 if ( !cont( source ) ) {
00283
00284
00285 emigrate();
00286 stop();
00287
00288
00289 sem_wait( &sync );
00290 getOwner()->setActive();
00291
00292
00293 immigrate();
00294 }
00295 }
00296
00297
00298 template< class EOT > void peoSyncIslandMig< EOT > :: notifySending() {
00299
00300 lock(); {
00301
00302 if ( imm.empty() ) {
00303
00304 printDebugMessage( "entering pasive mode\n" );
00305 getOwner()->setPassive();
00306 }
00307 }
00308 unlock();
00309
00310 resume();
00311 }
00312
00313
00314 #endif