Distributed computing JAVA/JSON

profileKailin-an
example.zip

jhpc/error/ErrorLog.java

jhpc/error/ErrorLog.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . error ;

import  java . io . PrintStream ;

/**
 * This class provides a very simple and consistent facility for logging.
 * It will probably be extended to support levels and filtering of certain
 * messages.
 */
public   class   ErrorLog   {
     public   static   final   String  WARNING  =   "Warning" ;
     public   static   final   String  ERROR  =   "Error" ;
     public   static   final   String  FATAL  =   "Fatal Error" ;
     public   static   final   String  INFORMATION  =   "Information" ;

     private   String  className ;
     private   String  funcName ;
     private   String  tag ;
     private   boolean  forceStderr ;
     private   PrintStream  ps ;

     /**
     * create an instance
     *
     *  @param  ps          the stream to use for writing messages
     *  @param  className   the name of the class issuing messages
     *  @param  forceStderr forcibly write all messages to System.err
     */
     public   ErrorLog ( PrintStream  ps ,   String  className ,   boolean  forceStderr )   {
         this . ps  =  ps ;
         this . className  =  className ;
         this . forceStderr  =  forceStderr ;
     }

     /**
     * create an instance
     *
     *  @param  className   the name of the class issuing messages
     *  @param  forceStderr forcibly write all messages to System.err
     */
     public   ErrorLog ( String  className ,   boolean  forceStderr )   {
         this ( System . err ,  className ,  forceStderr );
     }

     /**
     * set the method (or function) name where messages are being issued
     *
     *  @param  funcName name of the method (or function)
     */
     public   void  setFunction ( String  funcName )   {
         this . funcName  =  funcName ;
     }

     /**
     * set a tag so you can easily search for the error with your editor
     *
     *  @param  tag a tag that (hopefully) will be unique
     */
     public   void  setTag ( String  tag )   {
         this . tag  =  tag ;
     }

     /**
     * internal method to print message without new line
     *
     *  @param  message the message to print
     */
     private   void  print ( String  message )   {
        ps . print ( message );
         if   ( ps  !=   System . err )   System . err . print ( message );
     }

     /**
     * internal method to print message with new line
     *
     *  @param  message the message to print
     */
     private   void  println ( String  message )   {
        ps . println ( message );
         if   ( ps  !=   System . err )   System . err . println ( message );
     }

     /**
     * write an error message
     *
     *  @param  type      kind of message (see static constants)
     *  @param  message   the message to be printed
     *  @param  errorCode an exit code (zero is success)
     */
     public   void  error ( String  type ,   String  message ,   int  errorCode )   {
        print ( type );
        print ( ":" );
        print ( className );
         if   ( funcName  !=   null )   {
            print ( "." );
            print ( funcName );
            print ( "(...)" );
         }
         if   ( tag  !=   null )   {
            print ( ":" );
            print ( tag );
            print ( " " );
         }
        println ( message );
         if   ( errorCode  !=   0 )   System . exit ( errorCode );
     }

     public   void  warning ( String  message )   {
        error ( WARNING ,  message ,   0 );
     }

     public   void  information ( String  message )   {
        error ( INFORMATION ,  message ,   0 );
     }

     public   void  nonFatalError ( String  message )   {
        error ( ERROR ,  message ,   0 );
     }

     public   void  fatalError ( String  message )   {
        error ( FATAL ,  message ,   - 1 );
     }

     public   void  fatalError ( String  message ,   int  exitCode )   {
        error ( FATAL ,  message ,  exitCode );
     }
}

jhpc/gmi/00_ChangesFromBookVersion

This is the latest (improved) code for Generic Mailbox Invocations, a messaging framework for Remote Procedure Calls (RPC) with all of the benefits of RMI minus the hacks. This is not intended to be user documentation. This document will probably disappear at some point. This only identifies the recent changes to GMI and what you'll need to do to make GMI and your code coexist happily and merrily. 1. All code is now contained in a package named jhpc.gmi. This package will need to be imported in all code. It is recommended that you make this change immediately and keep the .jar file in your class path. 2. RemoteCallServerDispatcher had a bug. When a remote exception occurred, rather than dying gracefully, the client was left hanging. Needless to say, I should have documented this problem. The new version of this class includes full support for remote exceptions. If you have your own defined exceptions, you should make sure they are Serializable. Remote exceptions are wrapped in a CallMessageException instance, which is returned to the client. This makes it possible to have a remote call that can actually return (and not throw) an Exception or subclass thereof. 3. RemoteCallClient has also been cleaned up to accommodate the new remote exception capability. There are new GMI*Exception classes that will be thrown if a communication failure occurs during the call or the reply. There is also an exception generated if a communication failure occurs during the disconnect operation. 4. An unfortunate consequence of 3 (which you will later agree is a feature) is that you now must put try/catch around remote calls. I wanted to do this a long time ago, and this is just plugging a hole that I knew existed. In case you are wondering why this is a problem, consider the case where a remote call legitimately returns null. The original GMI used null as a flag to indicate general call failure (from the RemoteCallClient point of view.) Now you can rest assured that the return of null is clearly a result, not an exception or an error. I hope this makes sense. 5. The exception architecture for remote calls substantially differs from Java RMI. Regardless of whether your exceptions are local or remote, GMI simply does not care. Everything is an Exception. What I really despise about RMI are all of these kludges that impose an enormous burden on the programmer. GMI encapsulates the ugliness so programmers never have to see it in their code. Interestingly enough, the changes to accommodate exceptions were very straightforward. Since so little code had to be written (and some was even removed), I have taken the opportunity to comment the code, in case you want to understand how GMI works (the comments are placed strategically in the call() and run() methods in RemoteCallClient and RemoteCallServerDispatcher classes, respectively. Enjoy!

jhpc/gmi/Callable.java

jhpc/gmi/Callable.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   interface   Callable   {
     Serializable  call ( CallMessage  message )   throws   Exception ;
}

jhpc/gmi/CallMessage.java

jhpc/gmi/CallMessage.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   abstract   class   CallMessage   implements   Serializable   {
     /**
     * The name of the remote object. This must correspond to the name of
     * an object that was bound and registered.
     */
     protected   String  target ;

     private   String  ticket ;

     /**
     * establish a tag for use in a remote call.
     *
     *  @param  ticket the tag
     */
     public   void  setTicket ( String  ticket )   {
         this . ticket  =  ticket ;
     }

     /**
     * get the tag for a remote call
     */
     public   String  getTicket ()   {
         return  ticket ;
     }

     /**
     * Constructs a Call message with an invocation target in mind.
     *
     *  @param  target the name of a remote object.
     */

     public   CallMessage ( String  target )   {
         this . target  =  target ;
     }

     /**
     * Change the invocation target. This allows a call message to be
     * reused to make multiple calls to different objects.
     *
     *  @param  target the name of a remote object.
     */
     public   void  setTarget ( String  target )   {
         this . target  =  target ;
     }

     /**
     * Get the invocation target. This method cannot be overridden as GMI
     * depends on it to determine the name of the object to be called.
     *
     *  @return  the invocation target.
     */
     public   final   String  getTarget ()   {
         return  target ;
     }

}

jhpc/gmi/CallMessageException.java

jhpc/gmi/CallMessageException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   CallMessageException   extends   CallMessage   implements   Serializable   {

     Serializable  exception ;

     public   CallMessageException ( Exception  e )   {
         super ( null );
         if   ( instanceof   Serializable )
             this . exception  =  e ;
         else
             this . exception  =   new   Exception ( "GMI Remote Exception "   +  e . toString ());
     }

     public   Exception  getException ()   {
         return   ( Exception )  exception ;
     }
}

jhpc/gmi/CallMessageGeneralReply.java

jhpc/gmi/CallMessageGeneralReply.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   CallMessageGeneralReply   extends   CallMessage   implements   Serializable   {

     Serializable  reply ;

     public   CallMessageGeneralReply ( Serializable  reply )   {
         super ( null );
         this . reply  =  reply ;
     }

     public   Serializable  getReply ()   {
         return  reply ;
     }
}

jhpc/gmi/GMICallIssueException.java

jhpc/gmi/GMICallIssueException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   GMICallIssueException   extends   Exception   implements   Serializable   {

     CallMessage  cm ;

     public   GMICallIssueException ( CallMessage  cm )   {
         this . cm  =  cm ;
     }

     public   String  toString ()   {
         return   "GMICallIssueException: could not write CallMessage of type "
                 +  cm . getClass ();
     }
}

jhpc/gmi/GMICallReplyException.java

jhpc/gmi/GMICallReplyException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/

package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   GMICallReplyException   extends   Exception   implements   Serializable   {

     public   String  toString ()   {
         return   "GMICallReplyException: Could not read reply for GMI Call." ;
     }
}

jhpc/gmi/GMIDisconnectException.java

jhpc/gmi/GMIDisconnectException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/

package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   GMIDisconnectException   extends   Exception   implements   Serializable   {

     public   String  toString ()   {
         return   "GMIDisconnectException: Could not disconnect from GMI Server" ;
     }
}

jhpc/gmi/GMINullTargetException.java

jhpc/gmi/GMINullTargetException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   GMINullTargetException   extends   Exception   implements   Serializable   {

     public   String  toString ()   {
         return   "GMINullTargetException: A CallMessage was received with a null invocation target." ;
     }
}

jhpc/gmi/Goodbye.java

jhpc/gmi/Goodbye.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   Goodbye   extends   CallMessage   implements   Serializable   {
     public   Goodbye ()   {
         super ( null );
     }
}


jhpc/gmi/Ok.java

jhpc/gmi/Ok.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . Serializable ;

public   class   Ok   extends   CallMessage   implements   Serializable   {
     private   boolean  ok ;

     public   Ok ()   {
         super ( null );
        ok  =   true ;
     }

     public   Ok ( boolean  ok )   {
         super ( null );
         this . ok  =  ok ;
     }

     public   boolean  isOk ()   {
         return  ok ;
     }

     public   boolean  isNotOk ()   {
         return   ! ok ;
     }
}

jhpc/gmi/RemoteCallAgent.java

jhpc/gmi/RemoteCallAgent.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/

package  info . jhpc . gmi ;

import  info . jhpc . error . ErrorLog ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . ObjectOutputStream ;
import  java . io . OutputStream ;
import  java . net . Socket ;

public   final   class   RemoteCallAgent   extends   Thread   {
     private   Socket  socket ;
     private   ObjectOutputStream  out ;
     private   OutputStream  debug  =   null ;
     private   SharedTableOfQueues  callStore ;
     private   int  unissuedCalls  =   0 ;
     private   boolean  disconnected  =   false ;
     ErrorLog  err  =   new   ErrorLog ( "RemoteCallAgent" ,   false );

     public   RemoteCallAgent ( Socket  socket ,
                            ObjectOutputStream  out ,
                            SharedTableOfQueues  callStore )   {
        err . setFunction ( "RemoteCallAgent" );
        err . setTag ( "1" );
         this . socket  =  socket ;
         this . out  =  out ;
         this . callStore  =  callStore ;
        err . information ( "starting RemoteCallAgent thread" );
         this . start ();
     }

     public   void  setDebug ( OutputStream  debug )   {
         this . debug  =  debug ;
     }

     public   void  call ( CallMessage  message )   throws   Exception   {
         /*
To accompany High-Performance Java Platform(tm) Computing:
Threads and Networking, published by Prentice Hall PTR and
Sun Microsystems Press.

Threads and Networking Library
Copyright (C) 1999-2000
Thomas W. Christopher and George K. Thiruvathukal

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library 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.
*/

        err . setFunction ( "call" );
        err . setTag ( "2" );
         synchronized   ( this )   {
            unissuedCalls ++ ;
            notify ();
         }
        err . information ( "bumped unissued calls to "   +  unissuedCalls );
        callStore . put ( "call" ,  message );
        err . information ( "wrote call to STOQ" );
     }

     public   void  disconnect ()   throws   InterruptedException   {
         synchronized   ( this )   {
            disconnected  =   true ;
            notify ();
         }
         this . join ();
     }

     public   void  run ()   {
        err . setFunction ( "run" );
        err . setTag ( "3" );
         while   ( true )   {
             System . err . println ( "RemoteCallAgent thread" );
             synchronized   ( this )   {
                err . information ( "unissued calls "   +  unissuedCalls );
                err . information ( "disconnected status "   +  disconnected );
                 while   ( unissuedCalls  ==   0   &&   ! disconnected )
                     try   {
                        wait ();
                     }   catch   ( Exception  e )   {
                         System . err . println ( "RemoteCallAgent interrupted unexpectedly" );
                         return ;
                     }
             }
             if   ( unissuedCalls  ==   0   &&  disconnected )
                 break ;

            err . information ( "about to issue a call" );
             CallMessage  message ;
             try   {
                message  =   ( CallMessage )  callStore . get ( "call" );
             }   catch   ( Exception  e )   {
                 System . out . println ( "RemoteCallAgent "   +  e );
                 return ;
             }

            err . information ( "issuing call "   +  message . getTicket ());
             try   {
                out . writeObject ( message );
                out . flush ();
             }   catch   ( Exception  e )   {
                 System . err . println ( "RemoteCallAgent.run(): I/O Exception" );
                 // throw new GMICallIssueException(message);
             }
            err . information ( "call issued "   +  message . getTicket ());

             synchronized   ( this )   {
                unissuedCalls -- ;
                err . information ( "remaining calls = "   +  unissuedCalls );
             }
         }
     }
}






jhpc/gmi/RemoteCallClient.java

jhpc/gmi/RemoteCallClient.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  info . jhpc . error . ErrorLog ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . IOException ;
import  java . io . ObjectInputStream ;
import  java . io . ObjectOutputStream ;
import  java . io . OutputStream ;
import  java . net . Socket ;

public   final   class   RemoteCallClient   {
     private   Socket  socket ;
     private   ObjectOutputStream  out ;
     private   ObjectInputStream  in ;
     private   OutputStream  debug  =   null ;
     private   RemoteCallAgent  callAgent ;
     private   RemoteReplyAgent  replyAgent ;
     private   SharedTableOfQueues  callStore  =   new   SharedTableOfQueues ();
     private   TicketGenerator  ticketGenerator  =   new   TicketGenerator ( "gmi" );
     private   ErrorLog  e  =   new   ErrorLog ( "RemoteCallClient" ,   false );

     public   RemoteCallClient ( String  host ,   int  port )   throws   IOException   {
        socket  =   new   Socket ( host ,  port );
        out  =   new   ObjectOutputStream ( socket . getOutputStream ());
        in  =   new   ObjectInputStream ( socket . getInputStream ());
        e . setFunction ( "RemoteCallClient" );
        e . setTag ( "1" );
        e . information ( "created RemoteCallAgent" );
        callAgent  =   new   RemoteCallAgent ( socket ,  out ,  callStore );
        e . information ( "created RemoteReplyAgent" );
        replyAgent  =   new   RemoteReplyAgent ( socket ,  in ,  callStore );
     }

     public   void  setDebug ( OutputStream  debug )   {
         this . debug  =  debug ;
     }

     public   Object  call ( CallMessage  message )   throws   Exception   {

        e . setFunction ( "call" );
        e . setTag ( "2" );
         String  callTicket  =  ticketGenerator . nextTicket ();
        e . information ( "ticket generated "   +  callTicket );
        message . setTicket ( callTicket );

        e . information ( "added ticket to wait list "   +  callTicket );
         /* inform the reply agent that there is a call about to be made */
        replyAgent . addWaitingTicket ( callTicket );

        e . information ( "issuing GMI call "   +  callTicket );
         /* Make the call. */
        callAgent . call ( message );

        e . information ( "waiting for result of GMI call "   +  callTicket );
         /* await the reply. This could re-throw a remote exception, hence
         * the "throws Exception" above.
         */
         return  replyAgent . getReply ( message );
     }

     public   Object  call ( String  altTarget ,   CallMessage  message )   throws   Exception   {
        message . setTarget ( altTarget );
         return  call ( message );
     }

     public   void  disconnect ()   throws   GMIDisconnectException   {
         try   {
            callAgent . disconnect ();
            replyAgent . disconnect ();
            out . close ();
            in . close ();
            socket . close ();
         }   catch   ( Exception  e )   {
             throw   new   GMIDisconnectException ();
         }
     }
}

jhpc/gmi/RemoteCallServer.java

jhpc/gmi/RemoteCallServer.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;


import  java . io . IOException ;
import  java . net . ServerSocket ;
import  java . net . Socket ;
import  java . util . Hashtable ;

public   class   RemoteCallServer   extends   Thread   {
     private   Hashtable  registeredObjects  =   new   Hashtable ();
     private   ServerSocket  callListener ;

     public   RemoteCallServer ( int  port )   throws   IOException   {
        callListener  =   new   ServerSocket ( port );
         /* user must .start() thread explicitly */
     }

     public   synchronized   void  bind ( String  target ,   Callable  callable )   {
        registeredObjects . put ( target ,  callable );
     }

     public   synchronized   void  unbind ( String  target )   {
        registeredObjects . remove ( target );
     }

     public   synchronized   Callable  lookup ( String  target )   {
         return   ( Callable )  registeredObjects . get ( target );
     }

     /* currently every call will be dispatched as a thread */

     public   void  run ()   {
         while   ( true )   {
             try   {
                 Socket  s  =  callListener . accept ();
                 RemoteCallServerDispatcher  csd  =   new   RemoteCallServerDispatcher ( this ,  s );
                csd . setDaemon ( false );
                csd . start ();
             }   catch   ( Exception  e )   {
                 System . err . println ( "RemoteCallServer: Exception "   +  e );
             }
         }
     }
}

