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 }