001    // MemAreaStack.java, created by wbeebee
002    // Copyright (C) 2001 Wes Beebee <wbeebee@mit.edu>
003    // Licensed under the terms of the GNU GPL; see COPYING for details.
004    package javax.realtime;
005    
006    /** <code>MemAreaStack</code> can be used to create a tree of MemoryArea
007     *  references to determine whether a ScopedMemory check fails.  This is
008     *  the same cactus stack that is used to determine which MemoryArea x 
009     *  RealtimeThread MemBlock to enter for the constructor of a .newArray'ed
010     *  or a newInstance'd object.
011     * @author Wes Beebee <<a href="mailto:wbeebee@mit.edu">wbeebee@mit.edu</a>>
012     */
013    
014    class MemAreaStack {
015        /** A MemoryArea on the stack 
016         */
017        public MemoryArea entry, original;
018    
019        /** The "next" pointer for the stack.
020         */
021        public MemAreaStack next;
022    
023        /** Push the MemoryArea on the cactus stack. 
024         */
025        public MemAreaStack(MemoryArea entry, MemoryArea original, MemAreaStack next) {
026            this.entry = entry;
027            this.original = original;
028            this.next = next;
029        }
030    
031        public static MemAreaStack PUSH(MemoryArea entry, MemoryArea original, 
032                                        MemAreaStack next) {
033            RealtimeThread.checkInit();
034            RefCountArea ref = RefCountArea.refInstance();
035            Object mas = null;
036            if ((next != null) && (next.memoryArea == ref)) ref.INCREF(next);
037            if ((entry != null) && (entry.memoryArea == ref)) ref.INCREF(entry);
038            if ((original != null) && (original.memoryArea == ref)) ref.INCREF(original);
039            try {
040                mas = ref.newInstance(MemAreaStack.class, 
041                                      new Class[] { MemoryArea.class, MemoryArea.class,
042                                                    MemAreaStack.class },
043                                      new Object[] { entry, original, next});
044            } catch (Exception e) {
045                NoHeapRealtimeThread.print(e.toString());
046                System.exit(-1);
047            }
048            mas.memoryArea = ref;
049            return (MemAreaStack)mas;
050        }
051    
052        public static MemAreaStack POP(MemAreaStack top) {
053            MemAreaStack next = top.next;
054            RefCountArea ref = RefCountArea.refInstance();
055            if (top.memoryArea == ref) ref.DECREF(top);
056            return next;
057        }
058    
059        /** Get the MemAreaStack of the first occurance of the 
060         *  MemoryArea mem, or null if it is not found.
061         */
062        public MemAreaStack first(MemoryArea mem) {
063            MemAreaStack current = this;
064            
065            while (current != null) {
066                if (current.entry == mem) {
067                    return current;
068                }
069                current = current.next;
070            }
071    
072            return null;
073        }
074        
075        /** Dump a description of each MemoryArea on the stack. 
076         */
077        public String toString() {
078            if (next != null) {
079                return entry.toString()+"\n"+next.toString();
080            } else {
081                return entry.toString();
082            }
083        }
084    }