jhpc/gmi/RemoteCallServerDispatcher.java

jhpc/gmi/RemoteCallServerDispatcher.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . io . IOException ;
import  java . io . ObjectInputStream ;
import  java . io . ObjectOutputStream ;
import  java . io . Serializable ;
import  java . net . Socket ;

public   class   RemoteCallServerDispatcher   extends   Thread   {
     RemoteCallServer  callServer ;
     Socket  socket ;
     ObjectInputStream  in ;
     ObjectOutputStream  out ;

     public   RemoteCallServerDispatcher ( RemoteCallServer  callServer ,   Socket  socket )
             throws   IOException   {
         this . callServer  =  callServer ;
         this . socket  =  socket ;
         this . in  =   new   ObjectInputStream ( socket . getInputStream ());
         this . out  =   new   ObjectOutputStream ( socket . getOutputStream ());
     }

     public   void  run ()   {
         while   ( true )   {
             /*
To accompany High-Performance Java Platform(tm) Computing:
Threads and Networking, published by Prentice Hall PTR and
Sun Microsystems Press.

Threads and Networking Library
Copyright (C) 1999-2000
Thomas W. Christopher and George K. Thiruvathukal

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library 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.
*/

             CallMessage  message ;
             String  replyTicket ;

             try   {
                message  =   ( CallMessage )  in . readObject ();
             }   catch   ( Exception  e0 )   {
                 System . err . println ( "GMI Exception: run(): Could not read CallMessage; stream may be corrupted." );
                 break ;
             }

            replyTicket  =  message . getTicket ();
             /*
             * Check whether client wants to disconnect. Goodbye is reserved for this
             * purpose. If Goodbye is received, simply send it back to the client. If
             * for some reason the message cannot be written or the flush fails, it
             * is time to get out anyway, since no more messages will be received.
             */
             if   ( message  instanceof   Goodbye )   {
                 try   {
                    message . setTicket ( replyTicket );
                    out . writeObject ( message );
                    out . flush ();
                 }   catch   ( Exception  e1 )   {
                     System . err . println ( "GMI Exception: run(): e1 = "   +  e1 );
                 }
                 break ;
             }

             /*
             * Find the invocation target. The message contains the name of the
             * invocation target, which must be used to index the list of Callables
             * in the RemoteCallServer that created this RemoteCallServerDispatcher
             * instance.
             */
             Callable  callTarget  =  callServer . lookup ( message . getTarget ());

             /*
             * If the invocation target is null, this means that the client
             * specified the name of an object that is not registered in the
             * list of Callables. This corresponds to the "else" clause.
             *
             * CallMessageException is used so the client can distinguish Exceptions
             * (subclasses of CallMessageException) from normal return values (subclasses
             * of CallMessage). If an exception is thrown when the invocation is
             * performed, the Exception instance is wrapped in a CallMessageException
             * instance and returned.
             */
             Serializable  result ;
             if   ( callTarget  !=   null )   {
                 try   {
                    result  =  callTarget . call ( message );
                 }   catch   ( Exception  e2 )   {
                    result  =   new   CallMessageException ( e2 );
                 }
             }   else   {
                 GMINullTargetException  gmiException  =   new   GMINullTargetException ();
                result  =   new   CallMessageException ( gmiException );
             }

             /*
             * At this point, result refers to either (a) the return value of the
             * invocation or (b) an Exception that was thrown in performing the
             * invocation. In either case, the result is returned. The client will
             * rethrow the exception in the case where a CallMessageException
             * instance is returned.
*
* The result may in fact have been a general Serializable. Since
* I need a CallMessage to encode the replyTicket, the Serializable
* needs to be wrapped in CallMessageGeneralReply.
             */
             try   {
                 CallMessage  resultCM ;
                 if   ( result  instanceof   CallMessage )
                    resultCM  =   ( CallMessage )  result ;
                 else
                    resultCM  =   new   CallMessageGeneralReply ( result );
                resultCM . setTicket ( replyTicket );
                out . writeObject ( result );
                out . flush ();
             }   catch   ( Exception  e3 )   {
                 System . err . println ( "GMI Exception: run(): e3 = "   +  e3 );
             }
         }
         try   {
            out . flush ();
            out . close ();
            in . close ();
            socket . close ();
         }   catch   ( Exception  e4 )   {
             System . err . println ( "GMI Exception: run(): tear down failed (warning)" );
             return ;
         }
     }
}


jhpc/gmi/RemoteReplyAgent.java

jhpc/gmi/RemoteReplyAgent.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  info . jhpc . error . ErrorLog ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . ObjectInputStream ;
import  java . io . OutputStream ;
import  java . net . Socket ;
import  java . util . Vector ;

public   final   class   RemoteReplyAgent   extends   Thread   {
     private   Socket  socket ;
     private   ObjectInputStream  in ;
     private   OutputStream  debug  =   null ;
     private   SharedTableOfQueues  callStore ;
     private   Vector  ticketsAwaited  =   new   Vector ();
     private   boolean  disconnected  =   false ;
     ErrorLog  err  =   new   ErrorLog ( "RemoteReplyAgent" ,   false );


     public   RemoteReplyAgent ( Socket  socket ,
                             ObjectInputStream  in ,
                             SharedTableOfQueues  callStore )   {
        err . setFunction ( "RemoteReplyAgent" );
        err . setTag ( "1" );
         this . socket  =  socket ;
         this . in  =  in ;
         this . callStore  =  callStore ;
        err . information ( "starting RemoteReplyAgent thread" );
         this . start ();
     }

     public   void  setDebug ( OutputStream  debug )   {
         this . debug  =  debug ;
     }

     /*
To accompany High-Performance Java Platform(tm) Computing:
Threads and Networking, published by Prentice Hall PTR and
Sun Microsystems Press.

Threads and Networking Library
Copyright (C) 1999-2000
Thomas W. Christopher and George K. Thiruvathukal

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library 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.
*/

     public   synchronized   void  addWaitingTicket ( String  ticket )   {
        err . setFunction ( "addWaitingTicket" );
        err . setTag ( "2" );
        err . information ( "adding "   +  ticket  +   " to await list" );
        ticketsAwaited . addElement ( ticket );
        err . information ( "await list = "   +  ticketsAwaited . toString ());
        notify ();
     }

     public   Object  getReply ( CallMessage  message )   throws   Exception   {
         String  callTicket  =  message . getTicket ();
         CallMessage  reply  =   ( CallMessage )  callStore . get ( callTicket );
         if   ( reply  instanceof   CallMessageException )   {
             CallMessageException  exceptionInfo  =   ( CallMessageException )  reply ;
             throw  exceptionInfo . getException ();
         }   else   if   ( reply  instanceof   CallMessageGeneralReply )   {
             CallMessageGeneralReply  cmgr  =   ( CallMessageGeneralReply )  reply ;
             return  cmgr . getReply ();
         }   else
             return  reply ;
     }

     public   void  disconnect ()   throws   InterruptedException   {
         synchronized   ( this )   {
            disconnected  =   true ;
            notify ();
         }
         this . join ();
     }

     /*
     * the way this code works is a bit tricky
     * basically, the remote reply agent has to wait for any outstanding call tickets.
     * so we first have to await a condition
     *  either there are more tickets OR a disconnect call has been made
     *  now if a disconnect call has been made, we'll only stop processing replies
     *    when there are no more outstanding tickets
     *  if there are more tickets, we simply get a reply.
     *  the reply can correspond to ANY outstanding ticket.
     *  we remove the ticket for the reply from the list of outstanding tickets.
     *  then we put the reply in the shared table of queues so it can be gotten
     *   (either synchronously or asynchronously)
     */
     public   void  run ()   {
        err . setFunction ( "run" );
        err . setTag ( "3" );
        err . information ( "thread entered" );
         while   ( true )   {
             synchronized   ( this )   {
                err . information ( "# of tickets "   +  ticketsAwaited . size ());
                err . information ( "disconnected status "   +  disconnected );
                 while   ( ticketsAwaited . size ()   ==   0   &&   ! disconnected )   {
                     try   {
                        wait ();
                     }   catch   ( InterruptedException  ie )   {
                         System . err . println ( "RemoteReplyAgent.run()/wait() failed" );
                         return ;
                     }
                 }
             }
             if   ( disconnected  &&  ticketsAwaited . size ()   ==   0 )
                 return ;

            err . information ( "processing reply, # waiting tickets "   +  ticketsAwaited . size ());
             CallMessage  result ;
             try   {
                result  =   ( CallMessage )  in . readObject ();
             }   catch   ( Exception  e )   {
                 System . err . println ( "RemoteReplyAgent.run() I/O error "   +  e );
                 break ;
             }

            err . information ( "reply obtained for ticket "   +  result . getTicket ());
            ticketsAwaited . removeElement ( result . getTicket ());
            err . information ( "new ticket list = "   +  ticketsAwaited . toString ());
            callStore . put ( result . getTicket (),  result );
         }
     }
}



jhpc/gmi/TicketGenerator.java

jhpc/gmi/TicketGenerator.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . gmi ;

import  java . math . BigInteger ;

public   class   TicketGenerator   {

     private   BigInteger  ticket  =   new   BigInteger ( "0" );
     private   BigInteger  unity  =   new   BigInteger ( "1" );
     private   String  prefix ;

     public   TicketGenerator ( String  prefix )   {
         this . prefix  =  prefix ;
     }

     public   String  nextTicket ()   {
         try   {
            ticket  =  ticket . add ( unity );
         }   catch   ( ArithmeticException  e )   {
             System . err . println ( e );
         }
         return  prefix  +  ticket ;
     }

     public   static   class   Test   {
         public   static   void  main ( String  args [])   {
             int  i ;
             TicketGenerator  tg  =   new   TicketGenerator ( "rpc" );
             String  lastTicket  =   null ;
             for   ( =   0 ;  i  <   100000 ;  i ++ )   {
                lastTicket  =  tg . nextTicket ();
             }
             System . out . println ( lastTicket );
         }
     }
}

jhpc/memo/MemoClient.java

jhpc/memo/MemoClient.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . gmi . RemoteCallClient ;

import  java . io . Serializable ;


public   class   MemoClient   {

     RemoteCallClient  rc ;
     String  target ;
     String  host ;
     int  port ;

     public   MemoClient ( String  host ,   int  port ,   String  target )   throws   Exception   {
         this . host  =  host ;
         this . port  =  port ;
         this . rc  =   new   RemoteCallClient ( host ,  port );
         this . target  =  target ;
     }

     public   void  goodbye ()   {
         try   {
            rc . disconnect ();
         }   catch   ( Exception  e )   {
             System . err . println ( "warning: Failed to disconnect from GMI." );
         }
     }

     public   void  setTarget ( String  target )   {
         this . target  =  target ;
     }

     public   Object  get ( Serializable  key )   throws   InterruptedException ,   Exception   {
         MemoGet  mg  =   new   MemoGet ( target ,  key );
         return  rc . call ( mg );
     }

     public   Object  put ( Serializable  key ,   Serializable  value )   throws   Exception   {
         MemoPut  mp  =   new   MemoPut ( target ,  key ,  value );
         return  rc . call ( mp );
     }

     public   Object  getCopy ( Serializable  key )   throws   InterruptedException ,   Exception   {
         MemoGetCopy  mgc  =   new   MemoGetCopy ( target ,  key );
         return  rc . call ( mgc );
     }

     public   Object  getCopySkip ( Serializable  key )   throws   Exception   {
         MemoGetCopySkip  mgcs  =   new   MemoGetCopySkip ( target ,  key );
         return  rc . call ( mgcs );
     }

     public   Object  getSkip ( Serializable  key )   throws   Exception   {
         MemoGetSkip  mgs  =   new   MemoGetSkip ( target ,  key );
         return  rc . call ( mgs );
     }

     public   Object  runDelayed ( Serializable  key ,   Runnable  r )   throws   Exception   {
         if   ( instanceof   Serializable )   {
             Serializable  rs  =   ( Serializable )  r ;
             MemoRunDelayed  mrd  =   new   MemoRunDelayed ( target ,  key ,  rs );
             return  rc . call ( mrd );
         }   else
             throw   new   Exception ( "r must be both Runnable and Serializable" );
     }
}

jhpc/memo/MemoGet.java

jhpc/memo/MemoGet.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

class   MemoGet   extends   MemoMessage   {
     Serializable  key ;

     public   MemoGet ( String  target ,   Serializable  key )   {
         super ( target );
         this . key  =  key ;
     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   throws   Exception   {
         return   ( Serializable )  stoq . get ( key );
     }
}

jhpc/memo/MemoGetCopy.java

jhpc/memo/MemoGetCopy.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

class   MemoGetCopy   extends   MemoMessage   {
     Serializable  key ;

     public   MemoGetCopy ( String  target ,   Serializable  key )   {
         super ( target );
         this . key  =  key ;
     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   throws   Exception   {
         return   ( Serializable )  stoq . look ( key );
     }
}

jhpc/memo/MemoGetCopySkip.java

jhpc/memo/MemoGetCopySkip.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

class   MemoGetCopySkip   extends   MemoMessage   {
     Serializable  key ;

     public   MemoGetCopySkip ( String  target ,   Serializable  key )   {
         super ( target );
         this . key  =  key ;
     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   {
         return   ( Serializable )  stoq . lookSkip ( key );
     }
}

jhpc/memo/MemoGetSkip.java

jhpc/memo/MemoGetSkip.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

class   MemoGetSkip   extends   MemoMessage   {
     Serializable  key ;

     public   MemoGetSkip ( String  target ,   Serializable  key )   {
         super ( target );
         this . key  =  key ;
     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   {
         return   ( Serializable )  stoq . getSkip ( key );
     }
}

jhpc/memo/MemoMessage.java

jhpc/memo/MemoMessage.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . gmi . CallMessage ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

public   abstract   class   MemoMessage   extends   CallMessage   {

     public   MemoMessage ( String  target )   {
         super ( target );
     }

     public   abstract   Serializable  go ( SharedTableOfQueues  stoq )   throws   Exception ;

}

jhpc/memo/MemoPut.java

jhpc/memo/MemoPut.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . gmi . Ok ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

class   MemoPut   extends   MemoMessage   {
     Serializable  key ,  value ;

     public   MemoPut ( String  target ,   Serializable  key ,   Serializable  value )   {
         super ( target );
         this . key  =  key ;
         this . value  =  value ;
     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   {
        stoq . put ( key ,  value );
         return   new   Ok ( true );
     }
}

jhpc/memo/MemoRunDelayed.java

jhpc/memo/MemoRunDelayed.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . gmi . Ok ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

/* I am going to insist that anything being runDelayed is in fact 
 * serializable. At least I will do this when I am about to run the 
 * runnable.
 */

class   MemoRunDelayed   extends   MemoMessage   implements   Runnable   {
     Serializable  key ;
     Serializable  runnable ;

     public   MemoRunDelayed ( String  target ,   Serializable  key ,   Serializable  runnable )   {
         super ( target );
         this . key  =  key ;
         this . runnable  =  runnable ;

     }

     public   Serializable  go ( SharedTableOfQueues  stoq )   {
        stoq . runDelayed ( key ,   this );
         return   new   Ok ( true );
     }

     public   void  run ()   {
         if   ( runnable  instanceof   Runnable )   {
             Runnable  r  =   ( Runnable )  runnable ;
            r . run ();
         }
         // else Exception...
     }
}

jhpc/memo/MemoServer.java

jhpc/memo/MemoServer.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . memo ;

import  info . jhpc . gmi . * ;
import  info . jhpc . thread . SharedTableOfQueues ;

import  java . io . Serializable ;

public   class   MemoServer   implements   Callable   {

     SharedTableOfQueues  stoq  =   new   SharedTableOfQueues ();

     public   Serializable  call ( CallMessage  message )
             throws   Exception   {

         if   ( message  instanceof   MemoMessage )   {
             MemoMessage  mm  =   ( MemoMessage )  message ;
             return  mm . go ( stoq );
         }   else
             return   new   Ok ( false );
     }

     public   static   class   Server   {
         public   static   int  MEMO_DEFAULT_PORT  =   2099 ;
         public   static   int  memoPort ;

         public   static   void  message ( String  message )   {
             System . out . println ( "Memo.Server: "   +  message );
         }

         public   static   void  main ( String  args [])   {
             System . out . println ( "MemoServer version 1.0" );
             System . out . println ( "Copyright (c) 2000, TC, GKT, John, etc." );

             RemoteCallServer  cs ;
             try   {
                memoPort  =   Integer . parseInt ( args [ 0 ]);
             }   catch   ( Exception  e )   {
                memoPort  =  MEMO_DEFAULT_PORT ;
             }

            message ( "running server on "   +  memoPort );
             try   {
                cs  =   new   RemoteCallServer ( memoPort );
             }   catch   ( Exception  e )   {
                 System . err . println ( "" );
                 return ;
             }

            message ( "registering 'memo2000' name for Memo instance" );
             /* create some callables. */
            cs . bind ( "memo" ,   new   MemoServer ());

             /* listen for remote calls */
            message ( "Starting RMI-Lite Listener" );
            cs . start ();
             try   {
                cs . join ();
             }   catch   ( Exception  e )   {
                message ( "could not join() with main thread" );
             }
         }

     }

     public   static   class   SimpleTest1   {

