00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __peoSyncIslandMig_h
00010 #define __peoSyncIslandMig_h
00011
00012
00013 #include <queue>
00014 #include <cassert>
00015
00016 #include <eoPeriodicContinue.h>
00017
00018 #include <utils/eoUpdater.h>
00019
00020 #include <eoContinue.h>
00021 #include <eoSelect.h>
00022 #include <eoReplacement.h>
00023 #include <eoPop.h>
00024
00025 #include "core/topology.h"
00026 #include "core/thread.h"
00027 #include "core/eoPop_comm.h"
00028 #include "core/peo_debug.h"
00029
00030
00032
00114 template< class EOT > class peoSyncIslandMig : public Cooperative, public eoUpdater {
00115
00116 public:
00117
00127 peoSyncIslandMig(
00128 unsigned __frequency,
00129 eoSelect< EOT >& __select,
00130 eoReplacement< EOT >& __replace,
00131 Topology& __topology,
00132 eoPop< EOT >& __source,
00133 eoPop< EOT >& __destination
00134 );
00135
00140 void operator()();
00141
00143 void pack();
00145 void unpack();
00146
00148 void notifySending();
00149
00150
00151 private:
00152
00153 void emigrate();
00154 void immigrate();
00155
00156
00157 private:
00158
00159 eoPeriodicContinue< EOT > cont;
00160 eoSelect< EOT >& select;
00161 eoReplacement< EOT >& replace;
00162 Topology& topology;
00163
00164
00165 eoPop< EOT >& source;
00166 eoPop< EOT >& destination;
00167
00168
00169 std :: queue< eoPop< EOT > > imm;
00170 std :: queue< eoPop< EOT > > em;
00171
00172 std :: queue< Cooperative* > coop_em;
00173
00174 sem_t sync;
00175 };
00176
00177
00178 template< class EOT > peoSyncIslandMig< EOT > :: peoSyncIslandMig(
00179
00180 unsigned __frequency,
00181 eoSelect< EOT >& __select,
00182 eoReplacement< EOT >& __replace,
00183 Topology& __topology,
00184 eoPop< EOT >& __source,
00185 eoPop< EOT >& __destination
00186
00187 ) : cont( __frequency ), select( __select ), replace( __replace ), topology( __topology ), source( __source ), destination( __destination )
00188 {
00189
00190 __topology.add( *this );
00191 sem_init( &sync, 0, 0 );
00192 }
00193
00194
00195 template< class EOT > void peoSyncIslandMig< EOT > :: pack() {
00196
00197 lock(); {
00198
00199 :: pack( coop_em.front()->getKey() );
00200 :: pack( em.front() );
00201 coop_em.pop();
00202 em.pop();
00203 }
00204 unlock();
00205 }
00206
00207
00208 template< class EOT > void peoSyncIslandMig< EOT > :: unpack() {
00209
00210 lock(); {
00211
00212 eoPop< EOT > mig;
00213 :: unpack( mig );
00214 imm.push( mig );
00215 }
00216 unlock();
00217
00218 sem_post( &sync );
00219 }
00220
00221
00222 template< class EOT > void peoSyncIslandMig< EOT > :: emigrate() {
00223
00224 std :: vector< Cooperative* > in, out;
00225 topology.setNeighbors( this, in, out );
00226
00227 for ( unsigned i = 0; i < out.size(); i ++ ) {
00228
00229 eoPop< EOT > mig;
00230 select( source, mig );
00231 em.push( mig );
00232 coop_em.push( out[ i ] );
00233 send( out[ i ] );
00234 printDebugMessage( "sending some emigrants." );
00235 }
00236 }
00237
00238
00239 template< class EOT > void peoSyncIslandMig< EOT > :: immigrate() {
00240
00241 lock(); {
00242
00243 assert( imm.size() );
00244 replace( destination, imm.front() ) ;
00245 imm.pop();
00246 printDebugMessage( "receiving some immigrants." );
00247 }
00248 unlock();
00249 }
00250
00251
00252 template< class EOT > void peoSyncIslandMig< EOT > :: operator()() {
00253
00254 if ( !cont( source ) ) {
00255
00256
00257 emigrate();
00258 stop();
00259
00260
00261 sem_wait( &sync );
00262 getOwner()->setActive();
00263
00264
00265 immigrate();
00266 }
00267 }
00268
00269
00270 template< class EOT > void peoSyncIslandMig< EOT > :: notifySending() {
00271
00272 lock(); {
00273
00274 if ( imm.empty() ) {
00275
00276 printDebugMessage( "entering pasive mode\n" );
00277 getOwner()->setPassive();
00278 }
00279 }
00280 unlock();
00281
00282 resume();
00283 }
00284
00285
00286 #endif