001    package javax.realtime;
002    
003    /** The wait-free classes facilitate communication and synchronization
004     *  between instances of <code>RealtimeThread</code> and <code>Thread</code>.
005     */
006    public class WaitFreeDequeue {
007    
008        protected Object[] queue = null;
009        protected int queueSize;
010        protected int currentIndex = 0;
011        
012        protected Thread writerThread = null, readerThread = null;
013        protected MemoryArea memArea;
014    
015        /** A queue with unsynchronized and nonblocking <code>read()</code>
016         *  and <code>write()</code> methods and synchronized and blocking
017         *  <code>read()</code> and <code>write()</code> methods.
018         *
019         *  @param writer An instance of <code>Thread</code>.
020         *  @param reader An instance of <code>Thread</code>.
021         *  @param maximum The maximum number of elements in both the
022         *                 <code>WaitFreeReadQueue</code> and the
023         *                 <code>WaitFreeWriteQueue</code>.
024         *  @param area The <code>MemoryArea</code> in which this object and
025         *              internal elements are allocated
026         *  @throws java.lang.IllegalArgumentException If an argument holds an
027         *                                             invalid value. The current
028         *                                             memory areas of
029         *                                             <code>writer</code>,
030         *                                             <code>reader</code>, and
031         *                                             <code>memory</code> must be
032         *                                             compatible with respect to
033         *                                             the assignment and access
034         *                                             rules for memory areas.
035         */
036        public WaitFreeDequeue(Thread writer, Thread reader,
037                               int maximum, MemoryArea area)
038            throws IllegalArgumentException {
039            writerThread = writer;
040            readerThread = reader;
041            queueSize = maximum;
042            memArea = area;
043    
044            // TODO (?)
045        }
046    
047        /** Used to check if the queue is empty.
048         *
049         *  @return True, if the queue is empty. False, if it is not.
050         */
051        private boolean isEmpty() {
052            return (currentIndex == 0);
053        }
054    
055        /** Used to check if the queue is full.
056         *
057         *  @return True, if the queue is full. False, if it is not.
058         */
059        private boolean isFull() {
060            return (currentIndex == queueSize - 1);
061        }
062    
063        /** A synchronized call of the <code>read()</code> method of the
064         *  underlying <code>WaitFreeWriteQueue</code>. This call blocks on
065         *  queue empty and will wait until there is an element in the queue
066         *  to return.
067         *
068         *  @return The <code>java.lang.Object</code> read.
069         */
070        public synchronized Object blockingRead() {
071            while (isEmpty())
072                try {
073                    Thread.sleep(100);
074                } catch (Exception e) {};
075            
076            Object temp = queue[0];
077            for (int i = 0; i < currentIndex; i++)
078                queue[i] = queue[i+1];
079            currentIndex--;
080            return temp;
081        }
082    
083        /** A synchronized call of the <code>write()</code> method of the
084         *  underlying <code>WaitFreeReadQueue</code>. This call blocks on
085         *  queue full and waits until there is space in <code>this</code>.
086         *
087         *  @param object The <code>java.lang.Object</code> to place in
088         *                <code>this</code>.
089         *  @return True, if the write succeeded. False, if not.
090         *  @throws MemoryScopeException If the write causes an access or
091         *                               assignment violation.
092         */
093        public synchronized boolean blockingWrite(Object object)
094            throws MemoryScopeException {
095            while (isFull())
096                try {
097                    Thread.sleep(100);
098                } catch (Exception e) {};
099    
100            queue[++currentIndex] = object;
101            return true;
102        }
103    
104        /** If <code>this</code> is full then this call overwrites the
105         *  last object written to <code>this</code> with the given
106         *  object. If this is not full this call is equivalent to the
107         *  <code>nonBlockingWrite()</code> call.
108         *
109         *  @param object The <code>java.lang.Object which will overwrite
110         *                the last object if <code>this</code> is full.
111         *                Otherwise <code>object</code> will be placed in
112         *                <code>this</code.
113         *  @return True, if an element was overwritten. False, if there
114         *          is an empty element into which the write occured.
115         */
116        public boolean force(Object object) {
117            if (!isFull()) {
118                boolean b = false;
119                try {
120                    b = nonBlockingWrite(object);
121                } catch (Exception e) {}
122                return b;
123            }
124            else {
125                queue[currentIndex] = object;
126                return true;
127            }
128        }
129    
130        /** An unsynchronized call of the <code>read()</code> method of the
131         *  underlying <code>WaitFreeReadQueue</code>.
132         *
133         *  @return A <code>java.lang.Object</code> object read from
134         *          <code>this</code>. If there are no elements in
135         *          <code>this</code> then null is returned.
136         */
137        public Object nonBlockingRead() {
138            if (isEmpty()) return null;
139            else {
140                Object temp = queue[0];
141                for (int i = 0; i < currentIndex; i++)
142                    queue[i] = queue[i+1];
143                currentIndex--;
144                return temp;
145            }
146        }
147    
148        /** An unsynchronized call of the <code>write()</code> method of the
149         *  underlying <code>WaitFreeWriteQueue</code>. This call does not
150         *  block on queue full.
151         *
152         *  @param object The <code>java.lang.Object</code> to attempt to
153         *                place in <code>this</code>.
154         *  @return True, if the object is now in <code>this</code>, otherwise
155         *          returns false.
156         *  @throws MemoryScopeException If the write causes an access or
157         *                               assignment violation.
158         */
159        public boolean nonBlockingWrite(Object object)
160            throws MemoryScopeException {
161            if (isFull()) return false;
162            else {
163                queue[++currentIndex] = object;
164                return true;
165            }
166        }
167    }