         public   static   void  main ( String  args [])   {
             try   {
                 RemoteCallClient  rc  =   new   RemoteCallClient ( "127.0.0.1" ,   2099 );
                 MemoPut  p  =   new   MemoPut ( "memo2000" ,   "A" ,   "value of A" );
                rc . call ( p );
                 MemoGet  g  =   new   MemoGet ( "memo2000" ,   "A" );
                 System . out . println ( "A -> "   +  rc . call ( g ));
                rc . disconnect ();
             }   catch   ( Exception  e )   {
                 System . err . println ( e );
             }


         }
     }

     public   static   class   WeirdTest1   {

         public   static   void  main ( String  args [])   {
             try   {
                 MemoClient  c1  =   new   MemoClient ( "127.0.0.1" ,   2099 ,   "memo2000" );
                 MemoClient  c2  =   new   MemoClient ( "127.0.0.1" ,   2099 ,   "memo2001" );

                 System . out . println ( "connected to both" );
                c1 . put ( "A" ,   "memo2000:A" );
                 System . out . println ( "put1 " );
                c2 . put ( "A" ,   "memo2001:A" );
                 System . out . println ( "put2 " );
                 System . out . println ( "A @ memo2000 = "   +  c1 . get ( "A" ));
                 System . out . println ( "A @ memo2001 = "   +  c2 . get ( "A" ));
                c1 . goodbye ();
                c2 . goodbye ();
             }   catch   ( Exception  e )   {
                 System . err . println ( e );
             }
         }
     }
}

jhpc/message/Deliverable.java

jhpc/message/Deliverable.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . message ;

public   interface   Deliverable   {
     Message  send ( Message  m );
}

jhpc/message/Message.java

jhpc/message/Message.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . message ;

import  java . io . * ;
import  java . util . Enumeration ;
import  java . util . Hashtable ;

public   class   Message   {
     private   static   boolean  debug  =   true ;
     private   static   int  maxDebugLevel  =   1
             ;
     private   static   final   String  P_STRING  =   "S$" ;
     private   static   final   String  P_INTEGER  =   "I$" ;
     private   static   final   String  P_LONG  =   "L$" ;
     private   static   final   String  P_BOOLEAN  =   "B$" ;

     private   Hashtable  parameters  =   new   Hashtable ();
     private   int  type  =   0 ;
     private   int  tag  =   0 ;
     private   int  length  =   0 ;

     public   Message ()   {
         // nothing additional to do
     }

     public   static   void  log ( int  level ,   String  function ,   String  message )   {
         if   ( debug  &&  level  <=  maxDebugLevel )
             System . out . println ( "Message::"   +  function  +   "> "   +  message );
     }

     public   void  encode ( DataOutputStream  out )   throws   IOException   {
         // output a header
        out . writeUTF ( "SMA" );
         // output length, type, tag
        out . writeInt ( length );
        out . writeInt ( type );
        out . writeInt ( tag );
         // output # of pairs
        out . writeInt ( parameters . size ());
         // output pairs
         Enumeration  e  =  parameters . keys ();
         while   ( e . hasMoreElements ())   {
             String  key  =   ( String )  e . nextElement ();
            out . writeUTF ( key );
             String  value  =   ( String )  parameters . get ( key );
            out . writeUTF ( value );
         }
     }

     public   void  decode ( DataInputStream  in )   throws   IOException   {
         // read header
         String  header  =  in . readUTF ();
         if   ( ! header . equals ( "SMA" ))
             throw   new   IOException ();
         // read length, type, tag
        length  =  in . readInt ();
        type  =  in . readInt ();
        tag  =  in . readInt ();
         int  parameterCount  =  in . readInt ();
         for   ( int  i  =   0 ;  i  <  parameterCount ;  i ++ )   {
             String  key  =  in . readUTF ();
             String  value  =  in . readUTF ();
            parameters . put ( key ,  value );
         }
     }

     public   void  setType ( int  type )   {
         this . type  =  type ;
     }

     public   int  getType ()   {
         return  type ;
     }

     public   void  setTag ( int  tag )   {
         this . tag  =  tag ;
     }

     public   int  getTag ()   {
         return  tag ;
     }

     public   void  setParam ( String  key ,   String  value )   {
        parameters . put ( P_STRING  +  key ,  value );
     }

     public   String  getParam ( String  key )   {
         return   ( String )  parameters . get ( P_STRING  +  key );
     }

     public   void  setStringParam ( String  key ,   String  value )   {
        parameters . put ( P_STRING  +  key ,  value );
     }

     public   String  getStringParam ( String  key )   {
         return   ( String )  parameters . get ( P_STRING  +  key );
     }

     public   void  setIntegerParam ( String  key ,   int  value )   {
        parameters . put ( P_INTEGER  +  key ,  value  +   "" );
     }

     public   int  getIntegerParam ( String  key )   {
         try   {
             return   Integer . parseInt (( String )  parameters . get ( P_INTEGER  +  key ));
         }   catch   ( Exception  e )   {
             return   0 ;   // This cannot happen. I'm just making javac happy.
         }
     }

     public   void  setLongParam ( String  key ,   long  value )   {
        parameters . put ( P_LONG  +  key ,  value  +   "" );
     }

     public   long  getLongParam ( String  key )   {
         try   {
             return   Long . parseLong (( String )  parameters . get ( P_LONG  +  key ));
         }   catch   ( Exception  e )   {
             return   0 ;   // This cannot happen. I'm just making javac happy.
         }
     }

     public   void  setBooleanParam ( String  key ,   boolean  value )   {
        parameters . put ( P_BOOLEAN  +  key ,  value  +   "" );
     }

     public   boolean  getBooleanParam ( String  key )   {
         String  value  =   ( String )  parameters . get ( P_BOOLEAN  +  key );
         return  value . equals ( true   +   "" );
     }

     public   void  merge ( Message  m )   {
         Enumeration  e  =  m . parameters . keys ();
         while   ( e . hasMoreElements ())   {
             Object  key  =  e . nextElement ();
            parameters . put ( key ,  m . parameters . get ( key ));
         }
     }

     public   String  toString ()   {
         String  repAsString  =   "" ;
         return   "Message: type = "   +  type  +   " param = "   +  parameters ;
     }

     public   static   void  main ( String  args [])   {
         Message  m1  =   new   Message ();
         Message  m2  =   new   Message ();
        m1 . setType ( 2 );
        m1 . setTag ( 3 );
        m1 . setStringParam ( "s1" ,   "George" );
        m1 . setBooleanParam ( "b2" ,   true );
        m1 . setIntegerParam ( "i3" ,   100 );
        m1 . setIntegerParam ( "i4" ,   100 );

         try   {
             FileOutputStream  fos  =   new   FileOutputStream ( "m1.dat" );
             DataOutputStream  dos  =   new   DataOutputStream ( fos );
            m1 . encode ( dos );
            fos . close ();
         }   catch   ( Exception  e )   {
             System . out . println ( "exception/m1.dat"   +  e );
         }
         System . out . println ( "Message written to m1.dat" );
         try   {
             FileInputStream  fis  =   new   FileInputStream ( "m1.dat" );
             DataInputStream  dis  =   new   DataInputStream ( fis );
            m2 . decode ( dis );
            fis . close ();
         }   catch   ( Exception  e )   {
             System . out . println ( "exception/m2 "   +  e );
         }
         System . out . println ( "Read m2" );
         System . out . println ( "Message m1 "   +  m1 );
         System . out . println ( "Message m2 "   +  m2 );

     }
}

jhpc/message/MessageClient.java

jhpc/message/MessageClient.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . message ;

import  java . io . DataInputStream ;
import  java . io . DataOutputStream ;
import  java . io . IOException ;
import  java . net . Socket ;

public   class   MessageClient   extends   Thread   {
     Socket  socket ;
     DataOutputStream  out ;
     DataInputStream  in ;

     public   MessageClient ( String  host ,   int  port )   throws   IOException   {
        socket  =   new   Socket ( host ,  port );
        out  =   new   DataOutputStream ( socket . getOutputStream ());
        in  =   new   DataInputStream ( socket . getInputStream ());
     }

     public   Message  call ( Message  message )   {
         try   {
            message . encode ( out );
         }   catch   ( Exception  e )   {
             System . err . println ( "MessageClient: Call (to) failure: "   +  e );
             return   null ;
         }

         try   {
             Message  m  =   new   Message ();
            m . decode ( in );
             return  m ;
         }   catch   ( Exception  e )   {
             System . err . println ( "MessageClient: Call (from) failure: "   +  e );
             return   new   Message ();
         }
     }

     public   void  disconnect ()   {
         Message  m  =   new   Message ();
        m . setType ( 0 );
        m . setParam ( "$disconnect" ,   "$disconnect" );
        call ( m );
         try   {
            socket . close ();
         }   catch   ( Exception  e )   {
             System . err . println ( "ungraceful disconnect on client "   +  e );
         }
     }
}

jhpc/message/MessageServer.java

jhpc/message/MessageServer.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . message ;

/*
 * MessageServer.java - Server for George Method Invocation. A very simple
 * RMI framework for Java in the making.
 */

import  java . io . IOException ;
import  java . net . ServerSocket ;
import  java . net . Socket ;
import  java . util . Hashtable ;

public   class   MessageServer   extends   Thread   {
     private   ServerSocket  callListener ;
     private   Hashtable  subscribers ;

     public   static   final   boolean  logging  =   true ;

     public   void  log ( String  s )   {
         if   ( ! logging )   return ;
         System . err . println ( "MessageServer: "   +  s );
     }

     public   MessageServer ( int  port )   throws   IOException   {
        log ( "Simple Messaging Architecture (SMA) version 1.0" );
        log ( "Copyright (c) 2000, George K. Thiruvathukal" );
        callListener  =   new   ServerSocket ( port );
        subscribers  =   new   Hashtable ();
        log ( "Created MessageServer instance fully!" );
     }

     public   void  subscribe ( int  messageType ,   Deliverable  d )   {
        subscribers . put ( messageType  +   "" ,  d );
     }

     public   Deliverable  getSubscriber ( int  messageType )   {
         return   ( Deliverable )  subscribers . get ( messageType  +   "" );
     }

     public   void  run ()   {
        log ( "MessageServer thread started. run() method dispatched." );
         while   ( true )   {
             try   {
                 Socket  s  =  callListener . accept ();
                 MessageServerDispatcher  csd  =   new   MessageServerDispatcher ( this ,  s );
                csd . setDaemon ( false );
                csd . start ();
             }   catch   ( Exception  e )   {
                log ( "Exception "   +  e );
                e . printStackTrace ();
             }
         }
     }
}

jhpc/message/MessageServerDispatcher.java

jhpc/message/MessageServerDispatcher.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . message ;

import  java . io . DataInputStream ;
import  java . io . DataOutputStream ;
import  java . io . EOFException ;
import  java . io . IOException ;
import  java . net . Socket ;

public   class   MessageServerDispatcher   extends   Thread   {
     MessageServer  callServer ;
     Socket  socket ;
     DataInputStream  in ;
     DataOutputStream  out ;
     public   static   final   boolean  logging  =   true ;


     public   MessageServerDispatcher ( MessageServer  callServer ,   Socket  socket )
             throws   IOException   {
         this . callServer  =  callServer ;
         this . socket  =  socket ;
         this . in  =   new   DataInputStream ( socket . getInputStream ());
         this . out  =   new   DataOutputStream ( socket . getOutputStream ());
     }

     public   void  log ( String  s )   {
         if   ( ! logging )   return ;
         System . err . println ( "MessageServerDispatcher: "   +  s );
     }

     public   void  run ()   {
        log ( "Beginning of dispatch run() method." );
         try   {
             while   ( true )   {
                 Message  m  =   new   Message ();
                m . decode ( in );
                 Message  result  =   null ;
                log ( "Received Message "   +  m  +   "." );
                 if   ( m . getType ()   ==   0   &&  m . getParam ( "$disconnect" )   !=   null )   {
                    log ( "Message found with reserved $disconnect parameter." );
                     System . err . println ( "-> Disconnect received by server." );
                     Message  ack  =   new   Message ();
                    ack . encode ( out );
                    socket . close ();
                     return ;
                 }
                 Deliverable  d  =  callServer . getSubscriber ( m . getType ());
                 if   ( !=   null )
                    result  =  d . send ( m );
                 else   {
                     System . err . println ( "-> No subscribers for this message." );
                    result  =   new   Message ();
                 }
                result . encode ( out );
             }
         }   catch   ( EOFException  e1 )   {
             try   {
                log ( "End of file exception."   +  e1 );
                out . close ();
                socket . close ();
             }   catch   ( Exception  e2 )   {
                log ( "Unable to free open resources "   +  e2 );
                e2 . printStackTrace ();
             }
         }   catch   ( Exception  e )   {
            log ( "Unknown exception of unknown origin. Possibly a bug: "   +  e );
            e . printStackTrace ();
         }
     }
}

jhpc/text/Splitter.java

jhpc/text/Splitter.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . text ;

import  java . util . StringTokenizer ;
import  java . util . Vector ;

public   class   Splitter   {

     private   String  text ;
     private   String  delimiters ;
     private   Vector  tokens ;
     private   StringTokenizer  tokenizer ;
     private   String  labels [];

     public   Splitter ( String []  labels ,   String  text ,   String  delimiters )   {
         this . text  =  text ;
         this . delimiters  =  delimiters ;
        tokens  =   new   Vector ();
        tokenizer  =   null ;
         this . labels  =  labels ;
        performSplit ();
     }

     public   Splitter ( String  text ,   String  delimiters )   {
         this ( new   String [ 0 ],  text ,  delimiters );
     }

     public   Splitter ( String []  labels ,   String  delimiters )   {
         String  defaultText  =   "" ;
         for   ( int  i  =   0 ;  i  <  labels . length ;  i ++ )   {
            defaultText  +=  labels [ i ];
            defaultText  +=  delimiters . charAt ( 0 );
         }
         this . text  =  defaultText ;
         this . delimiters  =  delimiters ;
        tokens  =   new   Vector ();
        tokenizer  =   null ;
         this . labels  =  labels ;
        performSplit ();
     }

     public   void  setText ( String  text )   {
         this . text  =  text ;
        performSplit ();
     }

     public   void  setDelimiters ( String  delimiters )   {
         this . delimiters  =  delimiters ;
        performSplit ();
     }

     public   void  setTextAndDelimiters ( String  text ,   String  delimiters )   {
         this . text  =  text ;
         this . delimiters  =  delimiters ;
        performSplit ();
     }

     public   void  setLabels ( String []  labels )   {
         this . labels  =  labels ;
     }

     public   String  getLabel ( int  index )   {
         if   ( labels  ==   null   ||  index  <   0   ||  index  >=  labels . length )
             return  index  +   "" ;
         else
             return  labels [ index ];
     }

     private   void  performSplit ()   {
        tokenizer  =   new   StringTokenizer ( text ,  delimiters );
        tokens . removeAllElements ();
         while   ( tokenizer . hasMoreTokens ())   {
            tokens . addElement ( tokenizer . nextToken ());
         }
     }

     public   int  getTokenCount ()   {
         return  tokens . size ();
     }

     public   String  getTokenAt ( int  position )   {
         if   ( position  >=   0   &&  position  <  tokens . size ())
             return   ( String )  tokens . elementAt ( position );
         else
             return   null ;
     }

     public   String  getTokenAt ( String  label )   {
         int  index  =  findLabel ( label );
         if   ( index  <   0 )   {
             try   {
                index  =   Integer . parseInt ( label );
             }   catch   ( NumberFormatException  e )   {
                 return   null ;
             }
         }
         return  getTokenAt ( index );
     }

     private   int  findLabel ( String  label )   {
         int  index ;
         for   ( index  =   0 ;  index  <  labels . length ;  index ++ )
             if   ( label . equals ( labels [ index ]))
                 return  index ;
         return   - 1 ;
     }

     public   Vector  getAllTokens ()   {
         return  tokens ;
     }

     public   void  setTokenAt ( String  text ,   int  position )   {
        tokens . setElementAt ( text ,  position );
     }

     public   String  toString ()   {
         int  i ;
         String  s  =   "" ;

         for   ( =   0 ;  i  <  getTokenCount ();  i ++ )   {
             if   ( >   0 )
                s  =  s  +   "\n" ;

            s  =  s  +   "["   +  getLabel ( i )   +   "] = "   +  getTokenAt ( i );
         }
         return  s ;
     }

