Package javolution.context

Source Code of javolution.context.ImmortalContext$ImmortalAllocator

/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2007 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.context;

import java.lang.ThreadLocal;
import javax.realtime.MemoryArea;
import javolution.util.FastMap;
import javolution.util.FastTable;

/**
* <p> This class represents an allocator from immortal memory (RTSJ).</p>
*
* <p> It is typically used to allocate (and recycle) from immortal memory
*     allowing dynamically created static instances to be accessible by
*     <code>NoHeapRealtimeThread</code>:[code]
*         public synchronized Text intern() {
*             if (!INTERN_INSTANCES.containsKey(this)) {
*                 ImmortalContext.enter();
*                 try { // Forces interned instance to be in immortal memory.
*                     Text txt = this.copy(); // In ImmortalMemory.
*                     INTERN_INSTANCES.put(txt, txt);
*                 } finally {
*                     ImmortalContext.exit();
*                 }
*             }
*             return (Text) INTERN_INSTANCES.get(str);
*         }[/code]</p>
* <p> Because class initialization may occur while running in a non-heap
*     context, it is recommended to force factory produced constants
*     to immortal memory:[code]
*         public class Rational {
*             public static final Rational ZERO;
*             public static final Rational ONE;
*             ...
*             static { // Forces constants to ImmortalMemory.
*                 ImmortalContext.enter();
*                 try {
*                     ZERO = Rational.valueOf(0, 1); // Factory produced.
*                     ONE = Rational.valueOf(1, 1); // Factory produced.
*                 } finally {
*                     ImmortalContext.exit();
*                 }
*             }
*        }[/code]</p>
*       
* @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 5.2, August 19, 2007
*/
public final class ImmortalContext extends AllocatorContext {

    /**
     * Holds the factory to allocator mapping (per thread).
     */
    private static final ThreadLocal FACTORY_TO_ALLOCATOR = new ThreadLocal() {

        protected Object initialValue() {
            return new FastMap();
        }
    };
    /**
     * Holds the allocators which have been activated (per thread).
     */
    private static final ThreadLocal ACTIVE_ALLOCATORS = new ThreadLocal() {

        protected Object initialValue() {
            return new FastTable();
        }
    };

    /**
     * Enters an immortal memory context.
     */
    public static void enter() {
         Context.enter(ImmortalContext.class);
    }

    /**
     * Exits the current immortal memory context.
     *
     * @throws ClassCastException if the context is not an immortal context.
     */
    public static void exit() {
        Context.exit(ImmortalContext.class);
    }

    /**
     * Default constructor (private, instances are factory produced).
     */
    private ImmortalContext() {
    }

    // Overrides.
    protected void deactivate() {
        FastTable allocators = (FastTable) ACTIVE_ALLOCATORS.get();
        for (int i = 0, n = allocators.size(); i < n;) {
            ((Allocator) allocators.get(i++)).user = null;
        }
        allocators.clear();
    }

    // Overrides.
    protected Allocator getAllocator(ObjectFactory factory) {
        final FastMap factoryToAllocator = (FastMap) FACTORY_TO_ALLOCATOR.get();
        ImmortalAllocator allocator = (ImmortalAllocator) factoryToAllocator.get(factory);
        if (allocator == null) {
            allocator = new ImmortalAllocator(factory);
            factoryToAllocator.put(factory, allocator);
        }
        if (allocator.user == null) { // Activate.
            allocator.user = Thread.currentThread();
            FastTable activeAllocators = (FastTable) ACTIVE_ALLOCATORS.get();
            activeAllocators.add(allocator);
        }
        return allocator;
    }

    // Overrides.
    protected void enterAction() {
        getOuter().getAllocatorContext().deactivate();
    }

    // Overrides.
    protected void exitAction() {
        this.deactivate();
    }

    // Holds immortal allocator implementation.
    private static final class ImmortalAllocator extends Allocator {

        private static final MemoryArea IMMORTAL = MemoryArea.getMemoryArea("");
        private final ObjectFactory _factory;
        private Object _allocated;

        public ImmortalAllocator(ObjectFactory factory) {
            _factory = factory;
        }
        private final Runnable _allocate = new Runnable() {

            public void run() {
                _allocated = _factory.create();
            }
        };
        private final Runnable _resize = new Runnable() {

            public void run() {
                resize();
            }
        };

        protected Object allocate() {
            IMMORTAL.executeInArea(_allocate);
            return _allocated;
        }

        protected void recycle(Object object) {
            if (_factory.doCleanup())
                _factory.cleanup(object);
            if (queueSize >= queue.length)
                IMMORTAL.executeInArea(_resize);
            queue[queueSize++] = object;
        }

        public String toString() {
            return "Immortal allocator for " + _factory.getClass();
        }
    }

    // Allows instances to be factory produced (private constructor).
    static {
        ObjectFactory.setInstance(new ObjectFactory() {

            protected Object create() {
                return new ImmortalContext();
            }
        }, ImmortalContext.class);
    }
}
TOP

Related Classes of javolution.context.ImmortalContext$ImmortalAllocator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.