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