     public   static   void  main ( String []  args )   {
         String []  labels  =   { "username" ,   "password" ,   "home dir" ,   "shell" };
         Splitter  s  =   new   Splitter ( "gkt:X8kk43jkjs:/home/people/gkt:/bin/ksh" ,   ":" );
        s . setLabels ( labels );

         /* setLabels labelled the fields for us, "username" refers to field 0 */
         System . out . println ( "username = "   +  s . getTokenAt ( "username" ));

         /* the password is in field number 1 (0 represents the first field) */
         System . out . println ( "password = "   +  s . getTokenAt ( 1 ));

         /* inevitably, people will want to be able to put a numbered field reference
           in a string. this will work provided the field has not been labelled
           by setLabels with numbers */
         System . out . println ( "home dir = "   +  s . getTokenAt ( "2" ));

         /* a null reference is returned if a label has not been defined but used */
         System . out . println ( "bad ref \"bad\" = "   +  s . getTokenAt ( "bad" ));

         /* similar story for out of bounds field reference */
         System . out . println ( "bad ref (500) = "   +  s . getTokenAt ( 500 ));
         System . out . println ( "all tokens (gkt) = "   +  s );

        s . setText ( "tc:X4kkjk3jkjs:/home/people/tc:/bin/csh" );
         System . out . println ( "all tokens (tc) = "   +  s );
     }
}

jhpc/thread/Accumulator.java

jhpc/thread/Accumulator.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Allows multiple threads and runnables to wait for a number of tasks
 * to be completed before proceeding.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   class   Accumulator   implements   RunDelayed   {


     /**
     */

     protected   Future  future ;

     /**
     */

     protected   int  count ;

     /**
     */

     protected   Object  data ;

     /**
     * Creates an Accumulator which will wait for n completions.
     *
     *  @param  n total number of threads that must gather.
     */

     public   Accumulator ( int  n )   {
         this ( n ,   null ,   new   Future ());
     }

     /**
     * Creates an Accumulator which will wait for n completions before
     * placing data in Future f.
     *
     *  @param  n    total number of completions required.
     *  @param  data value to be placed in the future. It can be updated.
     *  @param  f    future to be set to data when the number of completions
     *             have occurred.
     */

     public   Accumulator ( int  n ,   Object  data ,   Future  f )   {
        count  =  n ;
         this . data  =  data ;
        future  =  f ;
         if   ( count  <=   0 )  future . setValue ( data );
     }

     /**
     * Creates an Accumulator which will wait for n completions before
     * placing data in Future f.
     *
     *  @param  n    total number of completions required.
     *  @param  data value to be placed in the future. It can be updated.
     */

     public   Accumulator ( int  n ,   Object  data )   {
         this ( n ,  data ,   new   Future ());
     }

     /**
     * Is called by a thread or chore to signal that it's operation
     * on the accumulator is complete. The nth of these signals
     * will place the contants of the Accumulator's data field in
     * its future.
     */
     public   synchronized   void  signal ()   {
         if   ( -- count  ==   0 )  future . setValue ( data );
     }

     /**
     * Get the data object.
     *
     *  @return  The data object that will be placed in the future upon
     *         the proper number of completions.
     */

     public   Object  getData ()   {
         return  data ;
     }

     /**
     * Get the Future to be set upon the correct number of signals.
     *
     *  @return  The Future.
     */

     public   Future  getFuture ()   {
         return  future ;
     }

     /**
     * Set the data object.
     *
     *  @param  val A data object that will be placed in the future upon
     *            the proper number of completions.
     */

     public   void  setData ( Object  val )   {
        data  =  val ;
     }

     /**
     * Delay the runnable r until all elements of the group
     * have terminated.
     *
     *  @param  r The runnable to be delayed.
     */

     public   void  runDelayed ( Runnable  r )   {
        future . runDelayed ( r );
     }
}



jhpc/thread/AccumulatorFactory.java

jhpc/thread/AccumulatorFactory.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Factory to create Accumulator objects for a shared memory system.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   AccumulatorFactory   {


     /**
     * The FutureFactory to create Futures for Accumulators.
     */

     protected   FutureFactory  futureFactory  =   null ;

     /**
     * Create a AccumulatorFactory.
     *
     *  @param  futureFactory The FutureFactory to create futures.
     */

     public   AccumulatorFactory ( FutureFactory  futureFactory )   {
         super ();
         this . futureFactory  =  futureFactory ;
     }

     /**
     * Get the FutureFactory for a AccumulatorFactory object.
     *
     *  @return  The FutureFactory that will create a Future object for aa
     *         Accumulator.
     */

     public   FutureFactory  getFutureFactory ()   {
         return  futureFactory ;
     }

     /**
     * Set the FutureFactory for a AccumulatorFactory object.
     */

     public   void  setFutureFactory ( FutureFactory  futureFactory )   {
         this . futureFactory  =  futureFactory ;
     }

     /**
     * Create a Accumulator awaiting n signals.
     *
     *  @param  n The number of signals expected.
     *  @return  The Accumulator.
     */

     public   Accumulator  make ( int  n )   {
         return   new   Accumulator ( n ,   null ,  futureFactory . make ());
     }

     /**
     * Create a Accumulator awaiting n signals.
     *
     *  @param  n    The number of signals expected.
     *  @param  data The initial value for accumulation.
     *  @return  The Accumulator.
     */

     public   Accumulator  make ( int  n ,   Object  data )   {
         return   new   Accumulator ( n ,  data ,  futureFactory . make ());
     }
}

jhpc/thread/Barrier.java

jhpc/thread/Barrier.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Stack ;

/**
 * Allows multiple threads and runnables to gather at a
 * point before proceeding.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   class   Barrier   extends   SimpleBarrier   implements   RunDelayed   {

     /**
     * The Stack containing waiting Runnables. (Stack so its quick and easy to
     * have them wait and to remove them.)
     */

     protected   Stack  runnablesWaiting  =   null ; //new Stack();//

     /**
     * The default queue into which to put (runDelayed) runnables that are
     * waiting on any of these Barriers. The limit on the number
     * of threads that can be running the (runDelayed) objects is the
     * amount of memory available. The (runDelayed) objects are placed
     * in this queue by default when a Future is given a value.
     */

     protected   static   RunQueue  classRunQueue  =
             new   RunQueue ();

     /**
     * The queue into which to put (runDelayed) runnables that are
     * waiting on this Barrier. The limit on the number
     * of threads that can be running the (runDelayed) objects is the
     * amount of memory available. They are placed in the queue when
     * the Future is given a value.
     */

     protected   RunQueue  runQueue  =  classRunQueue ;

     /**
     * Creates a Barrier at which n Threads or Runnables may repeatedly
     * gather.
     *
     *  @param  n total number of threads that must gather.
     */

     public   Barrier ( int  n )   {
         super ( n );
     }

     /**
     * Is called by a thread to wait for the rest of the n Threads or
     * Runnables to gather before the set of threads or runnables may
     * continue executing.
     *
     *  @throws  InterruptedException If interrupted while waiting.
     */
     public   synchronized   void  gather ()
             throws   InterruptedException   {
         if   ( -- count  >   0 )
            wait ();
         else   {
            releaseRunnables ();
            count  =  initCount ;
            notifyAll ();
         }
     }

     /**
     * Is a non-delaying version of gather().
     */
     public   synchronized   void  signal ()   {
         if   ( -- count  ==   0 )   {
            releaseRunnables ();
            count  =  initCount ;
            notifyAll ();
         }
     }

     protected   void  releaseRunnables ()   {
         RunQueue  q  =  getRunQueue ();
         if   ( runnablesWaiting  !=   null )   {
             while   ( ! runnablesWaiting . empty ())   {
                q . run (( Runnable )  runnablesWaiting . pop ());
             }
             //runnablesWaiting=null;
         }
     }

     /**
     * Get the RunQueue for a Barrier object. The run queue should be
     * changed with setRunQueue for more precise control.
     *
     *  @return  The RunQueue that objects runDelayed on a Barrier object
     *         will be  placed in.
     */

     public   RunQueue  getRunQueue ()   {
         return  runQueue ;
     }

     /**
     * Set the RunQueue for a Barrier object.
     */

     public   void  setRunQueue ( RunQueue  rq )   {
        runQueue  =  rq ;
     }

     /**
     * Get the RunQueue for the Barrier class.
     *
     *  @return  The RunQueue that  objects runDelayed on a pure Future
     *         will be placed in.
     */

     public   static   RunQueue  getClassRunQueue ()   {
         return  classRunQueue ;
     }

     /**
     * Schedule a runnable object to execute when the Barrier has
     * gathered the correct number of threads or runnables.
     */

     public   synchronized   void  runDelayed ( Runnable  r )   {
         if   ( -- count  >   0 )   {
             if   ( runnablesWaiting  ==   null )   {
                runnablesWaiting  =   new   Stack ();
             }
            runnablesWaiting . push ( r );
         }   else   {
            releaseRunnables ();
            count  =  initCount ;
            notifyAll ();
            getRunQueue (). run ( r );
         }
     }
}



jhpc/thread/BarrierFactory.java

jhpc/thread/BarrierFactory.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Factory to create Barriers. Barriers allows multiple threads and
 * runnables to gather at a point before proceeding.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   class   BarrierFactory   {

     /**
     * The RunQueue for the Barriers created.
     */

     protected   RunQueue  rq  =   null ;

     /**
     * Create a BarrierFactory.
     *
     *  @param  rq The RunQueue to run any synchronized Runnables in.
     */

     public   BarrierFactory ( RunQueue  rq )   {
         super ();
         this . rq  =  rq ;
     }

     /**
     * Get the RunQueue for a BarrierFactory object.
     *
     *  @return  The RunQueue where runDelayed Runnables will be run.
     */

     public   RunQueue  getRunQueue ()   {
         return  rq ;
     }

     /**
     * Set the RunQueue for a BarrierFactory object.
     */

     public   void  setRunQueue ( RunQueue  rq )   {
         this . rq  =  rq ;
     }

     /**
     * Create a Barrier.
     */

     public   Barrier  make ( int  n )   {
         Barrier  b  =   new   Barrier ( n );
        b . setRunQueue ( rq );
         return  b ;
     }
}

jhpc/thread/DynAlloc.java

jhpc/thread/DynAlloc.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * A root class for classes that dynamicly allocate
 * blocks of numbers out of a contiguous range. This is used
 * by parallel threads to allocate loop indices to use, e.g.
 * for processing elements of an array in parallel.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   abstract   class   DynAlloc   {
     /**
     * A Range object indicates the block of numbers
     * that are allocated. The numbers go from start up to
     * but not including end.
     */
     public   static   class   Range   {
         /**
         * The initial value in the range.
         */
         public   int  start ;
         /**
         * The value just beyond the end of the range.
         */
         public   int  end ;
         /**
         * The number of values in the range, end-start.
         */
         public   int  num ;
     }

     /**
     * Allocate a new range. The information on the range of values
     * is filled into the range parameter, r.
     *
     *  @param  r The Range object that has the bounds of the allocated
     *          range filled in.
     *  @return  true if the range is non-empty, false if all the
     *         range has been allocated.
     */
     public   abstract   boolean  alloc ( Range  r );
}

jhpc/thread/DynAllocShare.java

jhpc/thread/DynAllocShare.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * A DynAlloc subclass to dynamicly allocate
 * blocks of numbers out of a contiguous range. This is used
 * by shared-memory parallel threads to allocate loop
 * indices to use, e.g. for processing elements of an array
 * in parallel.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2
 */
public   class   DynAllocShare   extends   DynAlloc   {
     int  range ;
     int  nt ;
     int  min ;
     int  zc ;
     int  current ;

     /**
     * Create a DynAllocShare object that will allocate
     * blocks of numbers in the range [0..range) for nt
     * parallel threads. It will allocate no fewer than min
     * numbers in a block until the last allocation.
     * It tries to allocate max(remaining/nt,min) numbers to
     * each thread. After nt threads have been told that there
     * are no numbers left to allocate, the DynAllocShare object
     * will automatically reset and start allocating blocks of
     * numbers out of the full range again. This is to tell each
     * of the threads that they are done with one iteration of
     * a loop so they can gather at a barrier and start the next
     * iteration without having to create or explicitly reset the
     * DynAllocShare object.
     *
     *  @param  range Non-inclusive upper bound. Numbers [0,range)
     *              are allocated.
     *  @param  nt    The number of threads allocating ranges from this
     *              DynAllocShare object.
     *  @param  min   The minimum number of numbers to allocate at a
     *              time, except the last allocation.
     */
     public   DynAllocShare ( int  range ,   int  nt ,   int  min )   {
         this . range  =  range ;
         this . nt  =  nt ;
         this . min  =  min ;
        zc  =   0 ;
        current  =   0 ;
     }

     /**
     * Allocate a new range. The information on the range of values
     * is filled into the range parameter, r.
     *
     *  @param  r The Range object that has the bounds of the allocated
     *          range filled in.
     *  @return  true if the range is non-empty, false if all the
     *         range has been allocated.
     */
     public   synchronized   boolean  alloc ( Range  r )   {
         if   ( current  >=  range )   {
            zc ++ ;
             if   ( zc  >=  nt )   {
                current  =   0 ;
                zc  =   0 ;
             }
            r . start  =  r . end  =  range ;
            r . num  =   0 ;
             return   false ;
         }
        r . start  =  current ;
         int  rem  =  range  -  current ;
         int  num  =   ( rem  +  nt  -   1 )   /  nt ; //ceiling(rem/nt)
         if   ( num  <  min )  num  =  min ;
         if   ( num  >  rem )  num  =  rem ;
        current  +=  num ;
        r . end  =  current ;
        r . num  =  num ;
         return   true ;
     }
}

jhpc/thread/EmptyQueueException.java

jhpc/thread/EmptyQueueException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Exception thrown if a get() method is called on an
 * empty QueueComponent.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   class   EmptyQueueException   extends   RuntimeException   {
     public   EmptyQueueException ()   {
         super ( "get() from an empty queue" );
     }
}

jhpc/thread/Future.java

jhpc/thread/Future.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Stack ;

/**
 * An assign-once variable that allows consumers to wait for a value to be produced.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   Future   extends   SimpleFuture   implements   RunDelayed   {

     /**
     * The Stack containing waiting Runnables. (Stack so its quick and easy to
     * have them wait and to remove them.)
     */

     protected   Stack  runnablesWaiting  =   null ;

     /**
     * The default queue into which to put (runDelayed) runnables that are
     * waiting on any of these Futures. The limit on the number
     * of threads that can be running the (runDelayed) objects is the
     * amount of memory available. The (runDelayed) objects are placed
     * in this queue by default when a Future is given a value.
     */

     protected   static   RunQueue  classRunQueue  =
             new   RunQueue ();

     /**
     * The queue into which to put (runDelayed) runnables that are
     * waiting on this Future. The limit on the number
     * of threads that can be running the (runDelayed) objects is the
     * amount of memory available. They are placed in the queue when
     * the Future is given a value.
     */

     protected   RunQueue  runQueue  =  classRunQueue ;

     /**
     * Create a Future with no value yet assigned.
     */

     public   Future ()   {
         super ();
     }

     /**
     * Create a Future with a value initially assigned.
     *
     *  @param  val The value the Future is to be initialized with.
     */

     public   Future ( Object  val )   {
         super ( val );
     }

     /**
     * Assigns a value to the Future and notifies all waiting threads.
     * Attempts to change a previously assigned value will be ignored.
     *
     *  @param  val The value to be assigned to the Future.
     */

     public   synchronized   void  setValue ( Object  val )   {
         super . setValue ( val );
         if   ( runnablesWaiting  !=   null )   {
             while   ( ! runnablesWaiting . empty ())   {
                getRunQueue (). run (( Runnable )  runnablesWaiting . pop ());
             }
            runnablesWaiting  =   null ;
         }
     }

     /**
     * Get the RunQueue for a Future object. The run queue should be
     * changed with setRunQueue for more precise control.
     *
     *  @return  The RunQueue that objects runDelayed on a Future object
     *         will be  placed in.
     */

     public   RunQueue  getRunQueue ()   {
         return  runQueue ;
     }

     /**
     * Set the RunQueue for a Future object.
     */

     public   void  setRunQueue ( RunQueue  rq )   {
        runQueue  =  rq ;
     }

     /**
     * Get the RunQueue for the Future class.
     *
     *  @return  The RunQueue that  objects runDelayed on a pure Future
     *         will be placed in.
     */

     public   static   RunQueue  getClassRunQueue ()   {
         return  classRunQueue ;
     }

     /**
     * Schedule a runnable object to execute when the Future has
     * its value set.
     */

     public   synchronized   void  runDelayed ( Runnable  r )   {
         if   ( value  !=   this )
            runQueue . run ( r );
         else   {
             if   ( runnablesWaiting  ==   null )
                runnablesWaiting  =   new   Stack ();
            runnablesWaiting . push ( r );
         }
     }
}

jhpc/thread/FutureFactory.java

jhpc/thread/FutureFactory.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * A factory to create assign-once variables that allows consumers to
 * wait for a value to be produced.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   FutureFactory   {


     /**
     * The queue into which to put (runDelayed) runnables that are
     * waiting on this Future. The limit on the number
     * of threads that can be running the (runDelayed) objects is the
     * amount of memory available. They are placed in the queue when
     * the Future is given a value.
     */

     protected   RunQueue  runQueue  =   null ;

     /**
     * Create a FutureFactory.
     *
     *  @param  runQueue The run queue into which all created futures
     *                 will deposit Runnables.
     */

     public   FutureFactory ( RunQueue  runQueue )   {
         super ();
         this . runQueue  =  runQueue ;
     }

     /**
     * Create a FutureFactory. Use Future's default RunQueue.
     */

     public   FutureFactory ()   {
         super ();
        runQueue  =   Future . getClassRunQueue ();
     }

     /**
     * Get the RunQueue for a FutureFactory object.
     *
     *  @return  The RunQueue that objects runDelayed on a Future object
     *         created by this factory will be placed in.
     */

     public   RunQueue  getRunQueue ()   {
         return  runQueue ;
     }

     /**
     * Set the RunQueue for a FutureFactory object.
     */

     public   void  setRunQueue ( RunQueue  rq )   {
        runQueue  =  rq ;
     }

     /**
     * Create a Future.
     */

     public   Future  make ()   {
         Future  f  =   new   Future ();
        f . setRunQueue ( runQueue );
         return  f ;
     }

     /**
     * Create a Future with a value already assigned.
     */

     public   Future  make ( Object  val )   {
         Future  f  =   new   Future ( val );
        f . setRunQueue ( runQueue );
         return  f ;
     }
}

jhpc/thread/FutureQueue.java

jhpc/thread/FutureQueue.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

// package jhpc.thread;


/**
 * A FIFO queue.
 * A get() [dequeue] will return immediately with a Future
 * if the queue is empty. The operation look() will return a Future for the
 * first element in the queue. Methods getSkip() and lookSkip() will return
 * the element itself, not a future, or null if the queue is empty.
 * Used in SharedTableOfQueues.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */
public   class   FutureQueue   {
     /**
     * Is the queue of objects.
     */
     QueueComponent  q  =   new   QueueComponent ();
     /**
     * Is a queue of Futures each of which is being waited on by one thread
     * trying to get an object.
     */
     QueueComponent  qf  =   new   QueueComponent ();
     /**
     * Is a single Future being waited on by one or more threads trying to
     * do a lookup. If there are no threads waiting on a lookup,
     * lf==null.
     */
     Future  lf  =   null ;

