Package com.jogamp.opencl.util.concurrent

Source Code of com.jogamp.opencl.util.concurrent.CLForkJoinPool$CLThreadFactory

/*
* Copyright (c) 2011, Michael Bien
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*    1. Redistributions of source code must retain the above copyright notice, this list of
*       conditions and the following disclaimer.
*
*    2. Redistributions in binary form must reproduce the above copyright notice, this list
*       of conditions and the following disclaimer in the documentation and/or other materials
*       provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/*
* Created on Tuesday, August 02 2011 01:53
*/
package com.jogamp.opencl.util.concurrent;

import com.jogamp.opencl.CLCommandQueue;
import com.jogamp.opencl.CLDevice;
import com.jogamp.opencl.util.CLMultiContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.Future;

/**
* A multithreaded, fixed size pool of OpenCL command queues supporting fork-join tasks.
* <p>
* The usage is similar to {@link ForkJoinPool} but uses {@link CLRecursiveTask}s.
* </p>
* @see CLRecursiveTask
* @author Michael Bien
*/
public class CLForkJoinPool extends CLExecutorService {

    private CLForkJoinPool(ExecutorService executor, List<CLCommandQueue> queues) {
        super(executor, queues);
    }

    public static CLForkJoinPool create(CLMultiContext mc, CLCommandQueue.Mode... modes) {
        return create(mc.getDevices(), modes);
    }

    public static CLForkJoinPool create(Collection<? extends CLDevice> devices, CLCommandQueue.Mode... modes) {
        List<CLCommandQueue> queues = new ArrayList<CLCommandQueue>(devices.size());
        for (CLDevice device : devices) {
            queues.add(device.createCommandQueue(modes));
        }
        return create(queues);
    }

    public static CLForkJoinPool create(Collection<CLCommandQueue> queues) {

        List<CLCommandQueue> list = new ArrayList<CLCommandQueue>(queues);

        CLThreadFactory factory = new CLThreadFactory(list);
        int size = list.size();

        ExecutorService service = new ForkJoinPool(size, factory, null, false);
        return new CLForkJoinPool(service, list);
    }

    /**
     * Performs the given task, returning its result upon completion.
     * @see ForkJoinPool#invoke(java.util.concurrent.ForkJoinTask)
     */
    public <R> R invoke(CLRecursiveTask<? extends CLQueueContext, R> task) {
        // shortcut, prevents redundant wrapping
        return getExcecutor().invoke(task);
    }

    /**
     * Submits this task to the pool for execution returning its {@link Future}.
     * @see ForkJoinPool#submit(java.util.concurrent.ForkJoinTask)
     */
    public <R> Future<R> submit(CLRecursiveTask<? extends CLQueueContext, R> task) {
        // shortcut, prevents redundant wrapping
        return getExcecutor().submit(task);
    }

    @Override
    ForkJoinPool getExcecutor() {
        return (ForkJoinPool) super.getExcecutor();
    }

    /**
     * Returns an estimate of the total number of tasks stolen from
     * one thread's work queue by another.
     * @see ForkJoinPool#getStealCount()
     */
    public long getStealCount() {
        return getExcecutor().getStealCount();
    }

    /**
     * Returns an estimate of the number of tasks submitted to this
     * pool that have not yet begun executing. This method may take
     * time proportional to the number of submissions.
     * @see ForkJoinPool#getQueuedSubmissionCount()
     */
    public int getQueuedSubmissionCount() {
        return getExcecutor().getQueuedSubmissionCount();
    }

    /**
     * Returns an estimate of the total number of tasks currently held
     * in queues by worker threads (but not including tasks submitted
     * to the pool that have not begun executing). This value is only
     * an approximation, obtained by iterating across all threads in
     * the pool. This method may be useful for tuning task
     * granularities.
     * @see ForkJoinPool#getQueuedTaskCount()
     */
    public long getQueuedTaskCount() {
        return getExcecutor().getQueuedTaskCount();
    }

    /**
     * Returns {@code true} if there are any tasks submitted to this
     * pool that have not yet begun executing.
     * @see ForkJoinPool#hasQueuedSubmissions()
     */
    public boolean hasQueuedSubmissions() {
        return getExcecutor().hasQueuedSubmissions();
    }

    /**
     * Returns {@code true} if all worker threads are currently idle.
     * An idle worker is one that cannot obtain a task to execute
     * because none are available to steal from other threads, and
     * there are no pending submissions to the pool. This method is
     * conservative; it might not return {@code true} immediately upon
     * idleness of all threads, but will eventually become true if
     * threads remain inactive.
     * @see ForkJoinPool#isQuiescent()
     */
    public boolean isQuiescent() {
        return getExcecutor().isQuiescent();
    }

    private static class CLThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {

        private int index = 0;
        private final List<CLCommandQueue> queues;

        private CLThreadFactory(List<CLCommandQueue> queues) {
            this.queues = queues;
        }

        @Override
        public synchronized ForkJoinWorkerThread newThread(ForkJoinPool pool) {
            return new ForkJoinQueueWorkerThread(pool, queues.get(index++));
        }

    }

    final static class ForkJoinQueueWorkerThread extends ForkJoinWorkerThread implements CommandQueueThread {

        private final CLCommandQueue queue;
        private final Map<Object, CLQueueContext> contextMap;

        public ForkJoinQueueWorkerThread(ForkJoinPool pool, CLCommandQueue queue) {
            super(pool);
            this.queue = queue;
            this.contextMap = new HashMap<Object, CLQueueContext>();
        }

        @Override
        public void run() {
            super.run();
            //release threadlocal contexts
            queue.finish();
            for (CLQueueContext context : contextMap.values()) {
                context.release();
            }
        }

        @Override
        public Map<Object, CLQueueContext> getContextMap() {
            return contextMap;
        }

        @Override
        public CLCommandQueue getQueue() {
            return queue;
        }
    }


}
TOP

Related Classes of com.jogamp.opencl.util.concurrent.CLForkJoinPool$CLThreadFactory

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.