001 // RefList.java, created by wbeebee 002 // Copyright (C) 2002 Wes Beebee <wbeebee@mit.edu> 003 // Licensed under the terms of the GNU GPL; see COPYING for details. 004 package javax.realtime; 005 006 import java.util.Iterator; 007 import java.util.NoSuchElementException; 008 009 /** The goal here is to make a thread list that's accessable from a NoHeapRealtimeThread that keeps 010 * all the relevant information about the threads accessable to the scheduler. 011 * Therefore, all memory allocations/deallocations must be made explicit. 012 * RefCountAreas are explicitly unsafe currently - an interesting research project to make them safe. 013 */ 014 class RefList { 015 final RefCountArea ref = RefCountArea.refInstance(); 016 017 class Elt { 018 Object obj; 019 Elt next; 020 boolean beingRemoved = false; 021 022 /** <code>Obj</code> is assumed to have refCount == 1. 023 * It's not kosher to share between lists. 024 * Once an object is removed from the list, it is DEAD! 025 */ 026 027 Elt(Object obj, Elt next) { 028 if (next != null) RefList.this.ref.INCREF(next); 029 this.obj = obj; 030 this.next = next; 031 } 032 } 033 034 Elt elt = null; 035 036 public RefList() { 037 } 038 039 public void add(final Object o) { 040 ref.enter(new Runnable() { // These Runnables cause a memory leak... 041 public void run() { 042 elt = new Elt(o, elt); 043 } 044 }); 045 } 046 047 public void add(final long l) { 048 ref.enter(new Runnable() { 049 public void run() { 050 elt = new Elt(new Long(l), elt); 051 } 052 }); 053 } 054 055 public void remove(final Object o) { 056 Elt prev = elt; 057 for (Elt e = elt; e != null; prev = e, e = e.next) { 058 if (o.equals(e.obj)) { 059 if (prev == elt) { 060 elt = elt.next; 061 // ref.DECREF(prev); 062 } else { 063 prev.next = elt.next; 064 // ref.DECREF(elt); 065 // ref.DECREF(elt); 066 } 067 break; 068 } 069 } 070 } 071 072 public void remove(final long lo) { 073 Elt prev = elt; 074 for (Elt e = elt; e != null; prev = e, e = e.next) { 075 if ((e.obj instanceof Long)&&(((Long)e.obj).longValue()==lo)) { 076 if (e == elt) { 077 elt = elt.next; 078 // ref.DECREF(prev); 079 } else { 080 prev.next = e.next; 081 // ref.DECREF(elt); 082 // ref.DECREF(elt); 083 } 084 break; 085 } 086 } 087 } 088 089 public boolean contains(final Object o) { 090 for (Elt e = elt; e != null; e = e.next) 091 if (o.equals(e.obj)) return true; 092 return false; 093 } 094 095 public boolean contains(final long lo) { 096 for (Elt e = elt; e != null; e = e.next) 097 if ((e.obj instanceof Long)&&(((Long)e.obj).longValue()==lo)) return true; 098 return false; 099 } 100 101 public boolean isEmpty() { 102 return elt == null; 103 } 104 105 public long length() { 106 int i = 0; 107 for (Elt e = elt; e != null; e = e.next) i++; 108 return i; 109 } 110 111 public Iterator iterator() { 112 class RefListIterator implements Iterator { 113 private Elt prev; 114 private Elt curr; 115 116 public RefListIterator() { 117 if ((prev = curr = elt) != null) { 118 ref.INCREF(curr); 119 } 120 } 121 122 /** Warning: not thread safe under mutation! */ 123 public boolean hasNext() { 124 return curr != null; 125 } 126 127 public Object next() throws NoSuchElementException { 128 RefCountArea ref = RefList.this.ref; 129 if (curr == null) { 130 throw new NoSuchElementException(); 131 } 132 if (curr.beingRemoved) { 133 Elt newElt = curr.next; 134 if (newElt != null) { 135 ref.INCREF(newElt); 136 } 137 // ref.DECREF(curr); 138 curr = newElt; 139 return next(); 140 } 141 Elt newElt = curr.next; 142 if (newElt != null) { 143 ref.INCREF(newElt); 144 } 145 Object obj = curr.obj; 146 // ref.DECREF(prev = curr); 147 curr = newElt; 148 return obj; 149 } 150 151 public void remove() { 152 throw new UnsupportedOperationException("Not implemented!"); 153 } 154 } 155 return new RefListIterator(); 156 } 157 158 public Iterator roundIterator() { 159 class RefListIterator implements Iterator { 160 private Elt prev; 161 private Elt curr; 162 163 public RefListIterator() { 164 if ((prev = curr = RefList.this.elt) != null) { 165 ref.INCREF(curr); 166 } 167 } 168 169 /** Warning: not thread safe under mutation! */ 170 public boolean hasNext() { 171 return !RefList.this.isEmpty(); 172 } 173 174 public Object next() throws NoSuchElementException { 175 RefCountArea ref = RefList.this.ref; 176 if (!hasNext()) { 177 throw new NoSuchElementException(); 178 } 179 if (curr == null) { 180 if ((prev = curr = RefList.this.elt) != null) { 181 ref.INCREF(curr); 182 } 183 return next(); 184 } 185 if (curr.beingRemoved) { 186 Elt newElt = curr.next; 187 if (newElt != null) { 188 ref.INCREF(newElt); 189 } 190 // ref.DECREF(curr); 191 curr = newElt; 192 return next(); 193 } 194 Elt newElt = curr.next; 195 if (newElt != null) { 196 ref.INCREF(newElt); 197 } 198 Object obj = curr.obj; 199 // ref.DECREF(prev = curr); 200 curr = newElt; 201 return obj; 202 } 203 204 public void remove() { 205 throw new UnsupportedOperationException("Not implemented!"); 206 } 207 } 208 return new RefListIterator(); 209 } 210 211 public String toString() { 212 String s = "["; 213 try { 214 Iterator it = iterator(); 215 while (true) s += it.next(); 216 } catch (NoSuchElementException e) { 217 return s+"]"; 218 } 219 } 220 } 221