     /**
     * Is the future factory used to create the futures that will be returned.
     * It will be created to specify the RunQueue upon which runDelayed objects
     * will be placed.
     */
     FutureFactory  ff  =   null ;

     /**
     * The empty constructor. The Futures use their own class RunQueue.
     */

     public   FutureQueue ()   {
        ff  =   new   FutureFactory ( Future . getClassRunQueue ());
     }

     /**
     * The constructor that specifies a RunQueue upon which runDelayed
     * objects will be placed.
     *
     *  @param  r The RunQueue for runDelayed objects.
     */

     public   FutureQueue ( RunQueue  r )   {
        ff  =   new   FutureFactory ( r );
     }

     /**
     * The constructor that specifies a FutureFactory to use to create
     * the futures.
     *
     *  @param  f The FutureFactory.
     */

     public   FutureQueue ( FutureFactory  f )   {
        ff  =  f ;
     }

     /**
     * Put an object into the queue.
     *
     *  @param  obj The object to place in the queue. If you put null into the
     *            queue, the getSkip() and lookSkip() methods will not be able to
     *            distinguish it from an empty queue.
     */
     public   synchronized   void  put ( Object  obj )   {
         Future  f ;
         if   ( ! qf . isEmpty ())   {
            f  =   ( Future )  qf . get ();
            f . setValue ( obj );
         }   else   {
            q . put ( obj );
         }
     }

     /**
     * See if the queue is not in use.
     *
     *  @return  True if the queue is empty and there are no Futures outstanding.
     *         I.e., it returns true if and only if there are no elements in the queue
     *         and no threads are waiting for a get() or a look() method to complete.
     */
     public   synchronized   boolean  isVacant ()   {
         return   ( q . isEmpty ())   &&
                 ( qf . isEmpty ())   &&
                lf  ==   null ;
     }

     /**
     * Is the queue empty.
     *
     *  @return  True if there are no objects (or nulls) in the queue.
     */
     public   synchronized   boolean  isEmpty ()   {
         if   ( lf  !=   null   &&  lf . isSet ())   return   false ;
         return   ( q . isEmpty ());
     }

     /**
     * Get the next element in the queue, removing it.
     *
     *  @return  A Future for the next element in the queue. If the
     *         queue is not empty, the first element is removed and returned
     *         in the Future. If the queue is empty, the value will be assigned
     *         to the Future during a later put().
     */
     public   synchronized   Future  get ()   {
         Object  obj ;
         Future  f ;
         if   ( lf  !=   null )   {
            f  =  lf ;
            lf  =   null ;
             return  f ;
         }
         if   ( ! q . isEmpty ())   {
            obj  =  q . get ();
            lf  =   null ;
             return  ff . make ( obj );
         }
        f  =  ff . make ();
        qf . put ( f );
         return  f ;
     }

     /**
     * Look at the next element in the queue. Don't remove it.
     *
     *  @return  A Future for the next element in the queue. If the
     *         queue is not empty, the first element is returned
     *         in the Future. If the queue is empty, the value will be assigned
     *         to the Future during a later put().
     */
     public   synchronized   Future  look ()   {
         Object  obj ;
         if   ( lf  !=   null )   return  lf ;
        lf  =  ff . make ();
         if   ( ! q . isEmpty ())   {
            obj  =  q . get ();
            lf . setValue ( obj );
         }   else   {
            qf . put ( lf );
         }
         return  lf ;
     }

     /**
     * Run the Runnable object r as soon as the queue is not empty.
     *
     *  @param  r The object to run.
     */
     public   void  runDelayed ( Runnable  r )   {
        look (). runDelayed ( r );
     }

     /**
     * Get the next element in the queue, removing it. Return null if
     * the queue is empty. Cannot distinguish between an empty queue
     * and a null value in the queue.
     *
     *  @return  The next element in the queue. If the
     *         queue is not empty, remove and return the first element.
     *         If the queue is empty, return null.
     */
     public   synchronized   Object  getSkip ()   {
         Object  obj  =   null ;
         if   ( lf  !=   null   &&  lf . isSet ())   {
             try   {
                obj  =  lf . getValue ();
             }   catch   ( InterruptedException  ex )   {
             }
            lf  =   null ;
             return  obj ;
         }
         if   ( q . isEmpty ())   return   null ;
        obj  =  q . get ();
        lf  =   null ;
         return  obj ;
     }

     /**
     * Look at the next element in the queue. Don't remove it.
     * Cannot distinguish between an empty queue
     * and a null value in the queue.
     *
     *  @return  The first element in the queue or null. If the
     *         queue is not empty, returns a reference to the first element.
     *         If the queue is empty, returns null.
     */
     public   synchronized   Object  lookSkip ()   {
         Object  obj  =   null ;
         if   ( lf  !=   null   &&  lf . isSet ())   {
             try   {
                obj  =  lf . getValue ();
             }   catch   ( InterruptedException  ex )   {
             }
             return  obj ;
         }
         if   ( q . isEmpty ())   return   null ;
        obj  =  q . firstElement ();
         return  obj ;
     }

     public   static   class   Test1   {
         public   static   void  main ( String  args [])   {
             try   {
                 Future []  f  =   new   Future [ 6 ];
                 FutureQueue  q  =   new   FutureQueue ();
                 int  i  =   0 ;
                 System . out . println ( "Should each time yield: aaaabb" );
                q . put ( "a" );
                q . put ( "b" );
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . out . print ( f [ i ]. getValue ());
                 System . out . println ();

                i  =   0 ;
                f [ i ++ ]   =  q . look ();
                q . put ( "a" );
                f [ i ++ ]   =  q . look ();
                q . put ( "b" );
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . out . print ( f [ i ]. getValue ());
                 System . out . println ();

                i  =   0 ;
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . get ();
                q . put ( "a" );
                q . put ( "b" );
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . out . print ( f [ i ]. getValue ());
                 System . out . println ();

                i  =   0 ;
                q . put ( "a" );
                q . put ( "b" );
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . out . print ( f [ i ]. getValue ());
                 System . out . println ();

                i  =   0 ;
                f [ i ++ ]   =  q . look ();
                q . put ( "a" );
                f [ i ++ ]   =  q . look ();
                q . put ( "b" );
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                f [ i ++ ]   =  q . look ();
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . out . print ( f [ i ]. getValue ());
                 System . out . println ();

                i  =   0 ;
                f [ i ++ ]   =  q . look ();
                q . put ( "a" );
                f [ i ++ ]   =   new   Future ( q . lookSkip ());
                q . put ( "b" );
                f [ i ++ ]   =   new   Future ( q . lookSkip ());
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                f [ i ++ ]   =   new   Future ( q . lookSkip ());
                f [ i ++ ]   =   new   Future ( q . getSkip ());
                 for   ( =   0 ;  i  <  f . length ;  i ++ )
                     System . err . print ( f [ i ]. isSet ()   ?  f [ i ]. getValue ()   :   "." );
                 System . out . println ();
             }   catch   ( Exception  e )   {
                e . printStackTrace ();
             }
         }
     }
}

jhpc/thread/FutureTable.java

jhpc/thread/FutureTable.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Hashtable ;

/**
 * A table of Futures that are automatically created on look-up (get).
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   FutureTable   {

     /**
     * The FutureFactory to generate the futures.
     */
     protected   FutureFactory  ff ;

     /**
     * The table.
     */
     protected   Hashtable  tbl  =   new   Hashtable ();

     /**
     * Default constructor. Use the default FutureFactory,
     * which uses Future's class run queue.
     */
     public   FutureTable ()   {
        ff  =   new   FutureFactory ();
     }

     /**
     * Constructor taking an explicit future factory.
     *
     *  @param  f The future factory to use when creating futures.
     */
     public   FutureTable ( FutureFactory  f )   {
        ff  =  f ;
     }

     /**
     * Constructor taking an explicit run queue.
     *
     *  @param  f The run queue to use in the created futures.
     */
     public   FutureTable ( RunQueue  rq )   {
        ff  =   new   FutureFactory ( rq );
     }


     /**
     * Returns the Future associated with the key in this table.
     * Creates one if none existed previously.
     *
     *  @return  The Future associated with the key.
     */
     public   synchronized   Future  get ( Object  key )   {
         Future  f  =   ( Future )  tbl . get ( key );
         if   ( ==   null )  tbl . put ( key ,  f  =   new   Future ());
         return  f ;
     }

     /**
     * Removes any Future associated with key in the table.
     * Not that easy to use safely.
     */
     public   synchronized   void  remove ( Object  key )   {
        tbl . remove ( key );
     }

}

jhpc/thread/IndexedKey.java

jhpc/thread/IndexedKey.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Random ;

/**
 * To be used to generate keys for FutureTables
 * and SharedTableOfQueues. An indexed key consists of
 * an int id and a long index. </p>The id can be specified
 * when the indexed key is created, or it can be generated
 * randomly. Indexed keys with the same id value
 * may be considered names of parts of the same data
 * structure.
 */
public   class   IndexedKey   {
     private   static   Random  rand  =   new   Random ();
     private   static   Random  hasher  =   new   Random ();
     /**
     * The identity field. Indexed keys with the same id
     * field are considered related, i.e. names of parts of
     * the same data structure.
     */
     private   int  id ;
     /**
     * The index field.
     */
     private   long  x ;

     private   IndexedKey ( long  x )   {
         synchronized   ( rand )   {
             for   ( id  =  rand . nextInt ();
                 id  <   Short . MIN_VALUE  &&   Short . MAX_VALUE  <  id ;
                 id  =  rand . nextInt ())
                 ;
         }
         this . =  x ;
     }

     private   IndexedKey ( int  id ,   long  x )   {
         this . id  =  id ;
         this . =  x ;
     }

     /**
     * Factory method to create an indexed key with a random
     * id and a specified index. The id field will not be the
     * same as any short int.
     *
     *  @param  x The index.
     *  @return  The new IndexedKey.
     */
     public   static   IndexedKey  unique ( long  x )   {
         return   new   IndexedKey ( x );
     }

     /**
     * Factory method to make an indexed key with a specified
     * id and a specified index. If the id field is a short int,
     * it will not be the same as any id generated by unique().
     *
     *  @param  id The id field.
     *  @param  x  The index.
     *  @return  The new IndexedKey.
     */
     public   static   IndexedKey  make ( int  id ,   long  x )   {
         return   new   IndexedKey ( id ,  x );
     }

     /**
     * Get the id field.
     *
     *  @return  The id field.
     */
     public   int  getId ()   {
         return  id ;
     }

     /**
     * Get the index field.
     *
     *  @return  The index field.
     */
     public   long  getX ()   {
         return  x ;
     }

     /**
     * Create a new indexed key with the same id as this
     * one and a specified index field.
     *
     *  @param  x The index.
     *  @return  The new IndexedKey.
     */
     public   IndexedKey  at ( long  x )   {
         return   new   IndexedKey ( id ,  x );
     }

     /**
     * Create a new indexed key with the same id as this
     * one and an index field differing by a specified amount
     * from the index field of this indexed key.
     *
     *  @param  x The amount to add to the index.
     *  @return  The new IndexedKey.
     */
     public   IndexedKey  add ( long  x )   {
         return   new   IndexedKey ( id ,   this . +  x );
     }

     /**
     * Compare two indexed key objects for equality.
     * They are equal id their id and x fields are equal.
     *
     *  @param  o The other indexed key.
     *  @return  True if they are equal, else false.
     */
     public   boolean  equals ( Object  o )   {
         if   ( instanceof   IndexedKey )   {
             IndexedKey  k  =   ( IndexedKey )  o ;
             return  id  ==  k . id  &&
                    x  ==  k . x ;
         }   else
             return   false ;
     }

     /**
     * Hash an indexed key object. The hash value is
     * computed from the id and x fields.
     *
     *  @return  the hash code.
     */
     public   int  hashCode ()   {
         synchronized   ( hasher )   {
            hasher . setSeed ( id  +  x );
            hasher . nextInt ();
             return  hasher . nextInt ();
         }
     }

     /**
     * Convert the indexed key into a string.
     *
     *  @return  The string.
     */
     public   String  toString ()   {
         return   "IndexedKey("   +  id  +   ","   +  x  +   ")" ;
     }
}

jhpc/thread/Lock.java

jhpc/thread/Lock.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/

package  info . jhpc . thread ;

class   Lock   {
     protected   boolean  locked ;

     public   Lock ()   {
        locked  =   false ;
     }

     public   synchronized   void  lock ()
             throws   InterruptedException   {
         while   ( locked )  wait ();
        locked  =   true ;
     }

     public   synchronized   void  unlock ()   {
        locked  =   false ;
        notify ();
     }
}

jhpc/thread/LockTable.java

jhpc/thread/LockTable.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/



//Locks (binary semaphores)
package  info . jhpc . thread ;

import  java . util . Hashtable ;

/**
 * Lock single or multiple locks.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   LockTable   {
     protected   Hashtable  table  =   new   Hashtable ();

     /**
     * Lock single lock indicated by object s. Since
     * LockTable uses a hashtable to maintain the locks,
     * it uses equals() to detect whether two locks are
     * the same. Thus two strings can be equal and indicate
     * the same lock, even though they are not the same
     * object.
     */
     public   synchronized   void  lock ( Object  s )
             throws   InterruptedException   {
         while   ( table . get ( s )   !=   null )  wait ();
        table . put ( s ,  s );
     }

     /**
     * Unlock the single lock indicated by object s.
     */
     public   synchronized   void  unlock ( Object  s )   {
        table . remove ( s );
        notifyAll ();
     }

     /**
     * Simultaneously lock all the locks indicated by the
     * objects in the array sa. Since
     * LockTable uses a hashtable to maintain the locks,
     * it uses equals() to detect whether two locks are
     * the same. Thus two strings can be equal and indicate
     * the same lock, even though they are not the same
     * object.
     */
     public   synchronized   void  lock ( Object []  sa )
             throws   InterruptedException   {
         int  i ;
         TryToLock :
           while   ( true )   {
               for   ( =   0 ;  i  <  sa . length ;  i ++ )   {
                   if   ( table . get ( sa [ i ])   !=   null )   {
                      wait ();
                       continue   TryToLock ;
                   }
               }
               for   ( =   0 ;  i  <  sa . length ;  i ++ )
                  table . put ( sa [ i ],  sa [ i ]);
               return ;
           }
     }

     /**
     * Simultaneously unlock all the locks indicated by the
     * objects in the array sa.
     */
     public   synchronized   void  unlock ( Object []  sa )   {
         int  i ;
         for   ( =   0 ;  i  <  sa . length ;  i ++ )  table . remove ( sa [ i ]);
        notifyAll ();
     }
}

jhpc/thread/Monitor$1.class

                package info.jhpc.thread;

