Top Up Prev Next Bottom Contents Index Search

6.2 Class PortHole


PortHole is the means that Blocks use to talk to each other. It is derived from GenericPort; as such, it has a type, an optional alias, and is optionally a member of a ring of ports of the same type connected by typePort pointers. It guarantees that alias() always returns a PortHole. In addition, a PortHole has a peer (another port that it is connected to, which is returned by far()), a Geodesic (a path along which particles travel between the PortHole and its peer), and a Plasma (a pool of particles, all of the same type). In simulation domains, during the execution of the simulation objects known as Particles traverse a circular path: from an output porthole through a Geodesic to an input porthole, and finally to a Plasma, where they are recirculated back to the input porthole. Like all NamedObj-derived objects, a PortHole has a parent Block. It may also be a member of a MultiPortHole, which is a logical group of PortHoles.

6.2.1 PortHole public members

The constructor sets just about everything to null pointers. The destructor disconnects the PortHole, and if there is a parent Block, removes itself from the parent's porthole list.

PortHole& setPort(const char* portName, Block* parent, 
DataType type = FLOAT);
This function sets the name of the porthole, its parent, and its type.

void initialize(); 
This function is responsible for initializing the internal buffers of the porthole in preparation for a run.

virtual void disconnect(int delGeo = 1); 
Remove a connection, and optionally attempt to delete the geodesic. The is set to zero when the geodesic must be preserved for some reason (for example, from the Geodesic's destructor). The Geodesic is deleted only if it is "temporary"; we do not delete "persistent" geodesics when we disconnect them.

PortHole* far() const; 
Return the PortHole we are connected to.

void setAlias (PortHole& blockPort); 
Set my alias to blockPort.

int atBoundary() const; 
Return TRUE if this PortHole is at the wormhole boundary (if its peer is an inter-domain connection); FALSE otherwise.

virtual EventHorizon* asEH(); 
Return myself as an EventHorizon, if I am one. The base class returns a null pointer. EventHorizon objects (objects multiply inherited from EventHorizon and some type of PortHole) will redefine this appropriately.

virtual void receiveData(); 
Used to receive data in derived classes. The default implementation does nothing.

virtual void sendData(); 
Used to send data in derived classes. The default implementation does nothing.

Particle& operator % (int delay); 
This operator returns a reference to a Particle in the PortHole's buffer. A delay value of 0 returns the "newest" particle. In dataflow domains, the argument represents the delay associated with that particular particle.

DataType resolvedType () const; 
Return the data type computed by `PortHole::initialize' to resolve type conversions. For example, if an INT output porthole is connected to a FLOAT input porthole, the resolved type (the type of the Particles that travel between the ports) will be FLOAT. Two connected portholes will always return the same resolvedType. A null pointer will be returned if the type has not yet been resolved, e.g. before initialization.

DataType preferredType () const; 
Return the "preferred" type of the porthole. This is the same as the declared type (GenericPort::type()) if the declared type is not ANYTYPE. If the declared type is ANYTYPE, the preferredType is the type of the connected porthole or type equivalence set from which the ANYTYPE's true type was determined. (If preferredType and resolvedType are not the same, the need for a run-time type conversion is indicated. Code generation domains may choose to splice in type conversion stars to ensure that preferredType and resolvedType are the same at all ports.) A null pointer will be returned if the type has not yet been resolved, e.g. before initialization.

int numXfer() const; 
Returns the nominal number of tokens transferred per execution of the PortHole. It returns the value of the protected member numberTokens.

int numTokens() const; 
Returns the number of particles on my Geodesic.

int numInitDelays() const; 
Returns the number of initial delays on my Geodesic (the initial tokens, strictly speaking, are only delays in dataflow domains).

Geodesic* geo(); 
Return a pointer to my Geodesic.

int index() const; 
Return the index value. This is a mechanism for assigning all the portholes in a universe a unique integer index, for use in table-driven schedulers.

MultiPortHole* getMyMultiPortHole() const; 
Return the MultiPortHole that spawned this PortHole, or NULL if there is no such MultiPortHole.

virtual void setDelay (int newDelayValue); 
Set the delay value for the connection.

virtual Geodesic* allocateGeodesic(); 
Allocate a return a Geodesic compatible with this type of PortHole. This may become a protected member in future Ptolemy releases.

void enableLocking(const PtGate& master);
Enable locking on access to the Geodesic and Plasma. This is appropriate for connections that cross thread boundaries. Assumption: initialize() has been called.

void disableLocking();
The converse.

int isLockEnabled() const;
Returns the lock status.

6.2.2 PortHole protected members

Geodesic* myGeodesic; 
My geodesic, which connects to my peer. Initialized to NULL.

PortHole* farSidePort; 
The port on the far side of the connection. NULL for disconnected ports.

Plasma* myPlasma; 
Pointer to the Plasma where we get our Particles or replace unused Particles. Initialized to NULL.

CircularBuffer* myBuffer; 
Buffer where the Particles are stored. This is actually a buffer of pointers to Particles, not to Particles themselves.

int bufferSize; 
This gives the size of the CircularBuffer to allocate.

int numberTokens;
Number of Particles stored in the buffer each time the Geodesic is accessed. Normally this is one except for dataflow-type stars, where it is the number of Particles consumed or generated.

void getParticle(); 
Get numberTokens particles from the Geodesic and move them into my CircularBuffer. Actually, only Particles move. The same number of existing Particles are returned to their Plasma, so that the total number of Particles contained in the buffer remains constant.

void putParticle(); 
Move numberTokens particles from my CircularBuffer to the Geodesic. Replace them with the same number of Particles from the Plasma.

void clearParticle(); 
Clear numberTokens particles in the CircularBuffer. Leave the buffer position pointing to the last one.

virtual int allocatePlasma();
Allocate Plasma (default method uses global Plasma).

int allocateLocalPlasma();
Alternate function allocates a local Plasma (for use in derived classes).

void deletePlasma();
Delete Plasma if local; detach other end of connection from Plasma as well.

void allocateBuffer();
Allocate new buffer.

DataType SetPreferredType();
Function to determine preferred types during initialization. Returns the preferred type of this porthole, or 0 on failure. Protected, not private, so that subclasses that override setResolvedType() can call it.

6.2.3 CircularBuffer - a class used to implement PortHole

This class is misnamed; it is not a general circular buffer but rather an array of pointers to Particle that is accessed in a circular manner. It has a pointer representing the current position. This pointer can be advanced or backed up; it wraps around the end when this is done. The class also has a facility for keeping track of error conditions. The constructor takes an integer argument, the size of the buffer. It creates an array of pointers of that size and sets them all to null. The destructor returns any Particles in the buffer to their Plasma and then deletes the buffer.

void reset(); 
Set the access pointer to the beginning of the buffer.

void initialize();
Zero out the contents of the buffer.

Particle** here() const; 
Return the access pointer. Note the double indirection; since the buffer contains pointers to Particles, the buffer pointer points to a pointer.

Particle** next(); 
Advance the pointer one position (circularly) and return the new value.

Particle** last(); 
Back up the pointer one position (circularly) and return the new value.

void advance(int n); 
Advance the buffer pointer by n positions. This will not work correctly if n is larger than the buffer size. n is assumed positive.

void backup(int n); 
Back up the buffer pointer by n positions. This will not work correctly if n is larger than the buffer size. n is assumed positive.

Particle** previous(int offset) const; 
Find the position in the buffer offset positions in the past relative to the current position. The current position is unchanged. offset must not be negative, and must be less than the buffer size, or a null pointer is returned an an appropriate error message is set; this message can be accessed by the errMsg function.

int size() const; 
Return the size of the buffer.

static const char* errMsg(); 
Return the last error message (currently, only previous() sets error messages).



Top Up Prev Next Bottom Contents Index Search

Copyright © 1990-1997, University of California. All rights reserved.