// ************************************************************** // * * // * Spheres2 -- Example 1 * // * * // * (C) Christian Scheideler, 2003 * // * * // ************************************************************** // Example 1 generates a list of 10 nodes by contacting a node via Any(1) // Special definitions and operations provided by Spheres2.h: // // - Sphere: class that enables non-blocking method invocations (NMI). // To ensure the correct execution of NMIs, every method in a class // derived from Sphere that is to be called by NMI has to have the form // // void MethodName(long time, usertype *plist) // // where plist is a pointer to any kind of usertype. // // - void Send(SpherePtr, Time, SphereObj::Method, ParList): // This requests to call the method SphereObj::Method in the user object // referenced by SpherePtr at time Time, using the parameter list // referenced by ParList. // // - void Register(GID): // This registers a Sphere as a member of group GID // // - void Unregister(GID): // This removes a Sphere from the group GID // // - void Any(GID): // This returns a pointer to any Sphere belonging to group GID // // - void Simulate(Time): // This runs a simulation for Time time steps. // The Spheres.h class provides an environment for the simulation of // concurrent data structures, where concurrent executions are done at the // level of method invocations (i.e. each method invocation completes before // another method is invoked). To avoid inconsistencies in the data structure, // some general rules have to be obeyed: // // - A method may not have any side-effects other than modifying the // data inside the object. // // - A method must be total, meaning that it is well-defined for // EVERY legal state of the object. #include #include #include "Spheres2.h" class Node; // parameter list for connecting nodes class CPList { public: int ID; Node *nodeptr; CPList(int i, Node *n) { ID = i; nodeptr = n; } }; class Node: public Sphere { private: // own ID int ID; // pointers to left and right neighbor Node *lnode; Node *rnode; public: Node(int i) { CPList *pl; ID = i; // set own ID lnode = NULL; rnode = NULL; if (i==0) Register(1); // node 0 registers for GID 1 else { // other nodes try to join group with ID 1 pl = new CPList(ID, this); Send(Any(1), Node::Join, pl); } }; void NewLeft(CPList *p) { lnode = p->nodeptr; cout << ID << ": got new left neighbor from " << p->ID << "\n"; delete p; } void NewRight(CPList *p) { rnode = p->nodeptr; cout << ID << ": got new right neighbor from " << p->ID << "\n"; delete p; } void Join(CPList *p) { CPList *pl; cout << ID << ": welcome, " << p->ID << "\n"; // left neighbor of new node to this node pl = new CPList(ID, this); Send(p->nodeptr, Node::NewLeft, pl); if (rnode != NULL) { // right neighbor of new node to own right neighbor pl = new CPList(ID, rnode); Send(p->nodeptr, Node::NewRight, pl); // left neighbor of own right neighbor to new node pl = new CPList(ID, p->nodeptr); Send(rnode, Node::NewLeft, pl); } // own right neighbor to new node rnode = p->nodeptr; delete p; } }; void main() { int i; // generate array of node objects Node *List[10]; for (i=0; i<10; i++) List[i] = new Node(i); // run the simulation till it terminates Simulate(100); cin >> i; }