                synchronized 
                class Monitor$1 {
}

            

jhpc/thread/Monitor.java

jhpc/thread/Monitor.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * A Monitor with condition variables, similar to those
 * defined by Hoare and Brinch-Hansen. A class with methods
 * declared synchronized is Java's standard version of
 * a monitor.<p>
 * The condition variables are provided by the inner class
 * Condition.<p>
 * To use this monitor to protect your class,
 * you must either have your class extend Monitor, like
 * this bounded buffer example:<p>
 * <blockquote>
 * <pre>
 * class BoundedBuffer3 extends Monitor{
 * Condition notEmpty=new Condition();
 * Condition notFull=new Condition();
 * <p/>
 * volatile int hd=0,tl=0;
 * Object[] buffer;
 * public BoundedBuffer3(int size) {
 *    buffer=new Object[size];
 * }
 * public void put(Object v)
 *        throws InterruptedException {
 *    enter();
 *    if(tl - hd >= buffer.length) notFull.await();
 *    buffer[tl++ % buffer.length] = v;
 *    notEmpty.signal();
 *    leave();
 * }
 * public Object get()
 *        throws InterruptedException {
 *    enter();
 *    Object v;
 *    if (tl==hd) notEmpty.await();
 *    v = buffer[hd++ % buffer.length];
 *    notFull.signal();
 *    leave();
 *    return v;
 * }
 * }
 * </pre>
 * </blockquote>
 * or use a separate monitor
 * <blockquote>
 * <pre>
 * class BoundedBuffer4 {
 * Monitor mon = new Monitor();
 * Monitor.Condition notEmpty = mon.new Condition();
 * Monitor.Condition notFull = mon.new Condition();
 * <p/>
 * volatile int hd=0,tl=0;
 * Object[] buffer;
 * public BoundedBuffer4(int size) {
 *    buffer=new Object[size];
 * }
 * public void put(Object v)
 *        throws InterruptedException {
 *    mon.enter();
 *    if(tl - hd >= buffer.length) notFull.await();
 *    buffer[tl++ % buffer.length] = v;
 *    notEmpty.signal();
 *    mon.leave();
 * }
 * public Object get()
 *        throws InterruptedException {
 *    mon.enter();
 *    Object v;
 *    if (tl==hd) notEmpty.await();
 *    v = buffer[hd++ % buffer.length];
 *    notFull.leaveWithSignal();
 *    return v;
 * }
 * }
 * </pre>
 * </blockquote>
 * A Monitor must be entered with an enter() call.
 * It is left by a call of leave(). You may enter
 * the same monitor more than once, e.g. calling one
 * monitor-protected method from another. You must
 * leave, of course, as many times as you enter.<p>
 * <p/>
 * Condition is an inner class. It must be created
 * within a monitor object. It represents a condition
 * that a thread may wish to wait on. <p>
 * To wait for condition C to hold, a thread calls
 * <blockquote>
 * C.await();
 * </blockquote>
 * To signal that a condition holds, a thread calls
 * <blockquote>
 * C.signal();
 * </blockquote>
 * If one or more threads are awaiting the condition
 * at the time of a signal, one of them will be given
 * control of the monitor immediately. The thread
 * executing the signal() will wait to reacquire the
 * monitor. <p>
 * To both signal a condition and leave the monitor
 * simultaneously, you can call leaveWithSignal().
 * It is more efficient than a signal() followed by a
 * leave(), since it does not have to wait to reacquire
 * the monitor before executing the leave().
 * <blockquote>
 * C.leaveWithSignal();
 * </blockquote>
 * Be sure you declare the fields of the Monitor-protected
 * class to be <b>volatile</b>.<p>
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   Monitor    {
     /**
     * Semaphore to lock the Monitor:
     * <blockquote>
     * monitorEntry.down();
     * </blockquote>
     * locks the monitor on entry,
     * <blockquote>
     * monitorEntry.up();
     * </blockquote>
     * unlocks the monitor on exit.
     */
     Semaphore  monitorEntry  =   new   Semaphore ( 1 );
     /**
     * The current thread. When the monitor is not in use,
     * <b>monitorEntry==null</b>. This is checked to see if
     * the monitor is being reentered by the current owner
     * or not.
     */
     volatile   Thread  current  =   null ;
     /**
     * The number of times the monitor's current owner
     * has entered it minus the number of times it has
     * exited it.
     */
     volatile   int  monitorEntryCount  =   0 ;

     /**
     * The inner class for condition variables.
     */
     public   class   Condition   implements   MonitorCondition   {
         /**
         * The number of threads waiting on this condition.
         */
         volatile   int  waiting  =   0 ;
         /**
         * The semaphore upon which the waiting threads wait.
         * <blockquote>
         * waitCond.down();
         * </blockquote>
         * to wait.
         * <blockquote>
         * waitCond.up();
         * </blockquote>
         * to to signal one of the waiting threads to resume execution.
         */
         Semaphore  waitCond  =   new   Semaphore ( 0 );

         /**
         * Wait for the condition to hold. Another thread will signal when this happens.
         *
         *  @throws  InterruptedException If interrupted while waiting.
         *  @throws  MonitorException     If the thread executing this is not
         *                              inside the Monitor.
         */
         public   void  await ()
                 throws   InterruptedException ,   MonitorException   {
             if   ( current  !=   Thread . currentThread ())
                 throw   new   MonitorException ( "await()" );
             int  count  =  monitorEntryCount ;
            monitorEntryCount  =   0 ;
            current  =   null ;
            waiting ++ ;
            monitorEntry . up ();
            waitCond . down ();
            current  =   Thread . currentThread ();
            monitorEntryCount  =  count ;
         }

         /**
         * Signal the condition has occurred. If there are any waiting
         * threads, it signals one of them to resume execution,
         * hands over the monitor to it, and waits to reenter the monitor.
         *
         *  @throws  MonitorException If the thread executing this is not
         *                          inside the Monitor.
         */
         public   void  signal ()
                 throws   MonitorException   {
             if   ( current  !=   Thread . currentThread ())
                 throw   new   MonitorException ( "signal()" );
             if   ( waiting  >   0 )   {
                waiting -- ;
                 int  count  =  monitorEntryCount ;
                monitorEntryCount  =   0 ;
                current  =   null ;
                waitCond . up ();
                 boolean  interrupted  =   Thread . interrupted ();
                 for   (;   ;)
                     try   {
                        monitorEntry . down ();
                         break ;
                     }   catch   ( InterruptedException  ie )   {
                        interrupted  =   true ;
                     }
                current  =   Thread . currentThread ();
                monitorEntryCount  =  count ;
                 if   ( interrupted )  current . interrupt ();
             }
         }

         /**
         * Signal the condition has occurred and leaves the monitor.
         * Equivalent to
         * <blockquote>
         * cond.signal(); mon.leave();
         * </blockquote>
         * If there are any waiting
         * threads, it signals one of them to resume execution and
         * hands over the monitor to it.<p>
         * If this thread has entered the monitor more than once,
         * leaveWithSignal() behaves like signal(). After the signaled
         * thread has run, the signaling thread will reenter the monitor
         * to complete its execution.
         *
         *  @throws  MonitorException If the thread executing this is not
         *                          inside the Monitor.
         */
         public   void  leaveWithSignal ()
                 throws   MonitorException   {
             if   ( current  !=   Thread . currentThread ())
                 throw   new   MonitorException ( "leaveWithSignal()" );
            monitorEntryCount -- ;
             if   ( waiting  >   0 )   {
                waiting -- ;
                 if   ( monitorEntryCount  >   0 )   {
                     int  count  =  monitorEntryCount ;
                    monitorEntryCount  =   0 ;
                    current  =   null ;
                    waitCond . up ();
                     boolean  interrupted  =   Thread . interrupted ();
                     for   (;   ;)
                         try   {
                            monitorEntry . down ();
                             break ;
                         }   catch   ( InterruptedException  ie )   {
                            interrupted  =   true ;
                         }
                    monitorEntryCount  =  count ;
                    current  =   Thread . currentThread ();
                     if   ( interrupted )  current . interrupt ();
                 }   else   {
                    current  =   null ;
                    waitCond . up ();
                 }
             }   else   {
                 if   ( monitorEntryCount  ==   0 )   {
                    current  =   null ;
                    monitorEntry . up ();
                 }
             }
         }
     }

     /* (non-Javadoc)
     * @see info.jhpc.thread.IMonitor#enter()
     */
     public   void  enter ()   {
         if   ( current  ==   Thread . currentThread ())
            monitorEntryCount ++ ;
         else   {
             boolean  interrupted  =   Thread . interrupted ();
             for   (;   ;)
                 try   {
                    monitorEntry . down ();
                     break ;
                 }   catch   ( InterruptedException  ie )   {
                    interrupted  =   true ;
                 }
            current  =   Thread . currentThread ();
            monitorEntryCount  =   1 ;
             if   ( interrupted )  current . interrupt ();
         }
     }

     /* (non-Javadoc)
     * @see info.jhpc.thread.IMonitor#leave()
     */
     public   void  leave ()   throws   MonitorException   {
         if   ( current  !=   Thread . currentThread ())
             throw   new   MonitorException ( "leave()" );
        monitorEntryCount -- ;
         if   ( monitorEntryCount  ==   0 )   {
            current  =   null ;
            monitorEntry . up ();
         }
     }

     /**
     * Lock for a monitor left temporarily by release(). This Lock
     * can be used by the same thread to reacquire the Monitor once.
     */
     private   class   Lock   implements   MonitorLock   {
         int  n  =  monitorEntryCount ;
         Thread  owner  =  current ;

         /**
         * Enter the monitor again after an earlier release.
         *
         *  @throws  MonitorException If thread attempting to reacquire
         *                          a Monitor not released by this thread or if this Lock
         *                          has been previously used.
         */
         public   void  reacquire ()   throws
                 MonitorException   {
             if   ( owner  !=   Thread . currentThread ())
                 throw   new   MonitorException ( "attempt to reacquire Monitor by a different thread" );
             boolean  interrupted  =   Thread . interrupted ();
             for   (;   ;)
                 try   {
                    monitorEntry . down ();
                     break ;
                 }   catch   ( InterruptedException  ie )   {
                    interrupted  =   true ;
                 }
            current  =  owner ;
            monitorEntryCount  =  n ;
            owner  =   null ;
             if   ( interrupted )  current . interrupt ();
         }
     }

     /* (non-Javadoc)
     * @see info.jhpc.thread.IMonitor#release()
     */
     public   MonitorLock  release ()   throws   MonitorException   {
         if   ( current  !=   Thread . currentThread ())
             throw   new   MonitorException ( "release()" );
         Lock  L  =   new   Lock ();
        current  =   null ;
        monitorEntryCount  =   0 ;
        monitorEntry . up ();
         return  L ;
     }
}

jhpc/thread/MonitorCondition.java

jhpc/thread/MonitorCondition.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Interface implemented by Monitor.Condition.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   interface   MonitorCondition   {

     /**
     * Wait for the condition to hold. Another thread will signal when this happens.
     *
     *  @throws  InterruptedException If interrupted while waiting.
     *  @throws  MonitorException     If the thread executing this is not
     *                              inside the Monitor.
     */
     public   void  await ()
             throws   InterruptedException ,   MonitorException ;

     /**
     * Signal the condition has occurred. If there are any waiting
     * threads, it signals one of them to resume execution,
     * hands over the monitor to it, and waits to reenter the monitor.
     *
     *  @throws  InterruptedException If interrupted while trying to
     *                              reenter the monitor.
     *  @throws  MonitorException     If the thread executing this is not
     *                              inside the Monitor.
     */
     public   void  signal ()
             throws   InterruptedException ,   MonitorException ;

     /**
     * Signal the condition has occurred and leaves the monitor.
     * Equivalent to
     * <blockquote>
     * cond.signal(); mon.leave();
     * </blockquote>
     * If there are any waiting
     * threads, it signals one of them to resume execution and
     * hands over the monitor to it.<p>
     * If this thread has entered the monitor more than once,
     * leaveWithSignal() behaves like signal(). After the signaled
     * thread has run, the signaling thread will reenter the monitor
     * to complete its execution.
     *
     *  @throws  InterruptedException If interrupted while trying to
     *                              reenter the monitor.
     *  @throws  MonitorException     If the thread executing this is not
     *                              inside the Monitor.
     */
     public   void  leaveWithSignal ()
             throws   InterruptedException ,   MonitorException ;

}

jhpc/thread/MonitorException.java

jhpc/thread/MonitorException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Thrown if a thread tries to operate on a
 * com.toolsofcomputing.thread.Monitor that it
 * doesn't have locked.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   MonitorException
         extends   RuntimeException   {
     public   MonitorException ()   {
         super ( "Illegal operation by thread outside Monitor" );
     }

     public   MonitorException ( String  s )   {
         super ( +   " by thread outside the Monitor" );
     }
}

jhpc/thread/MonitorLock.java

jhpc/thread/MonitorLock.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Interface implemented by Monitor.Lock.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   interface   MonitorLock   {
     /**
     * Enter the monitor again after an earlier release.
     *
     *  @throws  InterruptedException If interrupted while waiting to enter.
     */
     public   void  reacquire ()   throws   InterruptedException ,   MonitorException ;
}

jhpc/thread/NegativeSemaphoreException.java

jhpc/thread/NegativeSemaphoreException.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Thrown if a com.toolsofcomputing.thread.Semaphore is assigned
 * a negative initial value
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   NegativeSemaphoreException
         extends   RuntimeException   {
     public   NegativeSemaphoreException ()   {
         super ( "Semaphore given a negative count" );
     }
}

jhpc/thread/PriorityRunQueue.java

jhpc/thread/PriorityRunQueue.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Runnable objects are placed in this queue
 * to be executed in threads. It has much the
 * same effect as creating a new thread to
 * run the object, but the threads created in
 * a PriorityRunQueue, called "Xeq" threads, can loop
 * to run another object, saving some of the
 * cost of thread creation.<p>
 * A limit may be placed on the maximum number
 * of Xeq threads that can be created at a time
 * to avoid clogging the system with too many
 * threads. This, however, can lead to deadlock
 * if the threads wait on conditions that objects
 * later in the queue will cause.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   PriorityRunQueue   {

     /**
     * The number of elements in the heap of Runnable
     * objects to execute.
     */

     protected   int  N  =   0 ;

     /**
     * The heap of Runnable objects to execute.
     */

     protected   Runnable []  runnables  =   new   Runnable [ 16 ];

     /**
     * The priorities for the heap of Runnable objects to execute.
     */

     protected   float []  priorities  =   new   float [ runnables . length ];

     /**
     * The number of threads currently waiting
     * for Runnable objects to execute that have
     * not been notified to wake up yet.
     */

     protected   int  numThreadsWaiting  =   0 ;

     /**
     * The number of threads currently waiting
     * that have been notified to wake up because
     * a Runnable object has been enqueued.
     * numThreadsWaiting + numNotifies = Xeq threads
     * waiting
     */

     protected   int  numNotifies  =   0 ;

     /**
     * The maximum number of
     * Xeq threads that can be waiting at a time
     * for Runnable objects to execute.
     * The default value is 1.
     */

     protected   int  maxThreadsWaiting  =   1 ;

     /**
     * The number of Xeq threads currently in existence.
     */

     protected   int  numThreadsCreated  =   0 ;

     /**
     * Whether the Xeq threads should continue.
     */

     protected   boolean  goOn  =   true ;

     /**
     * The maximum number of
     * threads that can be created at a time
     * to execute Runnable objects.
     * The default value is 1.
     */

     protected   int  maxThreadsCreated  =   1 ;

     /**
     * Whether to make the Xeq threads daemons.
     */

     protected   volatile   boolean  makeDaemon  =   true ;

     /**
     * The priority at which Xeq threads run.
     */

     protected   int  xeqPriority  =   Thread . NORM_PRIORITY ;

     /**
     * The number of milliseconds Xeq wait for something to run
     * before terminating themselves.
     */

     protected   long  waitTime  =   600000 ;   // 10 min.

     /**
     * Create a PriorityRunQueue with the default maximum number of
     * Xeq threads that can be created at a time
     * and a maximum number that can be waiting at any
     * one time for more Runnable objects to execute.
     */

     public   PriorityRunQueue ()   {
     }

     /**
     * Create a PriorityRunQueue with a specified maximum number of
     * Xeq threads that can be created at a time.
     *
     *  @param  maxCreatable Initial value for maxThreadsCreated.
     */

     public   PriorityRunQueue ( int  maxCreatable )   {
        maxThreadsCreated  =  maxCreatable ;
     }

     /**
     * Create a PriorityRunQueue with a specified maximum number of
     * Xeq threads that can be created at a time
     * and a maximum number that can be waiting at any
     * one time for more Runnable objects to execute.
     *
     *  @param  maxCreatable Initial value for maxThreadsCreated.
     *  @param  maxWaiting   Initial value for maxThreadsWaiting.
     */

     public   PriorityRunQueue ( int  maxCreatable ,   int  maxWaiting )   {
        maxThreadsCreated  =  maxCreatable ;
        maxThreadsWaiting  =  maxWaiting ;
     }

     /**
     * A thread that will dequeue and run Runnable objects in the
     * PriorityRunQueue.
     */

     protected   class   Xeq   extends   Thread   {
         public   void  run ()   {
             Runnable  r ;
             try   {
                 while   ( goOn )   {
                    r  =  dequeue ();
                    r . run ();
                 }
             }   catch   ( InterruptedException  ie )   { //nothing
             }   catch   ( Exception  e )   {
                e . printStackTrace ();
             }
            numThreadsCreated -- ;
         }
     }

     /**
     * Enqueue an object to be run when a thread becomes available.
     *
     *  @param  runnable The Runnable object to be enqueued for
     *                 execution.
     */

     public   void  put ( Runnable  runnable ,   double  priority )   {
         int  nt ;
         boolean  createThread  =   false ;
         synchronized   ( this )   {
            N ++ ;
             if   ( >=  runnables . length )   {
                 Runnable []  newRunnables  =   new   Runnable [ 2   *  runnables . length ];
                 System . arraycopy ( runnables ,   0 ,  newRunnables ,   0 ,  runnables . length );
                 float []  newPriorities  =   new   float [ 2   *  runnables . length ];
                 System . arraycopy ( priorities ,   0 ,  newPriorities ,   0 ,  priorities . length );
                runnables  =  newRunnables ;
                priorities  =  newPriorities ;
             }
            runnables [ N ]   =  runnable ;
            priorities [ N ]   =   ( float )  priority ;
            siftDown ( N );

            nt  =  numThreadsWaiting ;
             if   ( numThreadsWaiting  >   0 )   {
                numThreadsWaiting -- ;
                numNotifies ++ ;
                notify ();
             }   else   if   ( numThreadsCreated  <  maxThreadsCreated )   {
                 // was: if (nt==0 && numThreadsCreated<maxThreadsCreated) {
                numThreadsCreated ++ ;
                createThread  =   true ;
             }
         }
         if   ( createThread )   {
             Thread  t  =   new   Xeq ();
             //System.out.println("new Xeq():"+numThreadsCreated);
            t . setPriority ( xeqPriority );
            t . start ();
         }
     }
//******************************************************************
     protected   void  siftUp ( int  i ,   int  n )   {
         int  j ,  k ;
         for   ( =  i ,  k  =   2   *  j ;  k  <=  n ;  j  =  k ,  k  =   2   *  j )   {
             if   ( <  n  &&  priorities [ k ]   <  priorities [ +   1 ])  k ++ ;
             if   ( priorities [ j ]   <  priorities [ k ])   {
                exchange ( j ,  k );
             }   else
                 break ;
         }
     }
//******************************************************************
     protected   void  siftDown ( int  i )   {
         for   ( int  j  =  i  /   2 ;  i  >   1 ;  i  =  j ,  j  =  i  /   2 )   {
             if   ( priorities [ j ]   <  priorities [ i ])   {
                exchange ( i ,  j );
             }   else
                 break ;
             //i=j;
         }
     }
//******************************************************************
     protected   void  exchange ( int  i ,   int  j )   {
         float  fltTmp  =  priorities [ i ];
        priorities [ i ]   =  priorities [ j ];
        priorities [ j ]   =  fltTmp ;
         Runnable  runTmp  =  runnables [ i ];
        runnables [ i ]   =  runnables [ j ];
        runnables [ j ]   =  runTmp ;
     }
//******************************************************************

     /**
     * Same as put(runnable, priority).
     *
     *  @param  runnable The Runnable object to be enqueued for
     *                 execution.
     */

     public   void  run ( Runnable  runnable ,   double  priority )   {
        put ( runnable ,  priority );
     }


     /**
     * Removes and returns a Runnable object to be executed.
     * Called by an Xeq thread.<p>
     * Will wait for an object to run if the limit on waiting
     * threads hasn't been reached. If it has, dequeue will throw
     * an InterruptedException to kill the Xeq thread.
     *
     *  @throws  InterruptedException To kill the Xeq thread if the
     *                              limit of waiting threads has been reached and there are
     *                              no objects to run.
     */

     protected   synchronized   Runnable  dequeue ()
             throws   InterruptedException   {
         Runnable  runnable ;
         while   ( ==   0 )   {
             if   ( numThreadsWaiting  <  maxThreadsWaiting )   {
                numThreadsWaiting ++ ;
                wait ( waitTime );
                 if   ( numNotifies  ==   0   /*&& N==0*/ )   {
                    numThreadsWaiting -- ;
                     throw   new   InterruptedException ();
                 }   else   {
                    numNotifies -- ;
                 }
             }   else   {   //terminate
                 throw   new   InterruptedException ();
             }
         }
        runnable  =  runnables [ 1 ];
        runnables [ 1 ]   =  runnables [ N ];
        priorities [ 1 ]   =  priorities [ N ];
        N -- ;
        siftUp ( 1 ,  N );
         return  runnable ;
     }

     /**
     * Set the limit on the number of threads created by this
     * PriorityRunQueue object that may be waiting at any one time to
     * run objects.
     *
     *  @param  n The new limit.
     */

     public   synchronized   void  setMaxThreadsWaiting ( int  n )   {
        maxThreadsWaiting  =  n ;
        numNotifies  +=  numThreadsWaiting ;
        numThreadsWaiting  =   0 ;
        notifyAll ();
     }

     /**
     * Set the limit on the number of threads that may be
     * created by this PriorityRunQueue object at any one time to
     * run objects.
     *
     *  @param  n The new limit.
     */

     public   void  setMaxThreadsCreated ( int  n )   {
        maxThreadsCreated  =  n ;
     }

     /**
     * Get the limit on the number of threads created to
     * process objects that may be waiting for
     * new objects to process.
     *
     *  @return  maxThreadsWaiting
     */

     public   int  getMaxThreadsWaiting ()   {
         return  maxThreadsWaiting ;
     }

     /**
     * Get the limit on the number of threads that may be created to
     * process objects.
     *
     *  @return  maxThreadsCreated
     */

     public   int  getMaxThreadsCreated ()   {
         return  maxThreadsCreated ;
     }

     /**
     * Get the number of threads that have been created
     * by this PriorityRunQueue to process objects and
     * which are waiting to process more such objects.
     *
     *  @return  numThreadsWaiting
     */

     public   int  getNumThreadsWaiting ()   {
         return  numThreadsWaiting ;
     }

     /**
     * Get the number of existing threads that have been created
     * by this PriorityRunQueue to process objects.
     *
     *  @return  numThreadsCreated
     */

     public   int  getNumThreadsCreated ()   {
         return  numThreadsCreated ;
     }

     /**
     * Same as setMaxThreadsWaiting(0). Any waiting user threads
     * would prevent the system from terminating. This does not
     * force the queue to stop running threads.
     */

     public   synchronized   void  terminate ()   throws   InterruptedException   {
        goOn  =   false ;
        setMaxThreadsWaiting ( 0 );
         while   ( numThreadsCreated  >   0 )  wait ( 10 );
     }

     /**
     * Set the time limit an Xeq thread is to wait for a Runnable.
     *
     *  @param  n The new limit.
     */

     public   synchronized   void  setWaitTime ( long  n )   {
        waitTime  =  n ;
        numNotifies  +=  numThreadsWaiting ;
        numThreadsWaiting  =   0 ;
        notifyAll ();
     }

     /**
     * Get the time limit an Xeq thread is to wait for a Runnable.
     *
     *  @return  waitTime
     */

     public   long  getWaitTime ()   {
         return  waitTime ;
     }

     /**
     * Set the priority at which the Runnables are to execute.
     *
     *  @param  n The new priority.
     */

     public   void  setPriority ( int  n )   {
        xeqPriority  =  n ;
     }

     /**
     * Get the priority at which the Runnables are to execute.
     *
     *  @return  priority
     */

     public   int  getPriority ()   {
         return  xeqPriority ;
     }

     /**
     * Set whether the created threads will be daemons.
     *
     *  @param  d True if the created threads are to be daemon
     *          threads; false if user threads.
     */

     public   void  setDaemon ( boolean  d )   {
        makeDaemon  =  d ;
     }

     /**
     * Find out whether the created threads are daemons.
     *
     *  @return  true if the created threads are daemons.
     */

     public   boolean  getDaemon ()   {
         return  makeDaemon ;
     }

}

jhpc/thread/QueueComponent.java

jhpc/thread/QueueComponent.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Stack ;

/**
 * A class used to provide FIFO queues for the other classes
 * in the thread package. THIS IS NOT THREAD-SAFE. DO NOT
 * USE THIS ALONE FOR INTER-THREAD COMMUNICATION. This
 * must be contained within a locked object.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   QueueComponent   {
     Stack  hd  =   new   Stack (),  tl  =   new   Stack ();

     /**
     * Removes and returns the first element in the queue.
     *
     *  @throws  EmptyQueueException if the queue is empty.
     */
     public   Object  get ()   throws   EmptyQueueException   {
         if   ( ! hd . empty ())   return  hd . pop ();
         while   ( ! tl . empty ())  hd . push ( tl . pop ());
         if   ( hd . empty ())   throw   new   EmptyQueueException ();
         return  hd . pop ();
     }

