Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Data Structures   File List   Namespace Members   Data Fields   Globals   Related Pages   Examples  

Parallel.cpp

Multiple (parallel) simulations in one program are introduced.

As shown in the example for simulations inside simulations, it is possible to have multiple simulations in one program. These simulations can be computed one after another or 'parallel'. In this example both situations are presented.

//----------------------------------------------------------------------------
//      Copyright (C) 2002 Humboldt-Universitaet zu Berlin
//
//      This library is free software; you can redistribute it and/or
//      modify it under the terms of the GNU Lesser General Public
//      License as published by the Free Software Foundation; either
//      version 2.1 of the License, or (at your option) any later version.
//
//      This library is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//      Lesser General Public License for more details.
//
//      You should have received a copy of the GNU Lesser General Public
//      License along with this library; if not, write to the Free Software
//      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//----------------------------------------------------------------------------
#include <odemx/base/Process.h>
#include <odemx/synchronization/Waitq.h>

#include <iostream>

using namespace std;
using namespace odemx;

//
// In this example we demonstrate multiple parallel simulations. We have 
// two simulations (SimA and SimB) which are at first computed one after 
// another and then parallel.
//
// SimA contains two processes (Master and Slave) which cooperate through
// an instance of Waitq. Master uses the function 'coopt()' which returns a
// waiting slave. Slave calls the function 'wait()' to show its readiness.
// Both functions block the execution of the active process if an immediate
// interaction between a slave and a master is not possible.
//
class SimA : public Simulation {
        // process types of SimA
        class Master : public Process {
        public:
                Master(SimA* sim) 
                        : Process(sim, "Master") {}

        protected:
                virtual int main() {
                        SimA* sim = dynamic_cast<SimA*>(getSimulation());
                        Slave* s=0;

                        cout << getLabel() << " coopt" << endl;
                        s = dynamic_cast<Slave*>(sim->getQueue()->coopt());

                        //
                        // The function 'activateAfter()' causes the activation
                        // of a process after another.
                        //
                        s->activateAfter(this);

                        cout << getLabel() << " coopt finished" << endl;

                        return 0;
                }
        };

        class Slave : public Process {
        public:
                Slave(SimA* sim) 
                        : Process(sim, "Slave") {}

        protected:
                virtual int main() {
                        SimA* sim = dynamic_cast<SimA*>(getSimulation());

                        cout << getLabel() << " wait" << endl;
                        sim->getQueue()->wait();
                        cout << getLabel() << " wait finished" << endl;

                        return 0;
                }
        };

        Master* m;
        Slave* s;
        Waitq* q;

public:
        SimA(SimulationObserver* o = 0)
                : Simulation("SimA", o), m(0), s(0), q(0) {}

        ~SimA() {
                delete m;
                delete s;
                delete q;
        }

        Waitq* getQueue() {return q;}

protected:
        virtual void initSimulation() {
                m = new Master(this);
                s = new Slave(this);
                q = new Waitq(this, "queue");

                m->activate();
                s->activate();
        }       
};

//
// SimB contains a process called Loop which 10 times writes
// its label and holds for 1 time unit.
//
class SimB : public Simulation {
        // process types of SimA
        class Loop : public Process {
        public:
                Loop(SimB* sim, ProcessObserver* o = 0) 
                        : Process(sim, "Loop", o) {}

        protected:
                virtual int main() {
                        for (int i= 0; i<10; ++i) {
                                cout << getLabel() << i << endl;
                                holdFor(1.0);
                        }

                        return 0;
                }
        };

public:
        SimB(SimulationObserver* o = 0)
                : Simulation("SimB", o), l(0) {}

        ~SimB() {
                delete l;
        }

        Loop* l;

protected:
        virtual void initSimulation() {
                l=new Loop(this);

                l->activate();
        }
};

//
// The main function runs at first a simulation of type SimA,
// than a simulation of type SimB and finally a simulation of
// type SimA parallel to a simulation of type SimB (step by step).
//
int main(int argc, char* argv[]) {
        char c[2];

        //
        // Run simulation of type SimA
        //
        cout << "Part 1" << endl;
        for (int i=0; i<5; ++i) {
                SimA s;
                s.run();
        }
        cout << "Press [Enter] to continue";
        cin.getline(c, 1);

        //
        // Run simulation of type SimB
        //
        cout << endl << "Part 2" << endl;
        {
                SimB s;
                s.run();
        }
        cout << "Press [Enter] to continue";
        cin.getline(c, 1);

        //
        // Run simulations of type SimA and type SimB
        //
        cout << endl << "Part 3" << endl;
        {
                SimA s1;
                SimB s2;

                s1.step();
                s2.step();

                while ( !(s1.isFinished() && s2.isFinished()) ) {

                        if (!s1.isFinished())
                                s1.step();

                        if (!s2.isFinished())
                                s2.step();
                }
        }

        cout << endl << "Finished" << endl;
        return 0;
}


Generated on Mon Aug 11 10:36:06 2003 for ODEMx by doxygen1.3