     /**
     * Returns a reference to the first element in the queue
     * without removing it.
     *
     *  @throws  EmptyQueueException if the queue is empty.
     */
     public   Object  firstElement ()   throws   EmptyQueueException   {
         if   ( ! hd . empty ())   return  hd . peek ();
         while   ( ! tl . empty ())  hd . push ( tl . pop ());
         if   ( hd . empty ())   throw   new   EmptyQueueException ();
         return  hd . peek ();
     }

     /**
     * Enqueues its parameter.
     *
     *  @param  elem the value to be enqueued.
     */
     public   void  put ( Object  elem )   {
        tl . push ( elem );
     }

     /**
     * Returns true if the queue is empty; false, if it is not empty.
     */
     public   boolean  isEmpty ()   {
         return  hd . empty ()   &&  tl . empty ();
     }

     /**
     * Removes all elements from the queue, leaving it empty.
     */
     public   void  clear ()   {
        hd . setSize ( 0 );
        tl . setSize ( 0 );
     }

     /**
     * Tests the queue.
     */
     public   static   void  main ( String []  args )
             throws   NumberFormatException   {
         int  total ,  init ;
         int  i ;
         QueueComponent  q  =   new   QueueComponent ();
         String  s  =   "abc" ;
         for   ( =   0 ;  i  <  s . length ();  i ++ )   {
            q . put ( s . substring ( i ,  i  +   1 ));
         }
         String  t  =   "" ;
         while   ( ! q . isEmpty ())   {
            t  +=   ( String )  q . get ();
         }
         if   ( ! s . equals ( t ))   {
             System . out . println ( "Bug. Put in \""   +  s  +   "\", got \""   +  t  +   "\"" );
         }   else   {
             System . out . println ( "Tests okay." );
         }
         if   ( args . length  <   1 )   {
             System . out . println ( "usage: java QueueComponent total [init]" );
             System . exit ( 0 );
         }
        total  =   Integer . parseInt ( args [ 0 ]);
        init  =  args . length  <   2   ?   0   :   Integer . parseInt ( args [ 1 ]);
         if   ( total  <  init )   {
             System . out . println ( "total elements to enqueue must be greater than initial" );
             System . exit ( 0 );
         }

        q  =   new   QueueComponent ();

         long  startTime  =   System . currentTimeMillis ();
         for   ( =   0 ;  i  <  init ;  i ++ )  q . put ( "X" );
         for   (;  i  <  total ;  i ++ )   {
            q . put ( "X" );
            q . get ();
         }
         while   ( ! q . isEmpty ())  q . get ();
         System . out . println ( System . currentTimeMillis ()   -  startTime );
     }
}

jhpc/thread/RunDelayed.java

jhpc/thread/RunDelayed.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Interface implemented by objects that provide
 * method runDelayed.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   interface   RunDelayed   {

     /**
     * Delay the runnable r until some condition holds.
     *
     *  @param  r The runnable to be delayed.
     */

     public   void  runDelayed ( Runnable  r );

}

jhpc/thread/RunQueue.java

jhpc/thread/RunQueue.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Runnable objects are placed in this queue
 * to be executed in threads. It has much the
 * same effect as creating a new thread to
 * run the object, but the threads created in
 * a RunQueue, called "Xeq" threads, can loop
 * to run another object, saving some of the
 * cost of thread creation.<p>
 * A limit may be placed on the maximum number
 * of Xeq threads that can be created at a time
 * to avoid clogging the system with too many
 * threads. This, however, can lead to deadlock
 * if the threads wait on conditions that objects
 * later in the queue will cause.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   RunQueue   implements   RunDelayed   {

     /**
     * The queue of Runnable objects to execute.
     */

     protected   QueueComponent  runnables  =   new   QueueComponent ();

     /**
     * The number of threads currently waiting
     * for Runnable objects to execute that have
     * not been notified to wake up yet.
     */

     protected   volatile   int  numThreadsWaiting  =   0 ;

     /**
     * The number of threads currently waiting
     * that have been notified to wake up because
     * a Runnable object has been enqueued.
     * numThreadsWaiting + numNotifies = Xeq threads
     * waiting
     */

     protected   volatile   int  numNotifies  =   0 ;

     /**
     * The maximum number of
     * Xeq threads that can be waiting at a time
     * for Runnable objects to execute.
     * The default value is Integer.MAX_VALUE.
     */

     protected   volatile   int  maxThreadsWaiting  =   Integer . MAX_VALUE ;

     /**
     * The number of Xeq threads currently in existence.
     */

     protected   volatile   int  numThreadsCreated  =   0 ;

     /**
     * Whether the Xeq threads should continue.
     */

     protected   volatile   boolean  goOn  =   true ;

     /**
     * The maximum number of
     * threads that can be created at a time
     * to execute Runnable objects.
     * The default value is the largest
     * value an int can hold.
     */

     protected   volatile   int  maxThreadsCreated  =   Integer . MAX_VALUE ;

     /**
     * Whether to make the Xeq threads daemons.
     */

     protected   volatile   boolean  makeDaemon  =   true ;

     /**
     * The priority at which Xeq threads run.
     */

     protected   volatile   int  priority  =   Thread . NORM_PRIORITY ;

     /**
     * The number of milliseconds Xeq wait for something to run
     * before terminating themselves.
     */

     protected   volatile   long  waitTime  =   600000 ;   // 10 min.

     /**
     * Create a RunQueue with the default maximum number of
     * Xeq threads that can be created at a time
     * and a maximum number that can be waiting at any
     * one time for more Runnable objects to execute.
     */

     public   RunQueue ()   {
     }

     /**
     * Create a RunQueue with a specified maximum number of
     * Xeq threads that can be created at a time.
     *
     *  @param  maxCreatable Initial value for maxThreadsCreated.
     */

     public   RunQueue ( int  maxCreatable )   {
        maxThreadsCreated  =  maxCreatable ;
     }

     /**
     * Create a RunQueue with a specified maximum number of
     * Xeq threads that can be created at a time
     * and a maximum number that can be waiting at any
     * one time for more Runnable objects to execute.
     *
     *  @param  maxCreatable Initial value for maxThreadsCreated.
     *  @param  maxWaiting   Initial value for maxThreadsWaiting.
     */

     public   RunQueue ( int  maxCreatable ,   int  maxWaiting )   {
        maxThreadsCreated  =  maxCreatable ;
        maxThreadsWaiting  =  maxWaiting ;
     }

     /**
     * A thread that will dequeue and run Runnable objects in the
     * RunQueue.
     */

     protected   class   Xeq   extends   Thread   {
         public   void  run ()   {
             Runnable  r ;
             try   {
                 while   ( goOn )   {
                    r  =  dequeue ();
                    r . run ();
                 }
             }   catch   ( InterruptedException  ie )   { //nothing
             }   catch   ( Exception  e )   {
                e . printStackTrace ();
             }
            numThreadsCreated -- ;
         }
     }

     /**
     * Enqueue an object to be run when a thread becomes available.
     *
     *  @param  runnable The Runnable object to be enqueued for
     *                 execution.
     */

     public   void  put ( Runnable  runnable )   {
         boolean  createThread  =   false ;
         synchronized   ( this )   {
            runnables . put ( runnable );
             if   ( numThreadsWaiting  >   0 )   {
                numThreadsWaiting -- ;
                numNotifies ++ ;
                notify ();
             }   else   if   ( numThreadsCreated  <  maxThreadsCreated )   {
                numThreadsCreated ++ ;
                createThread  =   true ;
             }
         }
         if   ( createThread )   {
             Thread  t  =   new   Xeq ();
            t . setDaemon ( makeDaemon );
            t . setPriority ( priority );
            t . start ();
         }
     }

     /**
     * Same as put(runnable).
     *
     *  @param  runnable The Runnable object to be enqueued for
     *                 execution.
     */

     public   void  run ( Runnable  runnable )   {
        put ( runnable );
     }

     /**
     * Same as run(r). Runnable r is not delayed, but is run
     * immediately. This is provided to allow RunQueue to
     * implement RunDelayed, which can simplify algorithms
     * that build task graphs. Tasks can be generated that
     * are runDelayed on some condition. The initial tasks
     * can be automatically put in a RunQueue.
     *
     *  @param  r The runnable to be delayed.
     */

     public   void  runDelayed ( Runnable  r )   {
        run ( r );
     }

     /**
     * Removes and returns a Runnable object to be executed.
     * Called by an Xeq thread.<p>
     * Will wait for an object to run if the limit on waiting
     * threads hasn't been reached. If it has, dequeue will throw
     * an InterruptedException to kill the Xeq thread.
     *
     *  @throws  InterruptedException To kill the Xeq thread if the
     *                              limit of waiting threads has been reached and there are
     *                              no objects to run.
     */

     protected   synchronized   Runnable  dequeue ()
             throws   InterruptedException   {
         Runnable  runnable ;
         while   ( runnables . isEmpty ())   {
             if   ( numThreadsWaiting  <  maxThreadsWaiting )   {
                numThreadsWaiting ++ ;
                wait ( waitTime );
                 if   ( numNotifies  ==   0 )   {
                    numThreadsWaiting -- ;
                     throw   new   InterruptedException ();
                 }   else   {
                    numNotifies -- ;
                 }
             }   else   {   //terminate
                 throw   new   InterruptedException ();
             }
         }
        runnable  =   ( Runnable )  runnables . get ();
         return  runnable ;
     }

     /**
     * Set the limit on the number of threads created by this
     * RunQueue object that may be waiting at any one time to
     * run objects.
     *
     *  @param  n The new limit.
     */

     public   synchronized   void  setMaxThreadsWaiting ( int  n )   {
        maxThreadsWaiting  =  n ;
        numNotifies  +=  numThreadsWaiting ;
        numThreadsWaiting  =   0 ;
        notifyAll ();
     }

     /**
     * Set the limit on the number of threads that may be
     * created by this RunQueue object at any one time to
     * run objects.
     *
     *  @param  n The new limit.
     */

     public   void  setMaxThreadsCreated ( int  n )   {
        maxThreadsCreated  =  n ;
     }

     /**
     * Get the limit on the number of threads created to
     * process objects that may be waiting for
     * new objects to process.
     *
     *  @return  maxThreadsWaiting
     */

     public   int  getMaxThreadsWaiting ()   {
         return  maxThreadsWaiting ;
     }

     /**
     * Get the limit on the number of threads that may be created to
     * process objects.
     *
     *  @return  maxThreadsCreated
     */

     public   int  getMaxThreadsCreated ()   {
         return  maxThreadsCreated ;
     }

     /**
     * Get the number of threads that have been created
     * by this RunQueue to process objects and
     * which are waiting to process more such objects.
     *
     *  @return  numThreadsWaiting
     */

     public   int  getNumThreadsWaiting ()   {
         return  numThreadsWaiting ;
     }

     /**
     * Get the number of existing threads that have been created
     * by this RunQueue to process objects.
     *
     *  @return  numThreadsCreated
     */

     public   int  getNumThreadsCreated ()   {
         return  numThreadsCreated ;
     }

     /**
     * Same as setMaxThreadsWaiting(0). Any waiting user threads
     * would prevent the system from terminating. This does not
     * force the queue to stop running threads.
     */

     public   synchronized   void  terminate ()   throws   InterruptedException   {
        goOn  =   false ;
        setMaxThreadsWaiting ( 0 );
     }

     /**
     * Set the time limit an Xeq thread is to wait for a Runnable.
     *
     *  @param  n The new limit.
     */

     public   synchronized   void  setWaitTime ( long  n )   {
        waitTime  =  n ;
        numNotifies  +=  numThreadsWaiting ;
        numThreadsWaiting  =   0 ;
        notifyAll ();
     }

     /**
     * Get the time limit an Xeq thread is to wait for a Runnable.
     *
     *  @return  waitTime
     */

     public   synchronized   long  getWaitTime ()   {
         return  waitTime ;
     }

     /**
     * Set the priority at which the Runnables are to execute.
     *
     *  @param  n The new priority.
     */

     public   void  setPriority ( int  n )   {
        priority  =  n ;
     }

     /**
     * Get the priority at which the Runnables are to execute.
     *
     *  @return  priority
     */

     public   int  getPriority ()   {
         return  priority ;
     }

     /**
     * Set whether the created threads will be daemons.
     *
     *  @param  d True if the created threads are to be daemon
     *          threads; false if user threads.
     */

     public   void  setDaemon ( boolean  d )   {
        makeDaemon  =  d ;
     }

     /**
     * Find out whether the created threads are daemons.
     *
     *  @return  true if the created threads are daemons.
     */

     public   boolean  getDaemon ()   {
         return  makeDaemon ;
     }


}

jhpc/thread/Semaphore.java

jhpc/thread/Semaphore.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * A counting semaphore.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   Semaphore   {
     /**
     * The current count, which must be non-negative.
     */
     protected   int  count ;

     /**
     * Create a counting Semaphore with a specified initial count.
     *
     *  @param  initCount The initial value of count.
     *  @throws  com.toolsofcomputing.thread.NegativeSemaphoreException
     *          if initCount &lt; 0.
     */
     public   Semaphore ( int  initCount )
             throws   NegativeSemaphoreException   {
         if   ( initCount  <   0 )
             throw   new   NegativeSemaphoreException ();
        count  =  initCount ;
     }

     /**
     * Create a counting Semaphore with an initial count of zero.
     */
     public   Semaphore ()   {
        count  =   0 ;
     }

     /**
     * Subtract one from the count. Since count must be non-negative, wait until
     * count is positive before decrementing it.
     *
     *  @throws  InterruptedException if thread is interrupted while waiting.
     */
     public   synchronized   void  down ()
             throws   InterruptedException   {
         while   ( count  ==   0 )  wait ();
        count -- ;
     }

     /**
     * Add one to the count. Wake up a thread waiting to "down" the semaphore, if any.
     */
     public   synchronized   void  up ()   {
        count ++ ;
        notify ();
     }
}

jhpc/thread/SharedTableOfQueues.java

jhpc/thread/SharedTableOfQueues.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

import  java . util . Hashtable ;

/**
 * Provide a shared table of queues for thread communication. This
 * combines two of the most useful thread communication data structures:
 * directories and queues.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   SharedTableOfQueues   {
     /**
     * The table used to hold the shared queues.
     */
     Hashtable  tbl  =   new   Hashtable ();

     /**
     * The FutureFactory to use when creating futures in the contained
     * FutureQueues.
     */
     FutureFactory  ff  =   null ;

     /**
     * The default constructor, which uses the default FutureFactory.
     */
     public   SharedTableOfQueues ()   {
        ff  =   new   FutureFactory ();
     }

     /**
     * The constructor that uses an explicit FutureFactory.
     *
     *  @param  f The FutureFactory to use.
     */
     public   SharedTableOfQueues ( FutureFactory  f )   {
        ff  =  f ;
     }

     /**
     * The constructor that uses an explicit RunQueue in its future factory.
     *
     *  @param  rq The RunQueue to use it its FutureFactory.
     */
     public   SharedTableOfQueues ( RunQueue  rq )   {
        ff  =   new   FutureFactory ( rq );
     }

     /**
     * Look up the FutureQueue associated with key in tbl, creating one
     * and inserting it into tbl if none is present.
     */
     protected   synchronized   FutureQueue  getQueue ( Object  key )   {
         FutureQueue  f ;
        f  =   ( FutureQueue )  tbl . get ( key );
         if   ( ==   null )  tbl . put ( key ,  f  =   new   FutureQueue ());
         return  f ;
     }

     /**
     * Put an object, <i>value</i>, into the queue with name <i>key</i>. Create a queue
     * with name <i>key</i> if not already present.
     *
     *  @param  key   The name of the queue.
     *  @param  value The value to put in.
     */

     public   void  put ( Object  key ,   Object  value )   {
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
            q . put ( value );
             if   ( q . isVacant ())  tbl . remove ( key );
         }
     }

     /**
     * Remove and return an object from the queue named <i>key</i>. If the queue is
     * empty, wait for an object to be put into the queue.
     *
     *  @param  key The name of the queue.
     *  @return  The object removed from the queue.
     *  @throws  InterruptedException If interrupted while waiting.
     */

     public   Object  get ( Object  key )   throws   InterruptedException   {
         Future  f ;
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
            f  =  q . get ();
             if   ( q . isVacant ())  tbl . remove ( key );
         }
         return  f . getValue ();
     }

     /**
     * Return a reference to the first object in the queue named <i>key</i>.
     * If the queue is empty, wait for an object to be put into the queue.
     * The object is not removed from the queue.
     *
     *  @param  key The name of the queue.
     *  @return  The object removed from the queue.
     *  @throws  InterruptedException If interrupted while waiting.
     */

     public   Object  look ( Object  key )   throws   InterruptedException   {
         Future  f ;
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
            f  =  q . look ();
         }
         return  f . getValue ();
     }


     /**
     * Test whether the FutureQueue associated with <i>key</i> is empty.
     *
     *  @param  key The name of the queue.
     *  @return  true if the queue is empty (or not present), false otherwise.
     */

     public   boolean  isEmpty ( Object  key )   {
         synchronized   ( this )   {
             if   ( tbl . get ( key )   ==   null )   return   true ;
             FutureQueue  q  =  getQueue ( key );
             return  q . isEmpty ();
         }
     }


     /**
     * Get a Future by calling get()in the FutureQueue.
     * named <i>key</i>.
     *
     *  @param  key The name of the queue.
     *  @return  The Future from the queue.
     */

     public   Object  getFuture ( Object  key )   {
         Future  f ;
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
            f  =  q . get ();
             if   ( q . isVacant ())  tbl . remove ( key );
         }
         return  f ;
     }

     /**
     * Return a reference by calling look() in the FutureQueue.
     * named <i>key</i>.
     *
     *  @param  key The name of the queue.
     *  @return  The Future from the queue.
     */

     public   Object  lookFuture ( Object  key )   {
         return  getQueue ( key ). look ();
     }

     /**
     * Remove and return an object from the queue named <i>key</i>. If the queue is
     * empty, return null immediately.
     *
     *  @param  key The name of the queue.
     *  @return  The object removed from the queue or null if the queue is empty.
     */

     public   Object  getSkip ( Object  key )   {
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
             Object  value  =  q . getSkip ();
             if   ( q . isVacant ())  tbl . remove ( key );
             return  value ;
         }
     }

     /**
     * Return a reference to the first object in the queue named <i>key</i>.
     * If the queue is empty, return null immediately.
     * The object is not removed from the queue.
     *
     *  @param  key The name of the queue.
     *  @return  The object removed from the queue or null if the queue is empty.
     */

     public   Object  lookSkip ( Object  key )   {
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
             return  q . lookSkip ();
         }
     }

     /**
     * Execute the <i>run()</i> method in Runnable object <i>r</i> in a new
     * thread as soon as the queue named <i>key</i> is non-empty. Method
     * <i>runDelayed()</i> returns immediately.
     *
     *  @param  key The name of the queue.
     *  @param  r   The Runnable object to run in a new thread.
     */

     public   void  runDelayed ( Object  key ,   Runnable  r )   {
         Future  f  =   null ;
         synchronized   ( this )   {
             FutureQueue  q  =  getQueue ( key );
            f  =  q . look ();
         }
        f . runDelayed ( r );
     }
}

jhpc/thread/SharedTerminationGroup.java

jhpc/thread/SharedTerminationGroup.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Termination Group for a shared memory system.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   SharedTerminationGroup
         implements   TerminationGroup   {
     int  count ;
     Future  f ;

     public   SharedTerminationGroup ( Future  f )   {
        count  =   1 ;
         this . =  f ;
     }

     public   SharedTerminationGroup ()   {
        count  =   1 ;
         this . =   new   Future ();
     }

     /**
     * Adds another element to a termination group.
     */

     public   synchronized   TerminationGroup  fork ()   {
        count ++ ;
         return   this ;
     }

     /**
     * Terminate this element of the termination group.
     */

     public   synchronized   void  terminate ()   {
        count -- ;
         if   ( count  ==   0 )  f . setValue ( null );
     }

     /**
     * Waits for all elements of a termination group to terminate.
     * Blocks a thread.
     */

     public   void  awaitTermination ()   throws   InterruptedException   {
        f . getValue ();
     }

     /**
     * Delay the runnable r until all elements of the group
     * have terminated.
     *
     *  @param  r The runnable to be delayed.
     */

     public   void  runDelayed ( Runnable  r )   {
        f . runDelayed ( r );
     }
}

jhpc/thread/SharedTerminationGroupFactory.java

jhpc/thread/SharedTerminationGroupFactory.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * Factory to create TerminationGroup objects for a shared memory system.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   SharedTerminationGroupFactory
         implements   TerminationGroupFactory   {


     /**
     * The FutureFactory to create Futures for SharedTerminationGroups.
     */

     protected   FutureFactory  futureFactory  =   null ;

     /**
     * Create a SharedTerminationGroupFactory.
     *
     *  @param  futureFactory The FutureFactory to create futures.
     */

     public   SharedTerminationGroupFactory ( FutureFactory  futureFactory )   {
         super ();
         this . futureFactory  =  futureFactory ;
     }

     /**
     * Get the FutureFactory for a SharedTerminationGroupFactory object.
     *
     *  @return  The FutureFactory that will create a Future object for a
     *         termination group.
     */

     public   FutureFactory  getFutureFactory ()   {
         return  futureFactory ;
     }

     /**
     * Set the FutureFactory for a SharedTerminationGroupFactory object.
     */

     public   void  setFutureFactory ( FutureFactory  futureFactory )   {
         this . futureFactory  =  futureFactory ;
     }

     /**
     * Create a SharedTerminationGroup.
     */

     public   SharedTerminationGroup  make ()   {
         return   new   SharedTerminationGroup ( futureFactory . make ());
     }
}

jhpc/thread/SimpleBarrier.java

jhpc/thread/SimpleBarrier.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Allows multiple threads to gather at a point before proceeding.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   SimpleBarrier   {
     /**
     * Number of threads that still must gather.
     */
     protected   int  count ;
     /**
     * Total number of threads that must gather.
     */
     protected   int  initCount ;

     /**
     * Creates a Barrier at which n threads may repeatedly gather.
     *
     *  @param  n total number of threads that must gather.
     */

     public   SimpleBarrier ( int  n )   {
         if   ( <=   0 )
             throw
                     new   IllegalArgumentException ( "Barrier initialization specified non-positive value "
                     +  n );
        initCount  =  count  =  n ;
     }

     /**
     * Is called by a thread to wait for the rest of the n threads to gather
     * before the set of threads may continue executing.
     *
     *  @throws  InterruptedException If interrupted while waiting.
     */
     public   synchronized   void  gather ()
             throws   InterruptedException   {
         if   ( -- count  >   0 )
            wait ();
         else   {
            count  =  initCount ;
            notifyAll ();
         }
     }
}

jhpc/thread/SimpleFuture.java

jhpc/thread/SimpleFuture.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * An assign-once variable that allows consumers to wait for a value to be produced.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   SimpleFuture   {
     /**
     * The assign-once variable.
     */
     protected   Object  value ;

     /**
     * Create a SimpleFuture with no value yet assigned.
     */
     public   SimpleFuture ()   {
        value  =   this ;
     }

     /**
     * Create a SimpleFuture with a value initially assigned.
     *
     *  @param  val The value the SimpleFuture is to be initialized with.
     */
     public   SimpleFuture ( Object  val )   {
        value  =  val ;
     }

     /**
     * Waits until a value has been assigned to the SimpleFuture, then returns it.
     *
     *  @return  The value assigned.
     *  @throws  InterruptedException if the thread is interrupted while waiting
     *                              for a value to be assigned.
     */
     public   synchronized   Object  getValue ()
             throws   InterruptedException   {
         while   ( value  ==   this )  wait ();
         return  value ;
     }

     /**
     * Checks to see if a value has been assigned to the SimpleFuture yet.
     *
     *  @return  true if value has been assigned, false otherwise.
     */
     public   synchronized   boolean  isSet ()   {
         return   ( value  !=   this );
     }

     /**
     * Assigns a value to the SimpleFuture and notifies all waiting threads.
     * Attempts to change a previously assigned value will be ignored.
     *
     *  @param  val The value to be assigned to the SimpleFuture.
     */
     public   synchronized   void  setValue ( Object  val )   {
         if   ( value  !=   this )   return ;
        value  =  val ;
        notifyAll ();
     }

}

jhpc/thread/Suspension.java

jhpc/thread/Suspension.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * A suspended computation which will compute a value and
 * assign it to a Future when the value is demanded.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   class   Suspension   implements   Runnable   {
     /**
     * The Future.
     */
     protected   Future  future  =   null ;
     /**
     * The Runnable object to compute tha value of the Future
     * if it is demanded.
     */
     protected   Runnable  runnable  =   null ;

     /**
     * Create a Suspension.
     */
     public   Suspension ()   {
     }

     /**
     * Create a Suspension with a runnable object to compute its
     * value initially assigned.
     *
     *  @param  r The object that can compute the value of the suspension.
     */
     public   Suspension ( Runnable  r )   {
        runnable  =  r ;
     }

     /**
     * Returns the Future associated with the Suspension.
     *
     *  @return  The associated Future.
     */
     public   synchronized   Future  getFuture ()   {
         if   ( future  ==   null )  future  =   new   Future ();
         if   ( runnable  !=   null   &&  runnable  !=   this )   {
            future . getRunQueue (). run ( runnable );
            runnable  =   this ;
         }
         return  future ;
     }

     /**
     * Waits until a value has been assigned to the Suspension, then
     * returns it.
     *
     *  @return  The value assigned.
     *  @throws  InterruptedException if the thread is interrupted
     *                              while waiting for a value to be assigned.
     */
     public   Object  getValue ()   throws   InterruptedException   {
         return  getFuture (). getValue ();
     }

     /**
     * Assigns a value to the Future and notifies all waiting threads.
     * Attempts to change a previously assigned value will be ignored.
     *
     *  @param  value The value to be assigned to the Future.
     */
     public   synchronized   void  setValue ( Object  value )   {
        runnable  =   this ;
        getFuture (). setValue ( value );
     }

     /**
     * Force the suspension to be executed. (The runnable object, that is,
     * that is supposed to assign a value to the suspension's Future.)
     */
     public   void  run ()   {
        getFuture ();
     }

     /**
     * Schedule a runnable object to execute when the suspension has
     * its value demanded (by run(), getValue(), or getFuture()).
     */
     public   void  runOnDemand ( Runnable  r )   {
         if   ( runnable  ==   null )   {
             if   ( future  !=   null )   {
                future . getRunQueue (). run ( r );
                runnable  =   this ;
             }   else
                runnable  =  r ;
         }
     }
}

jhpc/thread/TerminationGroup.java

jhpc/thread/TerminationGroup.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;

/**
 * Interface implemented by Termination Groups.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   interface   TerminationGroup   extends   RunDelayed   {

     /**
     * Adds another element to a termination group.
     */

     public   TerminationGroup  fork ();

     /**
     * Terminate this element of the termination group.
     */

     public   void  terminate ();

     /**
     * Waits for all elements of a termination group to terminate.
     * Blocks a thread.
     */

     public   void  awaitTermination ()   throws   InterruptedException ;

     /**
     * Delay the runnable r until all elements of the group
     * have terminated.
     *
     *  @param  r The runnable to be delayed.
     */

     public   void  runDelayed ( Runnable  r );

}

jhpc/thread/TerminationGroupFactory.java

jhpc/thread/TerminationGroupFactory.java

/*
Copyright (c) 2000, Thomas W. Christopher and George K. Thiruvathukal

Java and High Performance Computing (JHPC) Organzization
Tools of Computing LLC

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

The names Java and High-Performance Computing (JHPC) Organization,
Tools of Computing LLC, and/or the names of its contributors may not
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This license is based on version 2 of the BSD license. For more
information on Open Source licenses, please visit
http://opensource.org.
*/


package  info . jhpc . thread ;


/**
 * An factory to create termination groups.
 *
 *  @author  Thomas W. Christopher (Tools of Computing LLC)
 *  @version  0.2 Beta
 */

public   interface   TerminationGroupFactory   {

     /**
     * Create a SharedTerminationGroup.
     */

     public   SharedTerminationGroup  make ();
}