/**
`std.parallelism` implements high-level primitives for SMP parallelism.
These include parallel foreach, parallel reduce, parallel eager map, pipelining
and future/promise parallelism.  `std.parallelism` is recommended when the
same operation is to be executed in parallel on different data, or when a
function is to be executed in a background thread and its result returned to a
well-defined main thread.  For communication between arbitrary threads, see
`std.concurrency`.

`std.parallelism` is based on the concept of a `Task`.  A `Task` is an
object that represents the fundamental unit of work in this library and may be
executed in parallel with any other `Task`.  Using `Task`
directly allows programming with a future/promise paradigm.  All other
supported parallelism paradigms (parallel foreach, map, reduce, pipelining)
represent an additional level of abstraction over `Task`.  They
automatically create one or more `Task` objects, or closely related types
that are conceptually identical but not part of the public API.

After creation, a `Task` may be executed in a new thread, or submitted
to a `TaskPool` for execution.  A `TaskPool` encapsulates a task queue
and its worker threads.  Its purpose is to efficiently map a large
number of `Task`s onto a smaller number of threads.  A task queue is a
FIFO queue of `Task` objects that have been submitted to the
`TaskPool` and are awaiting execution.  A worker thread is a thread that
is associated with exactly one task queue.  It executes the `Task` at the
front of its queue when the queue has work available, or sleeps when
no work is available.  Each task queue is associated with zero or
more worker threads.  If the result of a `Task` is needed before execution
by a worker thread has begun, the `Task` can be removed from the task queue
and executed immediately in the thread where the result is needed.

Warning:  Unless marked as `@trusted` or `@safe`, artifacts in
          this module allow implicit data sharing between threads and cannot
          guarantee that client code is free from low level data races.

Source:    $(PHOBOSSRC std/parallelism.d)
Author:  David Simcha
Copyright:  Copyright (c) 2009-2011, David Simcha.
License:    $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
*/
module std.parallelism;

version (OSX)
    version = Darwin;
else version (iOS)
    version = Darwin;
else version (TVOS)
    version = Darwin;
else version (WatchOS)
    version = Darwin;

///
@system unittest
{
    import std.algorithm.iteration : map;
    import std.math.operations : isClose;
    import std.parallelism : taskPool;
    import std.range : iota;

    // Parallel reduce can be combined with
    // std.algorithm.iteration.map to interesting effect.
    // The following example (thanks to Russel Winder)
    // calculates pi by quadrature  using
    // std.algorithm.map and TaskPool.reduce.
    // getTerm is evaluated in parallel as needed by
    // TaskPool.reduce.
    //
    // Timings on an Intel i5-3450 quad core machine
    // for n = 1_000_000_000:
    //
    // TaskPool.reduce:       1.067 s
    // std.algorithm.reduce:  4.011 s

    enum n = 1_000_000;
    enum delta = 1.0 / n;

    alias getTerm = (int i)
    {
        immutable x = ( i - 0.5 ) * delta;
        return delta / ( 1.0 + x * x ) ;
    };

    immutable pi = 4.0 * taskPool.reduce!"a + b"(n.iota.map!getTerm);

    assert(pi.isClose(3.14159, 1e-5));
}

import core.atomic;
import core.memory;
import core.sync.condition;
import core.thread;

import std.functional;
import std.meta;
import std.range.primitives;
import std.traits;

/*
(For now public undocumented with reserved name.)

A lazily initialized global constant. The underlying value is a shared global
statically initialized to `outOfBandValue` which must not be a legit value of
the constant. Upon the first call the situation is detected and the global is
initialized by calling `initializer`. The initializer is assumed to be pure
(even if not marked as such), i.e. return the same value upon repeated calls.
For that reason, no special precautions are taken so `initializer` may be called
more than one time leading to benign races on the cached value.

In the quiescent state the cost of the function is an atomic load from a global.

Params:
    T = The type of the pseudo-constant (may be qualified)
    outOfBandValue = A value that cannot be valid, it is used for initialization
    initializer = The function performing initialization; must be `nothrow`

Returns:
    The lazily initialized value
*/
@property pure
T __lazilyInitializedConstant(T, alias outOfBandValue, alias initializer)()
if (is(Unqual!T : T)
    && is(typeof(initializer()) : T)
    && is(typeof(outOfBandValue) : T))
{
    static T impl() nothrow
    {
        // Thread-local cache
        static Unqual!T tls = outOfBandValue;
        auto local = tls;
        // Shortest path, no atomic operations
        if (local != outOfBandValue) return local;
        // Process-level cache
        static shared Unqual!T result = outOfBandValue;
        // Initialize both process-level cache and tls
        local = atomicLoad(result);
        if (local == outOfBandValue)
        {
            local = initializer();
            atomicStore(result, local);
        }
        tls = local;
        return local;
    }

    import std.traits : SetFunctionAttributes;
    alias Fun = SetFunctionAttributes!(typeof(&impl), "D",
        functionAttributes!(typeof(&impl)) | FunctionAttribute.pure_);
    auto purified = (() @trusted => cast(Fun) &impl)();
    return purified();
}

// Returns the size of a cache line.
alias cacheLineSize =
    __lazilyInitializedConstant!(immutable(size_t), size_t.max, cacheLineSizeImpl);

private size_t cacheLineSizeImpl() @nogc nothrow @trusted
{
    size_t result = 0;
    import core.cpuid : datacache;
    foreach (ref const cachelevel; datacache)
    {
        if (cachelevel.lineSize > result && cachelevel.lineSize < uint.max)
        {
            result = cachelevel.lineSize;
        }
    }
    return result;
}

@nogc @safe nothrow unittest
{
    assert(cacheLineSize == cacheLineSizeImpl);
}

/* Atomics code.  These forward to core.atomic, but are written like this
   for two reasons:

   1.  They used to actually contain ASM code and I don' want to have to change
       to directly calling core.atomic in a zillion different places.

   2.  core.atomic has some misc. issues that make my use cases difficult
       without wrapping it.  If I didn't wrap it, casts would be required
       basically everywhere.
*/
private void atomicSetUbyte(T)(ref T stuff, T newVal)
if (__traits(isIntegral, T) && is(T : ubyte))
{
    //core.atomic.cas(cast(shared) &stuff, stuff, newVal);
    atomicStore(*(cast(shared) &stuff), newVal);
}

private ubyte atomicReadUbyte(T)(ref T val)
if (__traits(isIntegral, T) && is(T : ubyte))
{
    return atomicLoad(*(cast(shared) &val));
}

// This gets rid of the need for a lot of annoying casts in other parts of the
// code, when enums are involved.
private bool atomicCasUbyte(T)(ref T stuff, T testVal, T newVal)
if (__traits(isIntegral, T) && is(T : ubyte))
{
    return core.atomic.cas(cast(shared) &stuff, testVal, newVal);
}

/*--------------------- Generic helper functions, etc.------------------------*/
private template MapType(R, functions...)
{
    static assert(functions.length);

    ElementType!R e = void;
    alias MapType =
        typeof(adjoin!(staticMap!(unaryFun, functions))(e));
}

private template ReduceType(alias fun, R, E)
{
    alias ReduceType = typeof(binaryFun!fun(E.init, ElementType!R.init));
}

private template noUnsharedAliasing(T)
{
    enum bool noUnsharedAliasing = !hasUnsharedAliasing!T;
}

// This template tests whether a function may be executed in parallel from
// @safe code via Task.executeInNewThread().  There is an additional
// requirement for executing it via a TaskPool.  (See isSafeReturn).
private template isSafeTask(F)
{
    enum bool isSafeTask =
        (functionAttributes!F & (FunctionAttribute.safe | FunctionAttribute.trusted)) != 0 &&
        (functionAttributes!F & FunctionAttribute.ref_) == 0 &&
        (isFunctionPointer!F || !hasUnsharedAliasing!F) &&
        allSatisfy!(noUnsharedAliasing, Parameters!F);
}

@safe unittest
{
    alias F1 = void function() @safe;
    alias F2 = void function();
    alias F3 = void function(uint, string) @trusted;
    alias F4 = void function(uint, char[]);

    static assert( isSafeTask!F1);
    static assert(!isSafeTask!F2);
    static assert( isSafeTask!F3);
    static assert(!isSafeTask!F4);

    alias F5 = uint[] function(uint, string) pure @trusted;
    static assert( isSafeTask!F5);
}

// This function decides whether Tasks that meet all of the other requirements
// for being executed from @safe code can be executed on a TaskPool.
// When executing via TaskPool, it's theoretically possible
// to return a value that is also pointed to by a worker thread's thread local
// storage.  When executing from executeInNewThread(), the thread that executed
// the Task is terminated by the time the return value is visible in the calling
// thread, so this is a non-issue.  It's also a non-issue for pure functions
// since they can't read global state.
private template isSafeReturn(T)
{
    static if (!hasUnsharedAliasing!(T.ReturnType))
    {
        enum isSafeReturn = true;
    }
    else static if (T.isPure)
    {
        enum isSafeReturn = true;
    }
    else
    {
        enum isSafeReturn = false;
    }
}

private template randAssignable(R)
{
    enum randAssignable = isRandomAccessRange!R && hasAssignableElements!R;
}

private enum TaskStatus : ubyte
{
    notStarted,
    inProgress,
    done
}

private template AliasReturn(alias fun, T...)
{
    alias AliasReturn = typeof({ T args; return fun(args); });
}

// Should be private, but std.algorithm.reduce is used in the zero-thread case
// and won't work w/ private.
template reduceAdjoin(functions...)
{
    static if (functions.length == 1)
    {
        alias reduceAdjoin = binaryFun!(functions[0]);
    }
    else
    {
        T reduceAdjoin(T, U)(T lhs, U rhs)
        {
            alias funs = staticMap!(binaryFun, functions);

            foreach (i, Unused; typeof(lhs.expand))
            {
                lhs.expand[i] = funs[i](lhs.expand[i], rhs);
            }

            return lhs;
        }
    }
}

private template reduceFinish(functions...)
{
    static if (functions.length == 1)
    {
        alias reduceFinish = binaryFun!(functions[0]);
    }
    else
    {
        T reduceFinish(T)(T lhs, T rhs)
        {
            alias funs = staticMap!(binaryFun, functions);

            foreach (i, Unused; typeof(lhs.expand))
            {
                lhs.expand[i] = funs[i](lhs.expand[i], rhs.expand[i]);
            }

            return lhs;
        }
    }
}

private template isRoundRobin(R : RoundRobinBuffer!(C1, C2), C1, C2)
{
    enum isRoundRobin = true;
}

private template isRoundRobin(T)
{
    enum isRoundRobin = false;
}

@safe unittest
{
    static assert( isRoundRobin!(RoundRobinBuffer!(void delegate(char[]), bool delegate())));
    static assert(!isRoundRobin!(uint));
}

// This is the base "class" for all of the other tasks.  Using C-style
// polymorphism to allow more direct control over memory allocation, etc.
private struct AbstractTask
{
    AbstractTask* prev;
    AbstractTask* next;

    // Pointer to a function that executes this task.
    void function(void*) runTask;

    Throwable exception;
    ubyte taskStatus = TaskStatus.notStarted;

    bool done() @property
    {
        if (atomicReadUbyte(taskStatus) == TaskStatus.done)
        {
            if (exception)
            {
                throw exception;
            }

            return true;
        }

        return false;
    }

    void job()
    {
        runTask(&this);
    }
}

/**
`Task` represents the fundamental unit of work.  A `Task` may be
executed in parallel with any other `Task`.  Using this struct directly
allows future/promise parallelism.  In this paradigm, a function (or delegate
or other callable) is executed in a thread other than the one it was called
from.  The calling thread does not block while the function is being executed.
A call to `workForce`, `yieldForce`, or `spinForce` is used to
ensure that the `Task` has finished executing and to obtain the return
value, if any.  These functions and `done` also act as full memory barriers,
meaning that any memory writes made in the thread that executed the `Task`
are guaranteed to be visible in the calling thread after one of these functions
returns.

The $(REF task, std,parallelism) and $(REF scopedTask, std,parallelism) functions can
be used to create an instance of this struct.  See `task` for usage examples.

Function results are returned from `yieldForce`, `spinForce` and
`workForce` by ref.  If `fun` returns by ref, the reference will point
to the returned reference of `fun`.  Otherwise it will point to a
field in this struct.

Copying of this struct is disabled, since it would provide no useful semantics.
If you want to pass this struct around, you should do so by reference or
pointer.

Bugs:  Changes to `ref` and `out` arguments are not propagated to the
       call site, only to `args` in this struct.
*/
struct Task(alias fun, Args...)
{
    private AbstractTask base = {runTask : &impl};
    private alias base this;

    private @property AbstractTask* basePtr()
    {
        return &base;
    }

    private static void impl(void* myTask)
    {
        import std.algorithm.internal : addressOf;

        Task* myCastedTask = cast(typeof(this)*) myTask;
        static if (is(ReturnType == void))
        {
            fun(myCastedTask._args);
        }
        else static if (is(typeof(&(fun(myCastedTask._args)))))
        {
            myCastedTask.returnVal = addressOf(fun(myCastedTask._args));
        }
        else
        {
            myCastedTask.returnVal = fun(myCastedTask._args);
        }
    }

    private TaskPool pool;
    private bool isScoped;  // True if created with scopedTask.

    Args _args;

    /**
    The arguments the function was called with.  Changes to `out` and
    `ref` arguments will be visible here.
    */
    static if (__traits(isSame, fun, run))
    {
        alias args = _args[1..$];
    }
    else
    {
        alias args = _args;
    }


    // The purpose of this code is to decide whether functions whose
    // return values have unshared aliasing can be executed via
    // TaskPool from @safe code.  See isSafeReturn.
    static if (__traits(isSame, fun, run))
    {
        static if (isFunctionPointer!(_args[0]))
        {
            private enum bool isPure =
            (functionAttributes!(Args[0]) & FunctionAttribute.pure_) != 0;
        }
        else
        {
            // BUG:  Should check this for delegates too, but std.traits
            //       apparently doesn't allow this.  isPure is irrelevant
            //       for delegates, at least for now since shared delegates
            //       don't work.
            private enum bool isPure = false;
        }

    }
    else
    {
        // We already know that we can't execute aliases in @safe code, so
        // just put a dummy value here.
        private enum bool isPure = false;
    }


    /**
    The return type of the function called by this `Task`.  This can be
    `void`.
    */
    alias ReturnType = typeof(fun(_args));

    static if (!is(ReturnType == void))
    {
        static if (is(typeof(&fun(_args))))
        {
            // Ref return.
            ReturnType* returnVal;

            ref ReturnType fixRef(ReturnType* val)
            {
                return *val;
            }

        }
        else
        {
            ReturnType returnVal;

            ref ReturnType fixRef(ref ReturnType val)
            {
                return val;
            }
        }
    }

    private void enforcePool()
    {
        import std.exception : enforce;
        enforce(this.pool !is null, "Job not submitted yet.");
    }

    static if (Args.length > 0)
    {
        private this(Args args)
        {
            _args = args;
        }
    }

    // Work around DMD bug https://issues.dlang.org/show_bug.cgi?id=6588,
    // allow immutable elements.
    static if (allSatisfy!(isAssignable, Args))
    {
        typeof(this) opAssign(typeof(this) rhs)
        {
            foreach (i, Type; typeof(this.tupleof))
            {
                this.tupleof[i] = rhs.tupleof[i];
            }
            return this;
        }
    }
    else
    {
        @disable typeof(this) opAssign(typeof(this) rhs);
    }

    /**
    If the `Task` isn't started yet, execute it in the current thread.
    If it's done, return its return value, if any.  If it's in progress,
    busy spin until it's done, then return the return value.  If it threw
    an exception, rethrow that exception.

    This function should be used when you expect the result of the
    `Task` to be available on a timescale shorter than that of an OS
    context switch.
     */
    @property ref ReturnType spinForce() @trusted
    {
        enforcePool();

        this.pool.tryDeleteExecute(basePtr);

        while (atomicReadUbyte(this.taskStatus) != TaskStatus.done) {}

        if (exception)
        {
            throw exception;
        }

        static if (!is(ReturnType == void))
        {
            return fixRef(this.returnVal);
        }
    }

    /**
    If the `Task` isn't started yet, execute it in the current thread.
    If it's done, return its return value, if any.  If it's in progress,
    wait on a condition variable.  If it threw an exception, rethrow that
    exception.

    This function should be used for expensive functions, as waiting on a
    condition variable introduces latency, but avoids wasted CPU cycles.
     */
    @property ref ReturnType yieldForce() @trusted
    {
        enforcePool();
        this.pool.tryDeleteExecute(basePtr);

        if (done)
        {
            static if (is(ReturnType == void))
            {
                return;
            }
            else
            {
                return fixRef(this.returnVal);
            }
        }

        pool.waiterLock();
        scope(exit) pool.waiterUnlock();

        while (atomicReadUbyte(this.taskStatus) != TaskStatus.done)
        {
            pool.waitUntilCompletion();
        }

        if (exception)
        {
            throw exception; // nocoverage
        }

        static if (!is(ReturnType == void))
        {
            return fixRef(this.returnVal);
        }
    }

    /**
    If this `Task` was not started yet, execute it in the current
    thread.  If it is finished, return its result.  If it is in progress,
    execute any other `Task` from the `TaskPool` instance that
    this `Task` was submitted to until this one
    is finished.  If it threw an exception, rethrow that exception.
    If no other tasks are available or this `Task` was executed using
    `executeInNewThread`, wait on a condition variable.
     */
    @property ref ReturnType workForce() @trusted
    {
        enforcePool();
        this.pool.tryDeleteExecute(basePtr);

        while (true)
        {
            if (done)    // done() implicitly checks for exceptions.
            {
                static if (is(ReturnType == void))
                {
                    return;
                }
                else
                {
                    return fixRef(this.returnVal);
                }
            }

            AbstractTask* job;
            {
                // Locking explicitly and calling popNoSync() because
                // pop() waits on a condition variable if there are no Tasks
                // in the queue.

                pool.queueLock();
                scope(exit) pool.queueUnlock();
                job = pool.popNoSync();
            }


            if (job !is null)
            {

                version (verboseUnittest)
                {
                    stderr.writeln("Doing workForce work.");
                }

                pool.doJob(job);

                if (done)
                {
                    static if (is(ReturnType == void))
                    {
                        return;
                    }
                    else
                    {
                        return fixRef(this.returnVal);
                    }
                }
            }
            else
            {
                version (verboseUnittest)
                {
                    stderr.writeln("Yield from workForce.");
                }

                return yieldForce;
            }
        }
    }

    /**
    Returns `true` if the `Task` is finished executing.

    Throws:  Rethrows any exception thrown during the execution of the
             `Task`.
    */
    @property bool done() @trusted
    {
        // Explicitly forwarded for documentation purposes.
        return base.done;
    }

    /**
    Create a new thread for executing this `Task`, execute it in the
    newly created thread, then terminate the thread.  This can be used for
    future/promise parallelism.  An explicit priority may be given
    to the `Task`.  If one is provided, its value is forwarded to
    `core.thread.Thread.priority`. See $(REF task, std,parallelism) for
    usage example.
    */
    void executeInNewThread() @trusted
    {
        pool = new TaskPool(basePtr);
    }

    /// Ditto
    void executeInNewThread(int priority) @trusted
    {
        pool = new TaskPool(basePtr, priority);
    }

    @safe ~this()
    {
        if (isScoped && pool !is null && taskStatus != TaskStatus.done)
        {
            yieldForce;
        }
    }

    // When this is uncommented, it somehow gets called on returning from
    // scopedTask even though the struct shouldn't be getting copied.
    //@disable this(this) {}
}

// Calls `fpOrDelegate` with `args`.  This is an
// adapter that makes `Task` work with delegates, function pointers and
// functors instead of just aliases.
ReturnType!F run(F, Args...)(F fpOrDelegate, ref Args args)
{
    return fpOrDelegate(args);
}

/**
Creates a `Task` on the GC heap that calls an alias.  This may be executed
via `Task.executeInNewThread` or by submitting to a
$(REF TaskPool, std,parallelism).  A globally accessible instance of
`TaskPool` is provided by $(REF taskPool, std,parallelism).

Returns:  A pointer to the `Task`.

Example:
---
// Read two files into memory at the same time.
import std.file;

void main()
{
    // Create and execute a Task for reading
    // foo.txt.
    auto file1Task = task!read("foo.txt");
    file1Task.executeInNewThread();

    // Read bar.txt in parallel.
    auto file2Data = read("bar.txt");

    // Get the results of reading foo.txt.
    auto file1Data = file1Task.yieldForce;
}
---

---
// Sorts an array using a parallel quick sort algorithm.
// The first partition is done serially.  Both recursion
// branches are then executed in parallel.
//
// Timings for sorting an array of 1,000,000 doubles on
// an Athlon 64 X2 dual core machine:
//
// This implementation:               176 milliseconds.
// Equivalent serial implementation:  280 milliseconds
void parallelSort(T)(T[] data)
{
    // Sort small subarrays serially.
    if (data.length < 100)
    {
         std.algorithm.sort(data);
         return;
    }

    // Partition the array.
    swap(data[$ / 2], data[$ - 1]);
    auto pivot = data[$ - 1];
    bool lessThanPivot(T elem) { return elem < pivot; }

    auto greaterEqual = partition!lessThanPivot(data[0..$ - 1]);
    swap(data[$ - greaterEqual.length - 1], data[$ - 1]);

    auto less = data[0..$ - greaterEqual.length - 1];
    greaterEqual = data[$ - greaterEqual.length..$];

    // Execute both recursion branches in parallel.
    auto recurseTask = task!parallelSort(greaterEqual);
    taskPool.put(recurseTask);
    parallelSort(less);
    recurseTask.yieldForce;
}
---
*/
auto task(alias fun, Args...)(Args args)
{
    return new Task!(fun, Args)(args);
}

/**
Creates a `Task` on the GC heap that calls a function pointer, delegate, or
class/struct with overloaded opCall.

Example:
---
// Read two files in at the same time again,
// but this time use a function pointer instead
// of an alias to represent std.file.read.
import std.file;

void main()
{
    // Create and execute a Task for reading
    // foo.txt.
    auto file1Task = task(&read!string, "foo.txt", size_t.max);
    file1Task.executeInNewThread();

    // Read bar.txt in parallel.
    auto file2Data = read("bar.txt");

    // Get the results of reading foo.txt.
    auto file1Data = file1Task.yieldForce;
}
---

Notes: This function takes a non-scope delegate, meaning it can be
       used with closures.  If you can't allocate a closure due to objects
       on the stack that have scoped destruction, see `scopedTask`, which
       takes a scope delegate.
 */
auto task(F, Args...)(F delegateOrFp, Args args)
if (is(typeof(delegateOrFp(args))) && !isSafeTask!F)
{
    return new Task!(run, F, Args)(delegateOrFp, args);
}

/**
Version of `task` usable from `@safe` code.  Usage mechanics are
identical to the non-@safe case, but safety introduces some restrictions:

1.  `fun` must be @safe or @trusted.

2.  `F` must not have any unshared aliasing as defined by
    $(REF hasUnsharedAliasing, std,traits).  This means it
    may not be an unshared delegate or a non-shared class or struct
    with overloaded `opCall`.  This also precludes accepting template
    alias parameters.

3.  `Args` must not have unshared aliasing.

4.  `fun` must not return by reference.

5.  The return type must not have unshared aliasing unless `fun` is
    `pure` or the `Task` is executed via `executeInNewThread` instead
    of using a `TaskPool`.

*/
@trusted auto task(F, Args...)(F fun, Args args)
if (is(typeof(fun(args))) && isSafeTask!F)
{
    return new Task!(run, F, Args)(fun, args);
}

/**
These functions allow the creation of `Task` objects on the stack rather
than the GC heap.  The lifetime of a `Task` created by `scopedTask`
cannot exceed the lifetime of the scope it was created in.

`scopedTask` might be preferred over `task`:

1.  When a `Task` that calls a delegate is being created and a closure
    cannot be allocated due to objects on the stack that have scoped
    destruction.  The delegate overload of `scopedTask` takes a `scope`
    delegate.

2.  As a micro-optimization, to avoid the heap allocation associated with
    `task` or with the creation of a closure.

Usage is otherwise identical to `task`.

Notes:  `Task` objects created using `scopedTask` will automatically
call `Task.yieldForce` in their destructor if necessary to ensure
the `Task` is complete before the stack frame they reside on is destroyed.
*/
auto scopedTask(alias fun, Args...)(Args args)
{
    auto ret = Task!(fun, Args)(args);
    ret.isScoped = true;
    return ret;
}

/// Ditto
auto scopedTask(F, Args...)(scope F delegateOrFp, Args args)
if (is(typeof(delegateOrFp(args))) && !isSafeTask!F)
{
    auto ret = Task!(run, F, Args)(delegateOrFp, args);
    ret.isScoped = true;
    return ret;
}

/// Ditto
@trusted auto scopedTask(F, Args...)(F fun, Args args)
if (is(typeof(fun(args))) && isSafeTask!F)
{
    auto ret = Task!(run, F, Args)(fun, args);
    ret.isScoped = true;
    return ret;
}

/**
The total number of CPU cores available on the current machine, as reported by
the operating system.
*/
alias totalCPUs =
    __lazilyInitializedConstant!(immutable(uint), uint.max, totalCPUsImpl);

uint totalCPUsImpl() @nogc nothrow @trusted
{
    version (Windows)
    {
        // BUGS:  Only works on Windows 2000 and above.
        import core.sys.windows.winbase : SYSTEM_INFO, GetSystemInfo;
        import std.algorithm.comparison : max;
        SYSTEM_INFO si;
        GetSystemInfo(&si);
        return max(1, cast(uint) si.dwNumberOfProcessors);
    }
    else version (linux)
    {
        import core.stdc.stdlib : calloc;
        import core.stdc.string : memset;
        import core.sys.linux.sched : CPU_ALLOC_SIZE, CPU_FREE, CPU_COUNT, CPU_COUNT_S, cpu_set_t, sched_getaffinity;
        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;

        int count = 0;

        /**
         * According to ruby's source code, CPU_ALLOC() doesn't work as expected.
         *  see: https://github.com/ruby/ruby/commit/7d9e04de496915dd9e4544ee18b1a0026dc79242
         *
         *  The hardcode number also comes from ruby's source code.
         *  see: https://github.com/ruby/ruby/commit/0fa75e813ecf0f5f3dd01f89aa76d0e25ab4fcd4
         */
        for (int n = 64; n <= 16384; n *= 2)
        {
            size_t size = CPU_ALLOC_SIZE(count);
            if (size >= 0x400)
            {
                auto cpuset = cast(cpu_set_t*) calloc(1, size);
                if (cpuset is null) break;
                if (sched_getaffinity(0, size, cpuset) == 0)
                {
                    count = CPU_COUNT_S(size, cpuset);
                }
                CPU_FREE(cpuset);
            }
            else
            {
                cpu_set_t cpuset;
                if (sched_getaffinity(0, cpu_set_t.sizeof, &cpuset) == 0)
                {
                    count = CPU_COUNT(&cpuset);
                }
            }

            if (count > 0)
                return cast(uint) count;
        }

        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
    }
    else version (Darwin)
    {
        import core.sys.darwin.sys.sysctl : sysctlbyname;
        uint result;
        size_t len = result.sizeof;
        sysctlbyname("hw.physicalcpu", &result, &len, null, 0);
        return result;
    }
    else version (DragonFlyBSD)
    {
        import core.sys.dragonflybsd.sys.sysctl : sysctlbyname;
        uint result;
        size_t len = result.sizeof;
        sysctlbyname("hw.ncpu", &result, &len, null, 0);
        return result;
    }
    else version (FreeBSD)
    {
        import core.sys.freebsd.sys.sysctl : sysctlbyname;
        uint result;
        size_t len = result.sizeof;
        sysctlbyname("hw.ncpu", &result, &len, null, 0);
        return result;
    }
    else version (NetBSD)
    {
        import core.sys.netbsd.sys.sysctl : sysctlbyname;
        uint result;
        size_t len = result.sizeof;
        sysctlbyname("hw.ncpu", &result, &len, null, 0);
        return result;
    }
    else version (Solaris)
    {
        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
    }
    else version (OpenBSD)
    {
        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
    }
    else version (Hurd)
    {
        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
    }
    else
    {
        static assert(0, "Don't know how to get N CPUs on this OS.");
    }
}

/*
This class serves two purposes:

1.  It distinguishes std.parallelism threads from other threads so that
    the std.parallelism daemon threads can be terminated.

2.  It adds a reference to the pool that the thread is a member of,
    which is also necessary to allow the daemon threads to be properly
    terminated.
*/
private final class ParallelismThread : Thread
{
    this(void delegate() dg)
    {
        super(dg);
    }

    TaskPool pool;
}

// Kill daemon threads.
shared static ~this()
{
    foreach (ref thread; Thread)
    {
        auto pthread = cast(ParallelismThread) thread;
        if (pthread is null) continue;
        auto pool = pthread.pool;
        if (!pool.isDaemon) continue;
        pool.stop();
        pthread.join();
    }
}

/**
This class encapsulates a task queue and a set of worker threads.  Its purpose
is to efficiently map a large number of `Task`s onto a smaller number of
threads.  A task queue is a FIFO queue of `Task` objects that have been
submitted to the `TaskPool` and are awaiting execution.  A worker thread is a
thread that executes the `Task` at the front of the queue when one is
available and sleeps when the queue is empty.

This class should usually be used via the global instantiation
available via the $(REF taskPool, std,parallelism) property.
Occasionally it is useful to explicitly instantiate a `TaskPool`:

1.  When you want `TaskPool` instances with multiple priorities, for example
    a low priority pool and a high priority pool.

2.  When the threads in the global task pool are waiting on a synchronization
    primitive (for example a mutex), and you want to parallelize the code that
    needs to run before these threads can be resumed.

Note: The worker threads in this pool will not stop until
      `stop` or `finish` is called, even if the main thread
      has finished already. This may lead to programs that
      never end. If you do not want this behaviour, you can set `isDaemon`
      to true.
 */
final class TaskPool
{
private:

    // A pool can either be a regular pool or a single-task pool.  A
    // single-task pool is a dummy pool that's fired up for
    // Task.executeInNewThread().
    bool isSingleTask;

    ParallelismThread[] pool;
    Thread singleTaskThread;

    AbstractTask* head;
    AbstractTask* tail;
    PoolState status = PoolState.running;
    Condition workerCondition;
    Condition waiterCondition;
    Mutex queueMutex;
    Mutex waiterMutex;  // For waiterCondition

    // The instanceStartIndex of the next instance that will be created.
    __gshared size_t nextInstanceIndex = 1;

    // The index of the current thread.
    static size_t threadIndex;

    // The index of the first thread in this instance.
    immutable size_t instanceStartIndex;

    // The index that the next thread to be initialized in this pool will have.
    size_t nextThreadIndex;

    enum PoolState : ubyte
    {
        running,
        finishing,
        stopNow
    }

    void doJob(AbstractTask* job)
    {
        assert(job.taskStatus == TaskStatus.inProgress);
        assert(job.next is null);
        assert(job.prev is null);

        scope(exit)
        {
            if (!isSingleTask)
            {
                waiterLock();
                scope(exit) waiterUnlock();
                notifyWaiters();
            }
        }

        try
        {
            job.job();
        }
        catch (Throwable e)
        {
            job.exception = e;
        }

        atomicSetUbyte(job.taskStatus, TaskStatus.done);
    }

    // This function is used for dummy pools created by Task.executeInNewThread().
    void doSingleTask()
    {
        // No synchronization.  Pool is guaranteed to only have one thread,
        // and the queue is submitted to before this thread is created.
        assert(head);
        auto t = head;
        t.next = t.prev = head = null;
        doJob(t);
    }

    // This function performs initialization for each thread that affects
    // thread local storage and therefore must be done from within the
    // worker thread.  It then calls executeWorkLoop().
    void startWorkLoop()
    {
        // Initialize thread index.
        {
            queueLock();
            scope(exit) queueUnlock();
            threadIndex = nextThreadIndex;
            nextThreadIndex++;
        }

        executeWorkLoop();
    }

    // This is the main work loop that worker threads spend their time in
    // until they terminate.  It's also entered by non-worker threads when
    // finish() is called with the blocking variable set to true.
    void executeWorkLoop()
    {
        while (atomicReadUbyte(status) != PoolState.stopNow)
        {
            AbstractTask* task = pop();
            if (task is null)
            {
                if (atomicReadUbyte(status) == PoolState.finishing)
                {
                    atomicSetUbyte(status, PoolState.stopNow);
                    return;
                }
            }
            else
            {
                doJob(task);
            }
        }
    }

    // Pop a task off the queue.
    AbstractTask* pop()
    {
        queueLock();
        scope(exit) queueUnlock();
        auto ret = popNoSync();
        while (ret is null && status == PoolState.running)
        {
            wait();
            ret = popNoSync();
        }
        return ret;
    }

    AbstractTask* popNoSync()
    out(returned)
    {
        /* If task.prev and task.next aren't null, then another thread
         * can try to delete this task from the pool after it's
         * alreadly been deleted/popped.
         */
        if (returned !is null)
        {
            assert(returned.next is null);
            assert(returned.prev is null);
        }
    }
    do
    {
        if (isSingleTask) return null;

        AbstractTask* returned = head;
        if (head !is null)
        {
            head = head.next;
            returned.prev = null;
            returned.next = null;
            returned.taskStatus = TaskStatus.inProgress;
        }
        if (head !is null)
        {
            head.prev = null;
        }

        return returned;
    }

    // Push a task onto the queue.
    void abstractPut(AbstractTask* task)
    {
        queueLock();
        scope(exit) queueUnlock();
        abstractPutNoSync(task);
    }

    void abstractPutNoSync(AbstractTask* task)
    in
    {
        assert(task);
    }
    out
    {
        import std.conv : text;

        assert(tail.prev !is tail);
        assert(tail.next is null, text(tail.prev, '\t', tail.next));
        if (tail.prev !is null)
        {
            assert(tail.prev.next is tail, text(tail.prev, '\t', tail.next));
        }
    }
    do
    {
        // Not using enforce() to save on function call overhead since this
        // is a performance critical function.
        if (status != PoolState.running)
        {
            throw new Error(
                "Cannot submit a new task to a pool after calling " ~
                "finish() or stop()."
            );
        }

        task.next = null;
        if (head is null)   //Queue is empty.
        {
            head = task;
            tail = task;
            tail.prev = null;
        }
        else
        {
            assert(tail);
            task.prev = tail;
            tail.next = task;
            tail = task;
        }
        notify();
    }

    void abstractPutGroupNoSync(AbstractTask* h, AbstractTask* t)
    {
        if (status != PoolState.running)
        {
            throw new Error(
                "Cannot submit a new task to a pool after calling " ~
                "finish() or stop()."
            );
        }

        if (head is null)
        {
            head = h;
            tail = t;
        }
        else
        {
            h.prev = tail;
            tail.next = h;
            tail = t;
        }

        notifyAll();
    }

    void tryDeleteExecute(AbstractTask* toExecute)
    {
        if (isSingleTask) return;

        if ( !deleteItem(toExecute) )
        {
            return;
        }

        try
        {
            toExecute.job();
        }
        catch (Exception e)
        {
            toExecute.exception = e;
        }

        atomicSetUbyte(toExecute.taskStatus, TaskStatus.done);
    }

    bool deleteItem(AbstractTask* item)
    {
        queueLock();
        scope(exit) queueUnlock();
        return deleteItemNoSync(item);
    }

    bool deleteItemNoSync(AbstractTask* item)
    {
        if (item.taskStatus != TaskStatus.notStarted)
        {
            return false;
        }
        item.taskStatus = TaskStatus.inProgress;

        if (item is head)
        {
            // Make sure head gets set properly.
            popNoSync();
            return true;
        }
        if (item is tail)
        {
            tail = tail.prev;
            if (tail !is null)
            {
                tail.next = null;
            }
            item.next = null;
            item.prev = null;
            return true;
        }
        if (item.next !is null)
        {
            assert(item.next.prev is item);  // Check queue consistency.
            item.next.prev = item.prev;
        }
        if (item.prev !is null)
        {
            assert(item.prev.next is item);  // Check queue consistency.
            item.prev.next = item.next;
        }
        item.next = null;
        item.prev = null;
        return true;
    }

    void queueLock()
    {
        assert(queueMutex);
        if (!isSingleTask) queueMutex.lock();
    }

    void queueUnlock()
    {
        assert(queueMutex);
        if (!isSingleTask) queueMutex.unlock();
    }

    void waiterLock()
    {
        if (!isSingleTask) waiterMutex.lock();
    }

    void waiterUnlock()
    {
        if (!isSingleTask) waiterMutex.unlock();
    }

    void wait()
    {
        if (!isSingleTask) workerCondition.wait();
    }

    void notify()
    {
        if (!isSingleTask) workerCondition.notify();
    }

    void notifyAll()
    {
        if (!isSingleTask) workerCondition.notifyAll();
    }

    void waitUntilCompletion()
    {
        if (isSingleTask)
        {
            singleTaskThread.join();
        }
        else
        {
            waiterCondition.wait();
        }
    }

    void notifyWaiters()
    {
        if (!isSingleTask) waiterCondition.notifyAll();
    }

    // Private constructor for creating dummy pools that only have one thread,
    // only execute one Task, and then terminate.  This is used for
    // Task.executeInNewThread().
    this(AbstractTask* task, int priority = int.max)
    {
        assert(task);

        // Dummy value, not used.
        instanceStartIndex = 0;

        this.isSingleTask = true;
        task.taskStatus = TaskStatus.inProgress;
        this.head = task;
        singleTaskThread = new Thread(&doSingleTask);
        singleTaskThread.start();

        // Disabled until writing code to support
        // running thread with specified priority
        // See https://issues.dlang.org/show_bug.cgi?id=8960

        /*if (priority != int.max)
        {
            singleTaskThread.priority = priority;
        }*/
    }

public:
    // This is used in parallel_algorithm but is too unstable to document
    // as public API.
    size_t defaultWorkUnitSize(size_t rangeLen) const @safe pure nothrow
    {
        import std.algorithm.comparison : max;

        if (this.size == 0)
        {
            return max(rangeLen, 1);
        }

        immutable size_t eightSize = 4 * (this.size + 1);
        auto ret = (rangeLen / eightSize) + ((rangeLen % eightSize == 0) ? 0 : 1);
        return max(ret, 1);
    }

    /**
    Default constructor that initializes a `TaskPool` with
    `totalCPUs` - 1 worker threads.  The minus 1 is included because the
    main thread will also be available to do work.

    Note:  On single-core machines, the primitives provided by `TaskPool`
           operate transparently in single-threaded mode.
     */
    this() @trusted
    {
        this(totalCPUs - 1);
    }

    /**
    Allows for custom number of worker threads.
    */
    this(size_t nWorkers) @trusted
    {
        synchronized(typeid(TaskPool))
        {
            instanceStartIndex = nextInstanceIndex;

            // The first worker thread to be initialized will have this index,
            // and will increment it.  The second worker to be initialized will
            // have this index plus 1.
            nextThreadIndex = instanceStartIndex;
            nextInstanceIndex += nWorkers;
        }

        queueMutex = new Mutex(this);
        waiterMutex = new Mutex();
        workerCondition = new Condition(queueMutex);
        waiterCondition = new Condition(waiterMutex);

        pool = new ParallelismThread[nWorkers];
        foreach (ref poolThread; pool)
        {
            poolThread = new ParallelismThread(&startWorkLoop);
            poolThread.pool = this;
            poolThread.start();
        }
    }

    /**
    Implements a parallel foreach loop over a range.  This works by implicitly
    creating and submitting one `Task` to the `TaskPool` for each worker
    thread.  A work unit is a set of consecutive elements of `range` to
    be processed by a worker thread between communication with any other
    thread.  The number of elements processed per work unit is controlled by the
    `workUnitSize` parameter.  Smaller work units provide better load
    balancing, but larger work units avoid the overhead of communicating
    with other threads frequently to fetch the next work unit.  Large work
    units also avoid false sharing in cases where the range is being modified.
    The less time a single iteration of the loop takes, the larger
    `workUnitSize` should be.  For very expensive loop bodies,
    `workUnitSize` should  be 1.  An overload that chooses a default work
    unit size is also available.

    Example:
    ---
    // Find the logarithm of every number from 1 to
    // 10_000_000 in parallel.
    auto logs = new double[10_000_000];

    // Parallel foreach works with or without an index
    // variable.  It can iterate by ref if range.front
    // returns by ref.

    // Iterate over logs using work units of size 100.
    foreach (i, ref elem; taskPool.parallel(logs, 100))
    {
        elem = log(i + 1.0);
    }

    // Same thing, but use the default work unit size.
    //
    // Timings on an Athlon 64 X2 dual core machine:
    //
    // Parallel foreach:  388 milliseconds
    // Regular foreach:   619 milliseconds
    foreach (i, ref elem; taskPool.parallel(logs))
    {
        elem = log(i + 1.0);
    }
    ---

    Notes:

    The memory usage of this implementation is guaranteed to be constant
    in `range.length`.

    Breaking from a parallel foreach loop via a break, labeled break,
    labeled continue, return or goto statement throws a
    `ParallelForeachError`.

    In the case of non-random access ranges, parallel foreach buffers lazily
    to an array of size `workUnitSize` before executing the parallel portion
    of the loop.  The exception is that, if a parallel foreach is executed
    over a range returned by `asyncBuf` or `map`, the copying is elided
    and the buffers are simply swapped.  In this case `workUnitSize` is
    ignored and the work unit size is set to the  buffer size of `range`.

    A memory barrier is guaranteed to be executed on exit from the loop,
    so that results produced by all threads are visible in the calling thread.

    $(B Exception Handling):

    When at least one exception is thrown from inside a parallel foreach loop,
    the submission of additional `Task` objects is terminated as soon as
    possible, in a non-deterministic manner.  All executing or
    enqueued work units are allowed to complete.  Then, all exceptions that
    were thrown by any work unit are chained using `Throwable.next` and
    rethrown.  The order of the exception chaining is non-deterministic.
    */
    ParallelForeach!R parallel(R)(R range, size_t workUnitSize)
    {
        import std.exception : enforce;
        enforce(workUnitSize > 0, "workUnitSize must be > 0.");
        alias RetType = ParallelForeach!R;
        return RetType(this, range, workUnitSize);
    }


    /// Ditto
    ParallelForeach!R parallel(R)(R range)
    {
        static if (hasLength!R)
        {
            // Default work unit size is such that we would use 4x as many
            // slots as are in this thread pool.
            size_t workUnitSize = defaultWorkUnitSize(range.length);
            return parallel(range, workUnitSize);
        }
        else
        {
            // Just use a really, really dumb guess if the user is too lazy to
            // specify.
            return parallel(range, 512);
        }
    }

    ///
    template amap(functions...)
    {
        /**
        Eager parallel map.  The eagerness of this function means it has less
        overhead than the lazily evaluated `TaskPool.map` and should be
        preferred where the memory requirements of eagerness are acceptable.
        `functions` are the functions to be evaluated, passed as template
        alias parameters in a style similar to
        $(REF map, std,algorithm,iteration).
        The first argument must be a random access range. For performance
        reasons, amap will assume the range elements have not yet been
        initialized. Elements will be overwritten without calling a destructor
        nor doing an assignment. As such, the range must not contain meaningful
        data$(DDOC_COMMENT not a section): either un-initialized objects, or
        objects in their `.init` state.

        ---
        auto numbers = iota(100_000_000.0);

        // Find the square roots of numbers.
        //
        // Timings on an Athlon 64 X2 dual core machine:
        //
        // Parallel eager map:                   0.802 s
        // Equivalent serial implementation:     1.768 s
        auto squareRoots = taskPool.amap!sqrt(numbers);
        ---

        Immediately after the range argument, an optional work unit size argument
        may be provided.  Work units as used by `amap` are identical to those
        defined for parallel foreach.  If no work unit size is provided, the
        default work unit size is used.

        ---
        // Same thing, but make work unit size 100.
        auto squareRoots = taskPool.amap!sqrt(numbers, 100);
        ---

        An output range for returning the results may be provided as the last
        argument.  If one is not provided, an array of the proper type will be
        allocated on the garbage collected heap.  If one is provided, it must be a
        random access range with assignable elements, must have reference
        semantics with respect to assignment to its elements, and must have the
        same length as the input range.  Writing to adjacent elements from
        different threads must be safe.

        ---
        // Same thing, but explicitly allocate an array
        // to return the results in.  The element type
        // of the array may be either the exact type
        // returned by functions or an implicit conversion
        // target.
        auto squareRoots = new float[numbers.length];
        taskPool.amap!sqrt(numbers, squareRoots);

        // Multiple functions, explicit output range, and
        // explicit work unit size.
        auto results = new Tuple!(float, real)[numbers.length];
        taskPool.amap!(sqrt, log)(numbers, 100, results);
        ---

        Note:

        A memory barrier is guaranteed to be executed after all results are written
        but before returning so that results produced by all threads are visible
        in the calling thread.

        Tips:

        To perform the mapping operation in place, provide the same range for the
        input and output range.

        To parallelize the copying of a range with expensive to evaluate elements
        to an array, pass an identity function (a function that just returns
        whatever argument is provided to it) to `amap`.

        $(B Exception Handling):

        When at least one exception is thrown from inside the map functions,
        the submission of additional `Task` objects is terminated as soon as
        possible, in a non-deterministic manner.  All currently executing or
        enqueued work units are allowed to complete.  Then, all exceptions that
        were thrown from any work unit are chained using `Throwable.next` and
        rethrown.  The order of the exception chaining is non-deterministic.
        */
        auto amap(Args...)(Args args)
        if (isRandomAccessRange!(Args[0]))
        {
            import core.internal.lifetime : emplaceRef;

            alias fun = adjoin!(staticMap!(unaryFun, functions));

            alias range = args[0];
            immutable len = range.length;

            static if (
                Args.length > 1 &&
                randAssignable!(Args[$ - 1]) &&
                is(MapType!(Args[0], functions) : ElementType!(Args[$ - 1]))
                )
            {
                import std.conv : text;
                import std.exception : enforce;

                alias buf = args[$ - 1];
                alias args2 = args[0..$ - 1];
                alias Args2 = Args[0..$ - 1];
                enforce(buf.length == len,
                        text("Can't use a user supplied buffer that's the wrong ",
                             "size.  (Expected  :", len, " Got:  ", buf.length));
            }
            else static if (randAssignable!(Args[$ - 1]) && Args.length > 1)
            {
                static assert(0, "Wrong buffer type.");
            }
            else
            {
                import std.array : uninitializedArray;

                auto buf = uninitializedArray!(MapType!(Args[0], functions)[])(len);
                alias args2 = args;
                alias Args2 = Args;
            }

            if (!len) return buf;

            static if (isIntegral!(Args2[$ - 1]))
            {
                static assert(args2.length == 2);
                auto workUnitSize = cast(size_t) args2[1];
            }
            else
            {
                static assert(args2.length == 1, Args);
                auto workUnitSize = defaultWorkUnitSize(range.length);
            }

            alias R = typeof(range);

            if (workUnitSize > len)
            {
                workUnitSize = len;
            }

            // Handle as a special case:
            if (size == 0)
            {
                size_t index = 0;
                foreach (elem; range)
                {
                    emplaceRef(buf[index++], fun(elem));
                }
                return buf;
            }

            // Effectively -1:  chunkIndex + 1 == 0:
            shared size_t workUnitIndex = size_t.max;
            shared bool shouldContinue = true;

            void doIt()
            {
                import std.algorithm.comparison : min;

                scope(failure)
                {
                    // If an exception is thrown, all threads should bail.
                    atomicStore(shouldContinue, false);
                }

                while (atomicLoad(shouldContinue))
                {
                    immutable myUnitIndex = atomicOp!"+="(workUnitIndex, 1);
                    immutable start = workUnitSize * myUnitIndex;
                    if (start >= len)
                    {
                        atomicStore(shouldContinue, false);
                        break;
                    }

                    immutable end = min(len, start + workUnitSize);

                    static if (hasSlicing!R)
                    {
                        auto subrange = range[start .. end];
                        foreach (i; start .. end)
                        {
                            emplaceRef(buf[i], fun(subrange.front));
                            subrange.popFront();
                        }
                    }
                    else
                    {
                        foreach (i; start .. end)
                        {
                            emplaceRef(buf[i], fun(range[i]));
                        }
                    }
                }
            }

            submitAndExecute(this, &doIt);
            return buf;
        }
    }

    ///
    template map(functions...)
    {
        /**
        A semi-lazy parallel map that can be used for pipelining.  The map
        functions are evaluated for the first `bufSize` elements and stored in a
        buffer and made available to `popFront`.  Meanwhile, in the
        background a second buffer of the same size is filled.  When the first
        buffer is exhausted, it is swapped with the second buffer and filled while
        the values from what was originally the second buffer are read.  This
        implementation allows for elements to be written to the buffer without
        the need for atomic operations or synchronization for each write, and
        enables the mapping function to be evaluated efficiently in parallel.

        `map` has more overhead than the simpler procedure used by `amap`
        but avoids the need to keep all results in memory simultaneously and works
        with non-random access ranges.

        Params:

        source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        to be mapped.  If `source` is not random
        access it will be lazily buffered to an array of size `bufSize` before
        the map function is evaluated.  (For an exception to this rule, see Notes.)

        bufSize = The size of the buffer to store the evaluated elements.

        workUnitSize = The number of elements to evaluate in a single
        `Task`.  Must be less than or equal to `bufSize`, and
        should be a fraction of `bufSize` such that all worker threads can be
        used.  If the default of size_t.max is used, workUnitSize will be set to
        the pool-wide default.

        Returns:  An input range representing the results of the map.  This range
                  has a length iff `source` has a length.

        Notes:

        If a range returned by `map` or `asyncBuf` is used as an input to
        `map`, then as an optimization the copying from the output buffer
        of the first range to the input buffer of the second range is elided, even
        though the ranges returned by `map` and `asyncBuf` are non-random
        access ranges.  This means that the `bufSize` parameter passed to the
        current call to `map` will be ignored and the size of the buffer
        will be the buffer size of `source`.

        Example:
        ---
        // Pipeline reading a file, converting each line
        // to a number, taking the logarithms of the numbers,
        // and performing the additions necessary to find
        // the sum of the logarithms.

        auto lineRange = File("numberList.txt").byLine();
        auto dupedLines = std.algorithm.map!"a.idup"(lineRange);
        auto nums = taskPool.map!(to!double)(dupedLines);
        auto logs = taskPool.map!log10(nums);

        double sum = 0;
        foreach (elem; logs)
        {
            sum += elem;
        }
        ---

        $(B Exception Handling):

        Any exceptions thrown while iterating over `source`
        or computing the map function are re-thrown on a call to `popFront` or,
        if thrown during construction, are simply allowed to propagate to the
        caller.  In the case of exceptions thrown while computing the map function,
        the exceptions are chained as in `TaskPool.amap`.
        */
        auto
        map(S)(S source, size_t bufSize = 100, size_t workUnitSize = size_t.max)
        if (isInputRange!S)
        {
            import std.exception : enforce;

            enforce(workUnitSize == size_t.max || workUnitSize <= bufSize,
                    "Work unit size must be smaller than buffer size.");
            alias fun = adjoin!(staticMap!(unaryFun, functions));

            static final class Map
            {
                // This is a class because the task needs to be located on the
                // heap and in the non-random access case source needs to be on
                // the heap, too.

            private:
                enum bufferTrick = is(typeof(source.buf1)) &&
                is(typeof(source.bufPos)) &&
                is(typeof(source.doBufSwap()));

                alias E = MapType!(S, functions);
                E[] buf1, buf2;
                S source;
                TaskPool pool;
                Task!(run, E[] delegate(E[]), E[]) nextBufTask;
                size_t workUnitSize;
                size_t bufPos;
                bool lastTaskWaited;

            static if (isRandomAccessRange!S)
            {
                alias FromType = S;

                void popSource()
                {
                    import std.algorithm.comparison : min;

                    static if (__traits(compiles, source[0 .. source.length]))
                    {
                        source = source[min(buf1.length, source.length)..source.length];
                    }
                    else static if (__traits(compiles, source[0..$]))
                    {
                        source = source[min(buf1.length, source.length)..$];
                    }
                    else
                    {
                        static assert(0, "S must have slicing for Map."
                                      ~ "  " ~ S.stringof ~ " doesn't.");
                    }
                }
            }
            else static if (bufferTrick)
            {
                // Make sure we don't have the buffer recycling overload of
                // asyncBuf.
                static if (
                    is(typeof(source.source)) &&
                    isRoundRobin!(typeof(source.source))
                )
                {
                    static assert(0, "Cannot execute a parallel map on " ~
                                  "the buffer recycling overload of asyncBuf."
                                 );
                }

                alias FromType = typeof(source.buf1);
                FromType from;

                // Just swap our input buffer with source's output buffer.
                // No need to copy element by element.
                FromType dumpToFrom()
                {
                    import std.algorithm.mutation : swap;

                    assert(source.buf1.length <= from.length);
                    from.length = source.buf1.length;
                    swap(source.buf1, from);

                    // Just in case this source has been popped before
                    // being sent to map:
                    from = from[source.bufPos..$];

                    static if (is(typeof(source._length)))
                    {
                        source._length -= (from.length - source.bufPos);
                    }

                    source.doBufSwap();

                    return from;
                }
            }
            else
            {
                alias FromType = ElementType!S[];

                // The temporary array that data is copied to before being
                // mapped.
                FromType from;

                FromType dumpToFrom()
                {
                    assert(from !is null);

                    size_t i;
                    for (; !source.empty && i < from.length; source.popFront())
                    {
                        from[i++] = source.front;
                    }

                    from = from[0 .. i];
                    return from;
                }
            }

            static if (hasLength!S)
            {
                size_t _length;

                public @property size_t length() const @safe pure nothrow
                {
                    return _length;
                }
            }

                this(S source, size_t bufSize, size_t workUnitSize, TaskPool pool)
                {
                    static if (bufferTrick)
                    {
                        bufSize = source.buf1.length;
                    }

                    buf1.length = bufSize;
                    buf2.length = bufSize;

                    static if (!isRandomAccessRange!S)
                    {
                        from.length = bufSize;
                    }

                    this.workUnitSize = (workUnitSize == size_t.max) ?
                            pool.defaultWorkUnitSize(bufSize) : workUnitSize;
                    this.source = source;
                    this.pool = pool;

                    static if (hasLength!S)
                    {
                        _length = source.length;
                    }

                    buf1 = fillBuf(buf1);
                    submitBuf2();
                }

                // The from parameter is a dummy and ignored in the random access
                // case.
                E[] fillBuf(E[] buf)
                {
                    import std.algorithm.comparison : min;

                    static if (isRandomAccessRange!S)
                    {
                        import std.range : take;
                        auto toMap = take(source, buf.length);
                        scope(success) popSource();
                    }
                    else
                    {
                        auto toMap = dumpToFrom();
                    }

                    buf = buf[0 .. min(buf.length, toMap.length)];

                    // Handle as a special case:
                    if (pool.size == 0)
                    {
                        size_t index = 0;
                        foreach (elem; toMap)
                        {
                            buf[index++] = fun(elem);
                        }
                        return buf;
                    }

                    pool.amap!functions(toMap, workUnitSize, buf);

                    return buf;
                }

                void submitBuf2()
                in
                {
                    assert(nextBufTask.prev is null);
                    assert(nextBufTask.next is null);
                }
                do
                {
                    // Hack to reuse the task object.

                    nextBufTask = typeof(nextBufTask).init;
                    nextBufTask._args[0] = &fillBuf;
                    nextBufTask._args[1] = buf2;
                    pool.put(nextBufTask);
                }

                void doBufSwap()
                {
                    if (lastTaskWaited)
                    {
                        // Then the source is empty.  Signal it here.
                        buf1 = null;
                        buf2 = null;

                        static if (!isRandomAccessRange!S)
                        {
                            from = null;
                        }

                        return;
                    }

                    buf2 = buf1;
                    buf1 = nextBufTask.yieldForce;
                    bufPos = 0;

                    if (source.empty)
                    {
                        lastTaskWaited = true;
                    }
                    else
                    {
                        submitBuf2();
                    }
                }

            public:
                @property auto front()
                {
                    return buf1[bufPos];
                }

                void popFront()
                {
                    static if (hasLength!S)
                    {
                        _length--;
                    }

                    bufPos++;
                    if (bufPos >= buf1.length)
                    {
                        doBufSwap();
                    }
                }

                static if (isInfinite!S)
                {
                    enum bool empty = false;
                }
                else
                {

                    bool empty() const @property
                    {
                        // popFront() sets this when source is empty
                        return buf1.length == 0;
                    }
                }
            }
            return new Map(source, bufSize, workUnitSize, this);
        }
    }

    /**
    Given a `source` range that is expensive to iterate over, returns an
    $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that
    asynchronously buffers the contents of `source` into a buffer of `bufSize` elements in a worker thread,
    while making previously buffered elements from a second buffer, also of size
    `bufSize`, available via the range interface of the returned
    object.  The returned range has a length iff `hasLength!S`.
    `asyncBuf` is useful, for example, when performing expensive operations
    on the elements of ranges that represent data on a disk or network.

    Example:
    ---
    import std.conv, std.stdio;

    void main()
    {
        // Fetch lines of a file in a background thread
        // while processing previously fetched lines,
        // dealing with byLine's buffer recycling by
        // eagerly duplicating every line.
        auto lines = File("foo.txt").byLine();
        auto duped = std.algorithm.map!"a.idup"(lines);

        // Fetch more lines in the background while we
        // process the lines already read into memory
        // into a matrix of doubles.
        double[][] matrix;
        auto asyncReader = taskPool.asyncBuf(duped);

        foreach (line; asyncReader)
        {
            auto ls = line.split("\t");
            matrix ~= to!(double[])(ls);
        }
    }
    ---

    $(B Exception Handling):

    Any exceptions thrown while iterating over `source` are re-thrown on a
    call to `popFront` or, if thrown during construction, simply
    allowed to propagate to the caller.
    */
    auto asyncBuf(S)(S source, size_t bufSize = 100) if (isInputRange!S)
    {
        static final class AsyncBuf
        {
            // This is a class because the task and source both need to be on
            // the heap.

            // The element type of S.
            alias E = ElementType!S;  // Needs to be here b/c of forward ref bugs.

        private:
            E[] buf1, buf2;
            S source;
            TaskPool pool;
            Task!(run, E[] delegate(E[]), E[]) nextBufTask;
            size_t bufPos;
            bool lastTaskWaited;

            static if (hasLength!S)
            {
                size_t _length;

                // Available if hasLength!S.
                public @property size_t length() const @safe pure nothrow
                {
                    return _length;
                }
            }

            this(S source, size_t bufSize, TaskPool pool)
            {
                buf1.length = bufSize;
                buf2.length = bufSize;

                this.source = source;
                this.pool = pool;

                static if (hasLength!S)
                {
                    _length = source.length;
                }

                buf1 = fillBuf(buf1);
                submitBuf2();
            }

            E[] fillBuf(E[] buf)
            {
                assert(buf !is null);

                size_t i;
                for (; !source.empty && i < buf.length; source.popFront())
                {
                    buf[i++] = source.front;
                }

                buf = buf[0 .. i];
                return buf;
            }

            void submitBuf2()
            in
            {
                assert(nextBufTask.prev is null);
                assert(nextBufTask.next is null);
            }
            do
            {
                // Hack to reuse the task object.

                nextBufTask = typeof(nextBufTask).init;
                nextBufTask._args[0] = &fillBuf;
                nextBufTask._args[1] = buf2;
                pool.put(nextBufTask);
            }

            void doBufSwap()
            {
                if (lastTaskWaited)
                {
                    // Then source is empty.  Signal it here.
                    buf1 = null;
                    buf2 = null;
                    return;
                }

                buf2 = buf1;
                buf1 = nextBufTask.yieldForce;
                bufPos = 0;

                if (source.empty)
                {
                    lastTaskWaited = true;
                }
                else
                {
                    submitBuf2();
                }
            }

        public:
            E front() @property
            {
                return buf1[bufPos];
            }

            void popFront()
            {
                static if (hasLength!S)
                {
                    _length--;
                }

                bufPos++;
                if (bufPos >= buf1.length)
                {
                    doBufSwap();
                }
            }

            static if (isInfinite!S)
            {
                enum bool empty = false;
            }

            else
            {
                ///
                bool empty() @property
                {
                    // popFront() sets this when source is empty:
                    return buf1.length == 0;
                }
            }
        }
        return new AsyncBuf(source, bufSize, this);
    }

    /**
    Given a callable object `next` that writes to a user-provided buffer and
    a second callable object `empty` that determines whether more data is
    available to write via `next`, returns an input range that
    asynchronously calls `next` with a set of size `nBuffers` of buffers
    and makes the results available in the order they were obtained via the
    input range interface of the returned object.  Similarly to the
    input range overload of `asyncBuf`, the first half of the buffers
    are made available via the range interface while the second half are
    filled and vice-versa.

    Params:

    next = A callable object that takes a single argument that must be an array
           with mutable elements.  When called, `next` writes data to
           the array provided by the caller.

    empty = A callable object that takes no arguments and returns a type
            implicitly convertible to `bool`.  This is used to signify
            that no more data is available to be obtained by calling `next`.

    initialBufSize = The initial size of each buffer.  If `next` takes its
                     array by reference, it may resize the buffers.

    nBuffers = The number of buffers to cycle through when calling `next`.

    Example:
    ---
    // Fetch lines of a file in a background
    // thread while processing previously fetched
    // lines, without duplicating any lines.
    auto file = File("foo.txt");

    void next(ref char[] buf)
    {
        file.readln(buf);
    }

    // Fetch more lines in the background while we
    // process the lines already read into memory
    // into a matrix of doubles.
    double[][] matrix;
    auto asyncReader = taskPool.asyncBuf(&next, &file.eof);

    foreach (line; asyncReader)
    {
        auto ls = line.split("\t");
        matrix ~= to!(double[])(ls);
    }
    ---

    $(B Exception Handling):

    Any exceptions thrown while iterating over `range` are re-thrown on a
    call to `popFront`.

    Warning:

    Using the range returned by this function in a parallel foreach loop
    will not work because buffers may be overwritten while the task that
    processes them is in queue.  This is checked for at compile time
    and will result in a static assertion failure.
    */
    auto asyncBuf(C1, C2)(C1 next, C2 empty, size_t initialBufSize = 0, size_t nBuffers = 100)
    if (is(typeof(C2.init()) : bool) &&
        Parameters!C1.length == 1 &&
        Parameters!C2.length == 0 &&
        isArray!(Parameters!C1[0])
    ) {
        auto roundRobin = RoundRobinBuffer!(C1, C2)(next, empty, initialBufSize, nBuffers);
        return asyncBuf(roundRobin, nBuffers / 2);
    }

    ///
    template reduce(functions...)
    {
        /**
        Parallel reduce on a random access range.  Except as otherwise noted,
        usage is similar to $(REF _reduce, std,algorithm,iteration).  There is
        also $(LREF fold) which does the same thing with a different parameter
        order.

        This function works by splitting the range to be reduced into work
        units, which are slices to be reduced in parallel.  Once the results
        from all work units are computed, a final serial reduction is performed
        on these results to compute the final answer. Therefore, care must be
        taken to choose the seed value appropriately.

        Because the reduction is being performed in parallel, `functions`
        must be associative.  For notational simplicity, let # be an
        infix operator representing `functions`.  Then, (a # b) # c must equal
        a # (b # c).  Floating point addition is not associative
        even though addition in exact arithmetic is.  Summing floating
        point numbers using this function may give different results than summing
        serially.  However, for many practical purposes floating point addition
        can be treated as associative.

        Note that, since `functions` are assumed to be associative,
        additional optimizations are made to the serial portion of the reduction
        algorithm. These take advantage of the instruction level parallelism of
        modern CPUs, in addition to the thread-level parallelism that the rest
        of this module exploits.  This can lead to better than linear speedups
        relative to $(REF _reduce, std,algorithm,iteration), especially for
        fine-grained benchmarks like dot products.

        An explicit seed may be provided as the first argument.  If
        provided, it is used as the seed for all work units and for the final
        reduction of results from all work units.  Therefore, if it is not the
        identity value for the operation being performed, results may differ
        from those generated by $(REF _reduce, std,algorithm,iteration) or
        depending on how many work units are used.  The next argument must be
        the range to be reduced.
        ---
        // Find the sum of squares of a range in parallel, using
        // an explicit seed.
        //
        // Timings on an Athlon 64 X2 dual core machine:
        //
        // Parallel reduce:                     72 milliseconds
        // Using std.algorithm.reduce instead:  181 milliseconds
        auto nums = iota(10_000_000.0f);
        auto sumSquares = taskPool.reduce!"a + b"(
            0.0, std.algorithm.map!"a * a"(nums)
        );
        ---

        If no explicit seed is provided, the first element of each work unit
        is used as a seed.  For the final reduction, the result from the first
        work unit is used as the seed.
        ---
        // Find the sum of a range in parallel, using the first
        // element of each work unit as the seed.
        auto sum = taskPool.reduce!"a + b"(nums);
        ---

        An explicit work unit size may be specified as the last argument.
        Specifying too small a work unit size will effectively serialize the
        reduction, as the final reduction of the result of each work unit will
        dominate computation time.  If `TaskPool.size` for this instance
        is zero, this parameter is ignored and one work unit is used.
        ---
        // Use a work unit size of 100.
        auto sum2 = taskPool.reduce!"a + b"(nums, 100);

        // Work unit size of 100 and explicit seed.
        auto sum3 = taskPool.reduce!"a + b"(0.0, nums, 100);
        ---

        Parallel reduce supports multiple functions, like
        `std.algorithm.reduce`.
        ---
        // Find both the min and max of nums.
        auto minMax = taskPool.reduce!(min, max)(nums);
        assert(minMax[0] == reduce!min(nums));
        assert(minMax[1] == reduce!max(nums));
        ---

        $(B Exception Handling):

        After this function is finished executing, any exceptions thrown
        are chained together via `Throwable.next` and rethrown.  The chaining
        order is non-deterministic.

        See_Also:

            $(LREF fold) is functionally equivalent to $(LREF _reduce) except the
            range parameter comes first and there is no need to use
            $(REF_ALTTEXT `tuple`,tuple,std,typecons) for multiple seeds.
         */
        auto reduce(Args...)(Args args)
        {
            import core.exception : OutOfMemoryError;
            import core.internal.lifetime : emplaceRef;
            import std.exception : enforce;

            alias fun = reduceAdjoin!functions;
            alias finishFun = reduceFinish!functions;

            static if (isIntegral!(Args[$ - 1]))
            {
                size_t workUnitSize = cast(size_t) args[$ - 1];
                alias args2 = args[0..$ - 1];
                alias Args2 = Args[0..$ - 1];
            }
            else
            {
                alias args2 = args;
                alias Args2 = Args;
            }

            auto makeStartValue(Type)(Type e)
            {
                static if (functions.length == 1)
                {
                    return e;
                }
                else
                {
                    typeof(adjoin!(staticMap!(binaryFun, functions))(e, e)) seed = void;
                    foreach (i, T; seed.Types)
                    {
                        emplaceRef(seed.expand[i], e);
                    }

                    return seed;
                }
            }

            static if (args2.length == 2)
            {
                static assert(isInputRange!(Args2[1]));
                alias range = args2[1];
                alias seed = args2[0];
                enum explicitSeed = true;

                static if (!is(typeof(workUnitSize)))
                {
                    size_t workUnitSize = defaultWorkUnitSize(range.length);
                }
            }
            else
            {
                static assert(args2.length == 1);
                alias range = args2[0];

                static if (!is(typeof(workUnitSize)))
                {
                    size_t workUnitSize = defaultWorkUnitSize(range.length);
                }

                enforce(!range.empty,
                    "Cannot reduce an empty range with first element as start value.");

                auto seed = makeStartValue(range.front);
                enum explicitSeed = false;
                range.popFront();
            }

            alias E = typeof(seed);
            alias R = typeof(range);

            E reduceOnRange(R range, size_t lowerBound, size_t upperBound)
            {
                // This is for exploiting instruction level parallelism by
                // using multiple accumulator variables within each thread,
                // since we're assuming functions are associative anyhow.

                // This is so that loops can be unrolled automatically.
                enum ilpTuple = AliasSeq!(0, 1, 2, 3, 4, 5);
                enum nILP = ilpTuple.length;
                immutable subSize = (upperBound - lowerBound) / nILP;

                if (subSize <= 1)
                {
                    // Handle as a special case.
                    static if (explicitSeed)
                    {
                        E result = seed;
                    }
                    else
                    {
                        E result = makeStartValue(range[lowerBound]);
                        lowerBound++;
                    }

                    foreach (i; lowerBound .. upperBound)
                    {
                        result = fun(result, range[i]);
                    }

                    return result;
                }

                assert(subSize > 1);
                E[nILP] results;
                size_t[nILP] offsets;

                foreach (i; ilpTuple)
                {
                    offsets[i] = lowerBound + subSize * i;

                    static if (explicitSeed)
                    {
                        results[i] = seed;
                    }
                    else
                    {
                        results[i] = makeStartValue(range[offsets[i]]);
                        offsets[i]++;
                    }
                }

                immutable nLoop = subSize - (!explicitSeed);
                foreach (i; 0 .. nLoop)
                {
                    foreach (j; ilpTuple)
                    {
                        results[j] = fun(results[j], range[offsets[j]]);
                        offsets[j]++;
                    }
                }

                // Finish the remainder.
                foreach (i; nILP * subSize + lowerBound .. upperBound)
                {
                    results[$ - 1] = fun(results[$ - 1], range[i]);
                }

                foreach (i; ilpTuple[1..$])
                {
                    results[0] = finishFun(results[0], results[i]);
                }

                return results[0];
            }

            immutable len = range.length;
            if (len == 0)
            {
                return seed;
            }

            if (this.size == 0)
            {
                return finishFun(seed, reduceOnRange(range, 0, len));
            }

            // Unlike the rest of the functions here, I can't use the Task object
            // recycling trick here because this has to work on non-commutative
            // operations.  After all the tasks are done executing, fun() has to
            // be applied on the results of these to get a final result, but
            // it can't be evaluated out of order.

            if (workUnitSize > len)
            {
                workUnitSize = len;
            }

            immutable size_t nWorkUnits = (len / workUnitSize) + ((len % workUnitSize == 0) ? 0 : 1);
            assert(nWorkUnits * workUnitSize >= len);

            alias RTask = Task!(run, typeof(&reduceOnRange), R, size_t, size_t);
            RTask[] tasks;

            // Can't use alloca() due to https://issues.dlang.org/show_bug.cgi?id=3753
            // Use a fixed buffer backed by malloc().
            enum maxStack = 2_048;
            byte[maxStack] buf = void;
            immutable size_t nBytesNeeded = nWorkUnits * RTask.sizeof;

            import core.stdc.stdlib : malloc, free;
            if (nBytesNeeded <= maxStack)
            {
                tasks = (cast(RTask*) buf.ptr)[0 .. nWorkUnits];
            }
            else
            {
                auto ptr = cast(RTask*) malloc(nBytesNeeded);
                if (!ptr)
                {
                    throw new OutOfMemoryError(
                        "Out of memory in std.parallelism."
                    );
                }

                tasks = ptr[0 .. nWorkUnits];
            }

            scope(exit)
            {
                if (nBytesNeeded > maxStack)
                {
                    free(tasks.ptr);
                }
            }

            // Hack to take the address of a nested function w/o
            // making a closure.
            static auto scopedAddress(D)(scope D del) @system
            {
                auto tmp = del;
                return tmp;
            }

            size_t curPos = 0;
            void useTask(ref RTask task)
            {
                import std.algorithm.comparison : min;
                import core.lifetime : emplace;

                // Private constructor, so can't feed it's arguments directly
                // to emplace
                emplace(&task, RTask
                (
                    scopedAddress(&reduceOnRange),
                    range,
                    curPos, // lower bound.
                    cast() min(len, curPos + workUnitSize)  // upper bound.
                ));

                task.pool = this;

                curPos += workUnitSize;
            }

            foreach (ref task; tasks)
            {
                useTask(task);
            }

            foreach (i; 1 .. tasks.length - 1)
            {
                tasks[i].next = tasks[i + 1].basePtr;
                tasks[i + 1].prev = tasks[i].basePtr;
            }

            if (tasks.length > 1)
            {
                queueLock();
                scope(exit) queueUnlock();

                abstractPutGroupNoSync(
                    tasks[1].basePtr,
                    tasks[$ - 1].basePtr
                );
            }

            if (tasks.length > 0)
            {
                try
                {
                    tasks[0].job();
                }
                catch (Throwable e)
                {
                    tasks[0].exception = e;
                }
                tasks[0].taskStatus = TaskStatus.done;

                // Try to execute each of these in the current thread
                foreach (ref task; tasks[1..$])
                {
                    tryDeleteExecute(task.basePtr);
                }
            }

            // Now that we've tried to execute every task, they're all either
            // done or in progress.  Force all of them.
            E result = seed;

            Throwable firstException;

            foreach (ref task; tasks)
            {
                try
                {
                    task.yieldForce;
                }
                catch (Throwable e)
                {
                    /* Chain e to front because order doesn't matter and because
                     * e is not likely to be a chain itself (so fewer traversals)
                     */
                    firstException = Throwable.chainTogether(e, firstException);
                    continue;
                }

                if (!firstException) result = finishFun(result, task.returnVal);
            }

            if (firstException) throw firstException;

            return result;
        }
    }

    ///
    template fold(functions...)
    {
        /** Implements the homonym function (also known as `accumulate`, `compress`,
            `inject`, or `foldl`) present in various programming languages of
            functional flavor.

            `fold` is functionally equivalent to $(LREF reduce) except the range
            parameter comes first and there is no need to use $(REF_ALTTEXT
            `tuple`,tuple,std,typecons) for multiple seeds.

            There may be one or more callable entities (`functions` argument) to
            apply.

            Params:
                args = Just the range to _fold over; or the range and one seed
                       per function; or the range, one seed per function, and
                       the work unit size

            Returns:
                The accumulated result as a single value for single function and
                as a tuple of values for multiple functions

            See_Also:
            Similar to $(REF _fold, std,algorithm,iteration), `fold` is a wrapper around $(LREF reduce).

            Example:
            ---
            static int adder(int a, int b)
            {
                return a + b;
            }
            static int multiplier(int a, int b)
            {
                return a * b;
            }

            // Just the range
            auto x = taskPool.fold!adder([1, 2, 3, 4]);
            assert(x == 10);

            // The range and the seeds (0 and 1 below; also note multiple
            // functions in this example)
            auto y = taskPool.fold!(adder, multiplier)([1, 2, 3, 4], 0, 1);
            assert(y[0] == 10);
            assert(y[1] == 24);

            // The range, the seed (0), and the work unit size (20)
            auto z = taskPool.fold!adder([1, 2, 3, 4], 0, 20);
            assert(z == 10);
            ---
        */
        auto fold(Args...)(Args args)
        {
            static assert(isInputRange!(Args[0]), "First argument must be an InputRange");

            alias range = args[0];

            static if (Args.length == 1)
            {
                // Just the range
                return reduce!functions(range);
            }
            else static if (Args.length == 1 + functions.length ||
                            Args.length == 1 + functions.length + 1)
            {
                static if (functions.length == 1)
                {
                    alias seeds = args[1];
                }
                else
                {
                    auto seeds()
                    {
                        import std.typecons : tuple;
                        return tuple(args[1 .. functions.length+1]);
                    }
                }

                static if (Args.length == 1 + functions.length)
                {
                    // The range and the seeds
                    return reduce!functions(seeds, range);
                }
                else static if (Args.length == 1 + functions.length + 1)
                {
                    // The range, the seeds, and the work unit size
                    static assert(isIntegral!(Args[$-1]), "Work unit size must be an integral type");
                    return reduce!functions(seeds, range, args[$-1]);
                }
            }
            else
            {
                import std.conv : text;
                static assert(0, "Invalid number of arguments (" ~ Args.length.text ~ "): Should be an input range, "
                              ~ functions.length.text ~ " optional seed(s), and an optional work unit size.");
            }
        }
    }

    // This test is not included in the documentation because even though these
    // examples are for the inner fold() template, with their current location,
    // they would appear under the outer one. (We can't move this inside the
    // outer fold() template because then dmd runs out of memory possibly due to
    // recursive template instantiation, which is surprisingly not caught.)
    @system unittest
    {
        // Just the range
        auto x = taskPool.fold!"a + b"([1, 2, 3, 4]);
        assert(x == 10);

        // The range and the seeds (0 and 1 below; also note multiple
        // functions in this example)
        auto y = taskPool.fold!("a + b", "a * b")([1, 2, 3, 4], 0, 1);
        assert(y[0] == 10);
        assert(y[1] == 24);

        // The range, the seed (0), and the work unit size (20)
        auto z = taskPool.fold!"a + b"([1, 2, 3, 4], 0, 20);
        assert(z == 10);
    }

    /**
    Gets the index of the current thread relative to this `TaskPool`.  Any
    thread not in this pool will receive an index of 0.  The worker threads in
    this pool receive unique indices of 1 through `this.size`.

    This function is useful for maintaining worker-local resources.

    Example:
    ---
    // Execute a loop that computes the greatest common
    // divisor of every number from 0 through 999 with
    // 42 in parallel.  Write the results out to
    // a set of files, one for each thread.  This allows
    // results to be written out without any synchronization.

    import std.conv, std.range, std.numeric, std.stdio;

    void main()
    {
        auto filesHandles = new File[taskPool.size + 1];
        scope(exit) {
            foreach (ref handle; fileHandles)
            {
                handle.close();
            }
        }

        foreach (i, ref handle; fileHandles)
        {
            handle = File("workerResults" ~ to!string(i) ~ ".txt");
        }

        foreach (num; parallel(iota(1_000)))
        {
            auto outHandle = fileHandles[taskPool.workerIndex];
            outHandle.writeln(num, '\t', gcd(num, 42));
        }
    }
    ---
    */
    size_t workerIndex() @property @safe const nothrow
    {
        immutable rawInd = threadIndex;
        return (rawInd >= instanceStartIndex && rawInd < instanceStartIndex + size) ?
                (rawInd - instanceStartIndex + 1) : 0;
    }

    /**
    Struct for creating worker-local storage.  Worker-local storage is
    thread-local storage that exists only for worker threads in a given
    `TaskPool` plus a single thread outside the pool.  It is allocated on the
    garbage collected heap in a way that avoids _false sharing, and doesn't
    necessarily have global scope within any thread.  It can be accessed from
    any worker thread in the `TaskPool` that created it, and one thread
    outside this `TaskPool`.  All threads outside the pool that created a
    given instance of worker-local storage share a single slot.

    Since the underlying data for this struct is heap-allocated, this struct
    has reference semantics when passed between functions.

    The main uses cases for `WorkerLocalStorage` are:

    1.  Performing parallel reductions with an imperative, as opposed to
        functional, programming style.  In this case, it's useful to treat
        `WorkerLocalStorage` as local to each thread for only the parallel
        portion of an algorithm.

    2.  Recycling temporary buffers across iterations of a parallel foreach loop.

    Example:
    ---
    // Calculate pi as in our synopsis example, but
    // use an imperative instead of a functional style.
    immutable n = 1_000_000_000;
    immutable delta = 1.0L / n;

    auto sums = taskPool.workerLocalStorage(0.0L);
    foreach (i; parallel(iota(n)))
    {
        immutable x = ( i - 0.5L ) * delta;
        immutable toAdd = delta / ( 1.0 + x * x );
        sums.get += toAdd;
    }

    // Add up the results from each worker thread.
    real pi = 0;
    foreach (threadResult; sums.toRange)
    {
        pi += 4.0L * threadResult;
    }
    ---
     */
    static struct WorkerLocalStorage(T)
    {
    private:
        TaskPool pool;
        size_t size;

        size_t elemSize;
        bool* stillThreadLocal;

        static size_t roundToLine(size_t num) pure nothrow
        {
            if (num % cacheLineSize == 0)
            {
                return num;
            }
            else
            {
                return ((num / cacheLineSize) + 1) * cacheLineSize;
            }
        }

        void* data;

        void initialize(TaskPool pool)
        {
            this.pool = pool;
            size = pool.size + 1;
            stillThreadLocal = new bool;
            *stillThreadLocal = true;

            // Determines whether the GC should scan the array.
            auto blkInfo = (typeid(T).flags & 1) ?
                           cast(GC.BlkAttr) 0 :
                           GC.BlkAttr.NO_SCAN;

            immutable nElem = pool.size + 1;
            elemSize = roundToLine(T.sizeof);

            // The + 3 is to pad one full cache line worth of space on either side
            // of the data structure to make sure false sharing with completely
            // unrelated heap data is prevented, and to provide enough padding to
            // make sure that data is cache line-aligned.
            data = GC.malloc(elemSize * (nElem + 3), blkInfo) + elemSize;

            // Cache line align data ptr.
            data = cast(void*) roundToLine(cast(size_t) data);

            foreach (i; 0 .. nElem)
            {
                this.opIndex(i) = T.init;
            }
        }

        ref opIndex(this Qualified)(size_t index)
        {
            import std.conv : text;
            assert(index < size, text(index, '\t', uint.max));
            return *(cast(CopyTypeQualifiers!(Qualified, T)*) (data + elemSize * index));
        }

        void opIndexAssign(T val, size_t index)
        {
            assert(index < size);
            *(cast(T*) (data + elemSize * index)) = val;
        }

    public:
        /**
        Get the current thread's instance.  Returns by ref.
        Note that calling `get` from any thread
        outside the `TaskPool` that created this instance will return the
        same reference, so an instance of worker-local storage should only be
        accessed from one thread outside the pool that created it.  If this
        rule is violated, undefined behavior will result.

        If assertions are enabled and `toRange` has been called, then this
        WorkerLocalStorage instance is no longer worker-local and an assertion
        failure will result when calling this method.  This is not checked
        when assertions are disabled for performance reasons.
         */
        ref get(this Qualified)() @property
        {
            assert(*stillThreadLocal,
                "Cannot call get() on this instance of WorkerLocalStorage " ~
                "because it is no longer worker-local."
            );
            return opIndex(pool.workerIndex);
        }

        /**
        Assign a value to the current thread's instance.  This function has
        the same caveats as its overload.
        */
        void get(T val) @property
        {
            assert(*stillThreadLocal,
                "Cannot call get() on this instance of WorkerLocalStorage " ~
                "because it is no longer worker-local."
            );

            opIndexAssign(val, pool.workerIndex);
        }

        /**
        Returns a range view of the values for all threads, which can be used
        to further process the results of each thread after running the parallel
        part of your algorithm.  Do not use this method in the parallel portion
        of your algorithm.

        Calling this function sets a flag indicating that this struct is no
        longer worker-local, and attempting to use the `get` method again
        will result in an assertion failure if assertions are enabled.
         */
        WorkerLocalStorageRange!T toRange() @property
        {
            if (*stillThreadLocal)
            {
                *stillThreadLocal = false;

                // Make absolutely sure results are visible to all threads.
                // This is probably not necessary since some other
                // synchronization primitive will be used to signal that the
                // parallel part of the algorithm is done, but the
                // performance impact should be negligible, so it's better
                // to be safe.
                ubyte barrierDummy;
                atomicSetUbyte(barrierDummy, 1);
            }

            return WorkerLocalStorageRange!T(this);
        }
    }

    /**
    Range primitives for worker-local storage.  The purpose of this is to
    access results produced by each worker thread from a single thread once you
    are no longer using the worker-local storage from multiple threads.
    Do not use this struct in the parallel portion of your algorithm.

    The proper way to instantiate this object is to call
    `WorkerLocalStorage.toRange`.  Once instantiated, this object behaves
    as a finite random-access range with assignable, lvalue elements and
    a length equal to the number of worker threads in the `TaskPool` that
    created it plus 1.
     */
    static struct WorkerLocalStorageRange(T)
    {
    private:
        WorkerLocalStorage!T workerLocalStorage;

        size_t _length;
        size_t beginOffset;

        this(WorkerLocalStorage!T wl)
        {
            this.workerLocalStorage = wl;
            _length = wl.size;
        }

    public:
        ref front(this Qualified)() @property
        {
            return this[0];
        }

        ref back(this Qualified)() @property
        {
            return this[_length - 1];
        }

        void popFront()
        {
            if (_length > 0)
            {
                beginOffset++;
                _length--;
            }
        }

        void popBack()
        {
            if (_length > 0)
            {
                _length--;
            }
        }

        typeof(this) save() @property
        {
            return this;
        }

        ref opIndex(this Qualified)(size_t index)
        {
            assert(index < _length);
            return workerLocalStorage[index + beginOffset];
        }

        void opIndexAssign(T val, size_t index)
        {
            assert(index < _length);
            workerLocalStorage[index] = val;
        }

        typeof(this) opSlice(size_t lower, size_t upper)
        {
            assert(upper <= _length);
            auto newWl = this.workerLocalStorage;
            newWl.data += lower * newWl.elemSize;
            newWl.size = upper - lower;
            return typeof(this)(newWl);
        }

        bool empty() const @property
        {
            return length == 0;
        }

        size_t length() const @property
        {
            return _length;
        }
    }

    /**
    Creates an instance of worker-local storage, initialized with a given
    value.  The value is `lazy` so that you can, for example, easily
    create one instance of a class for each worker.  For usage example,
    see the `WorkerLocalStorage` struct.
     */
    WorkerLocalStorage!T workerLocalStorage(T)(lazy T initialVal = T.init)
    {
        WorkerLocalStorage!T ret;
        ret.initialize(this);
        foreach (i; 0 .. size + 1)
        {
            ret[i] = initialVal;
        }

        // Memory barrier to make absolutely sure that what we wrote is
        // visible to worker threads.
        ubyte barrierDummy;
        atomicSetUbyte(barrierDummy, 0);

        return ret;
    }

    /**
    Signals to all worker threads to terminate as soon as they are finished
    with their current `Task`, or immediately if they are not executing a
    `Task`.  `Task`s that were in queue will not be executed unless
    a call to `Task.workForce`, `Task.yieldForce` or `Task.spinForce`
    causes them to be executed.

    Use only if you have waited on every `Task` and therefore know the
    queue is empty, or if you speculatively executed some tasks and no longer
    need the results.
     */
    void stop() @trusted
    {
        queueLock();
        scope(exit) queueUnlock();
        atomicSetUbyte(status, PoolState.stopNow);
        notifyAll();
    }

    /**
    Signals worker threads to terminate when the queue becomes empty.

    If blocking argument is true, wait for all worker threads to terminate
    before returning.  This option might be used in applications where
    task results are never consumed-- e.g. when `TaskPool` is employed as a
    rudimentary scheduler for tasks which communicate by means other than
    return values.

    Warning:  Calling this function with $(D blocking = true) from a worker
              thread that is a member of the same `TaskPool` that
              `finish` is being called on will result in a deadlock.
     */
    void finish(bool blocking = false) @trusted
    {
        {
            queueLock();
            scope(exit) queueUnlock();
            atomicCasUbyte(status, PoolState.running, PoolState.finishing);
            notifyAll();
        }
        if (blocking)
        {
            // Use this thread as a worker until everything is finished.
            executeWorkLoop();

            foreach (t; pool)
            {
                // Maybe there should be something here to prevent a thread
                // from calling join() on itself if this function is called
                // from a worker thread in the same pool, but:
                //
                // 1.  Using an if statement to skip join() would result in
                //     finish() returning without all tasks being finished.
                //
                // 2.  If an exception were thrown, it would bubble up to the
                //     Task from which finish() was called and likely be
                //     swallowed.
                t.join();
            }
        }
    }

    /// Returns the number of worker threads in the pool.
    @property size_t size() @safe const pure nothrow
    {
        return pool.length;
    }

    /**
    Put a `Task` object on the back of the task queue.  The `Task`
    object may be passed by pointer or reference.

    Example:
    ---
    import std.file;

    // Create a task.
    auto t = task!read("foo.txt");

    // Add it to the queue to be executed.
    taskPool.put(t);
    ---

    Notes:

    @trusted overloads of this function are called for `Task`s if
    $(REF hasUnsharedAliasing, std,traits) is false for the `Task`'s
    return type or the function the `Task` executes is `pure`.
    `Task` objects that meet all other requirements specified in the
    `@trusted` overloads of `task` and `scopedTask` may be created
    and executed from `@safe` code via `Task.executeInNewThread` but
    not via `TaskPool`.

    While this function takes the address of variables that may
    be on the stack, some overloads are marked as @trusted.
    `Task` includes a destructor that waits for the task to complete
    before destroying the stack frame it is allocated on.  Therefore,
    it is impossible for the stack frame to be destroyed before the task is
    complete and no longer referenced by a `TaskPool`.
    */
    void put(alias fun, Args...)(ref Task!(fun, Args) task)
    if (!isSafeReturn!(typeof(task)))
    {
        task.pool = this;
        abstractPut(task.basePtr);
    }

    /// Ditto
    void put(alias fun, Args...)(Task!(fun, Args)* task)
    if (!isSafeReturn!(typeof(*task)))
    {
        import std.exception : enforce;
        enforce(task !is null, "Cannot put a null Task on a TaskPool queue.");
        put(*task);
    }

    @trusted void put(alias fun, Args...)(ref Task!(fun, Args) task)
    if (isSafeReturn!(typeof(task)))
    {
        task.pool = this;
        abstractPut(task.basePtr);
    }

    @trusted void put(alias fun, Args...)(Task!(fun, Args)* task)
    if (isSafeReturn!(typeof(*task)))
    {
        import std.exception : enforce;
        enforce(task !is null, "Cannot put a null Task on a TaskPool queue.");
        put(*task);
    }

    /**
    These properties control whether the worker threads are daemon threads.
    A daemon thread is automatically terminated when all non-daemon threads
    have terminated.  A non-daemon thread will prevent a program from
    terminating as long as it has not terminated.

    If any `TaskPool` with non-daemon threads is active, either `stop`
    or `finish` must be called on it before the program can terminate.

    The worker treads in the `TaskPool` instance returned by the
    `taskPool` property are daemon by default.  The worker threads of
    manually instantiated task pools are non-daemon by default.

    Note:  For a size zero pool, the getter arbitrarily returns true and the
           setter has no effect.
    */
    bool isDaemon() @property @trusted
    {
        queueLock();
        scope(exit) queueUnlock();
        return (size == 0) ? true : pool[0].isDaemon;
    }

    /// Ditto
    void isDaemon(bool newVal) @property @trusted
    {
        queueLock();
        scope(exit) queueUnlock();
        foreach (thread; pool)
        {
            thread.isDaemon = newVal;
        }
    }

    /**
    These functions allow getting and setting the OS scheduling priority of
    the worker threads in this `TaskPool`.  They forward to
    `core.thread.Thread.priority`, so a given priority value here means the
    same thing as an identical priority value in `core.thread`.

    Note:  For a size zero pool, the getter arbitrarily returns
           `core.thread.Thread.PRIORITY_MIN` and the setter has no effect.
    */
    int priority() @property @trusted
    {
        return (size == 0) ? core.thread.Thread.PRIORITY_MIN :
        pool[0].priority;
    }

    /// Ditto
    void priority(int newPriority) @property @trusted
    {
        if (size > 0)
        {
            foreach (t; pool)
            {
                t.priority = newPriority;
            }
        }
    }
}

@system unittest
{
    import std.algorithm.iteration : sum;
    import std.range : iota;
    import std.typecons : tuple;

    enum N = 100;
    auto r = iota(1, N + 1);
    const expected = r.sum();

    // Just the range
    assert(taskPool.fold!"a + b"(r) == expected);

    // Range and seeds
    assert(taskPool.fold!"a + b"(r, 0) == expected);
    assert(taskPool.fold!("a + b", "a + b")(r, 0, 0) == tuple(expected, expected));

    // Range, seeds, and work unit size
    assert(taskPool.fold!"a + b"(r, 0, 42) == expected);
    assert(taskPool.fold!("a + b", "a + b")(r, 0, 0, 42) == tuple(expected, expected));
}

// Issue 16705
@system unittest
{
    struct MyIota
    {
        size_t front;
        void popFront()(){front++;}
        auto empty(){return front >= 25;}
        auto opIndex(size_t i){return front+i;}
        auto length(){return 25-front;}
    }

    auto mySum = taskPool.reduce!"a + b"(MyIota());
}

/**
Returns a lazily initialized global instantiation of `TaskPool`.
This function can safely be called concurrently from multiple non-worker
threads.  The worker threads in this pool are daemon threads, meaning that it
is not necessary to call `TaskPool.stop` or `TaskPool.finish` before
terminating the main thread.
*/
@property TaskPool taskPool() @trusted
{
    import std.concurrency : initOnce;
    __gshared TaskPool pool;
    return initOnce!pool({
        auto p = new TaskPool(defaultPoolThreads);
        p.isDaemon = true;
        return p;
    }());
}

private shared uint _defaultPoolThreads = uint.max;

/**
These properties get and set the number of worker threads in the `TaskPool`
instance returned by `taskPool`.  The default value is `totalCPUs` - 1.
Calling the setter after the first call to `taskPool` does not changes
number of worker threads in the instance returned by `taskPool`.
*/
@property uint defaultPoolThreads() @trusted
{
    const local = atomicLoad(_defaultPoolThreads);
    return local < uint.max ? local : totalCPUs - 1;
}

/// Ditto
@property void defaultPoolThreads(uint newVal) @trusted
{
    atomicStore(_defaultPoolThreads, newVal);
}

/**
Convenience functions that forwards to `taskPool.parallel`.  The
purpose of these is to make parallel foreach less verbose and more
readable.

Example:
---
// Find the logarithm of every number from
// 1 to 1_000_000 in parallel, using the
// default TaskPool instance.
auto logs = new double[1_000_000];

foreach (i, ref elem; parallel(logs))
{
    elem = log(i + 1.0);
}
---

*/
ParallelForeach!R parallel(R)(R range)
{
    return taskPool.parallel(range);
}

/// Ditto
ParallelForeach!R parallel(R)(R range, size_t workUnitSize)
{
    return taskPool.parallel(range, workUnitSize);
}

//  `each` should be usable with parallel
// https://issues.dlang.org/show_bug.cgi?id=17019
@system unittest
{
    import std.algorithm.iteration : each, sum;
    import std.range : iota;

    // check behavior with parallel
    auto arr = new int[10];
    parallel(arr).each!((ref e) => e += 1);
    assert(arr.sum == 10);

    auto arrIndex = new int[10];
    parallel(arrIndex).each!((i, ref e) => e += i);
    assert(arrIndex.sum == 10.iota.sum);
}

// https://issues.dlang.org/show_bug.cgi?id=22745
@system unittest
{
    auto pool = new TaskPool(0);
    int[] empty;
    foreach (i; pool.parallel(empty)) {}
    pool.finish();
}

// Thrown when a parallel foreach loop is broken from.
class ParallelForeachError : Error
{
    this()
    {
        super("Cannot break from a parallel foreach loop using break, return, "
              ~ "labeled break/continue or goto statements.");
    }
}

/*------Structs that implement opApply for parallel foreach.------------------*/
private template randLen(R)
{
    enum randLen = isRandomAccessRange!R && hasLength!R;
}

private void submitAndExecute(
    TaskPool pool,
    scope void delegate() doIt
)
{
    import core.exception : OutOfMemoryError;
    immutable nThreads = pool.size + 1;

    alias PTask = typeof(scopedTask(doIt));
    import core.stdc.stdlib : malloc, free;
    import core.stdc.string : memcpy;

    // The logical thing to do would be to just use alloca() here, but that
    // causes problems on Windows for reasons that I don't understand
    // (tentatively a compiler bug) and definitely doesn't work on Posix due
    // to https://issues.dlang.org/show_bug.cgi?id=3753.
    // Therefore, allocate a fixed buffer and fall back to `malloc()` if
    // someone's using a ridiculous amount of threads.
    // Also, the using a byte array instead of a PTask array as the fixed buffer
    // is to prevent d'tors from being called on uninitialized excess PTask
    // instances.
    enum nBuf = 64;
    byte[nBuf * PTask.sizeof] buf = void;
    PTask[] tasks;
    if (nThreads <= nBuf)
    {
        tasks = (cast(PTask*) buf.ptr)[0 .. nThreads];
    }
    else
    {
        auto ptr = cast(PTask*) malloc(nThreads * PTask.sizeof);
        if (!ptr) throw new OutOfMemoryError("Out of memory in std.parallelism.");
        tasks = ptr[0 .. nThreads];
    }

    scope(exit)
    {
        if (nThreads > nBuf)
        {
            free(tasks.ptr);
        }
    }

    foreach (ref t; tasks)
    {
        import core.stdc.string : memcpy;

        // This silly looking code is necessary to prevent d'tors from being
        // called on uninitialized objects.
        auto temp = scopedTask(doIt);
        memcpy(&t, &temp, PTask.sizeof);

        // This has to be done to t after copying, not temp before copying.
        // Otherwise, temp's destructor will sit here and wait for the
        // task to finish.
        t.pool = pool;
    }

    foreach (i; 1 .. tasks.length - 1)
    {
        tasks[i].next = tasks[i + 1].basePtr;
        tasks[i + 1].prev = tasks[i].basePtr;
    }

    if (tasks.length > 1)
    {
        pool.queueLock();
        scope(exit) pool.queueUnlock();

        pool.abstractPutGroupNoSync(
            tasks[1].basePtr,
            tasks[$ - 1].basePtr
        );
    }

    if (tasks.length > 0)
    {
        try
        {
            tasks[0].job();
        }
        catch (Throwable e)
        {
            tasks[0].exception = e; // nocoverage
        }
        tasks[0].taskStatus = TaskStatus.done;

        // Try to execute each of these in the current thread
        foreach (ref task; tasks[1..$])
        {
            pool.tryDeleteExecute(task.basePtr);
        }
    }

    Throwable firstException;

    foreach (i, ref task; tasks)
    {
        try
        {
            task.yieldForce;
        }
        catch (Throwable e)
        {
            /* Chain e to front because order doesn't matter and because
             * e is not likely to be a chain itself (so fewer traversals)
             */
            firstException = Throwable.chainTogether(e, firstException);
            continue;
        }
    }

    if (firstException) throw firstException;
}

void foreachErr()
{
    throw new ParallelForeachError();
}

int doSizeZeroCase(R, Delegate)(ref ParallelForeach!R p, Delegate dg)
{
    with(p)
    {
        int res = 0;
        size_t index = 0;

        // The explicit ElementType!R in the foreach loops is necessary for
        // correct behavior when iterating over strings.
        static if (hasLvalueElements!R)
        {
            foreach (ref ElementType!R elem; range)
            {
                static if (Parameters!dg.length == 2)
                {
                    res = dg(index, elem);
                }
                else
                {
                    res = dg(elem);
                }
                if (res) break;
                index++;
            }
        }
        else
        {
            foreach (ElementType!R elem; range)
            {
                static if (Parameters!dg.length == 2)
                {
                    res = dg(index, elem);
                }
                else
                {
                    res = dg(elem);
                }
                if (res) break;
                index++;
            }
        }
        if (res) foreachErr;
        return res;
    }
}

private enum string parallelApplyMixinRandomAccess = q{
    // Handle empty thread pool as special case.
    if (pool.size == 0)
    {
        return doSizeZeroCase(this, dg);
    }

    // Whether iteration is with or without an index variable.
    enum withIndex = Parameters!(typeof(dg)).length == 2;

    shared size_t workUnitIndex = size_t.max;  // Effectively -1:  chunkIndex + 1 == 0
    immutable len = range.length;
    if (!len) return 0;

    shared bool shouldContinue = true;

    void doIt()
    {
        import std.algorithm.comparison : min;

        scope(failure)
        {
            // If an exception is thrown, all threads should bail.
            atomicStore(shouldContinue, false);
        }

        while (atomicLoad(shouldContinue))
        {
            immutable myUnitIndex = atomicOp!"+="(workUnitIndex, 1);
            immutable start = workUnitSize * myUnitIndex;
            if (start >= len)
            {
                atomicStore(shouldContinue, false);
                break;
            }

            immutable end = min(len, start + workUnitSize);

            foreach (i; start .. end)
            {
                static if (withIndex)
                {
                    if (dg(i, range[i])) foreachErr();
                }
                else
                {
                    if (dg(range[i])) foreachErr();
                }
            }
        }
    }

    submitAndExecute(pool, &doIt);

    return 0;
};

enum string parallelApplyMixinInputRange = q{
    // Handle empty thread pool as special case.
    if (pool.size == 0)
    {
        return doSizeZeroCase(this, dg);
    }

    // Whether iteration is with or without an index variable.
    enum withIndex = Parameters!(typeof(dg)).length == 2;

    // This protects the range while copying it.
    auto rangeMutex = new Mutex();

    shared bool shouldContinue = true;

    // The total number of elements that have been popped off range.
    // This is updated only while protected by rangeMutex;
    size_t nPopped = 0;

    static if (
        is(typeof(range.buf1)) &&
        is(typeof(range.bufPos)) &&
        is(typeof(range.doBufSwap()))
    )
    {
        // Make sure we don't have the buffer recycling overload of
        // asyncBuf.
        static if (
            is(typeof(range.source)) &&
            isRoundRobin!(typeof(range.source))
        )
        {
            static assert(0, "Cannot execute a parallel foreach loop on " ~
            "the buffer recycling overload of asyncBuf.");
        }

        enum bool bufferTrick = true;
    }
    else
    {
        enum bool bufferTrick = false;
    }

    void doIt()
    {
        scope(failure)
        {
            // If an exception is thrown, all threads should bail.
            atomicStore(shouldContinue, false);
        }

        static if (hasLvalueElements!R)
        {
            alias Temp = ElementType!R*[];
            Temp temp;

            // Returns:  The previous value of nPopped.
            size_t makeTemp()
            {
                import std.algorithm.internal : addressOf;
                import std.array : uninitializedArray;

                if (temp is null)
                {
                    temp = uninitializedArray!Temp(workUnitSize);
                }

                rangeMutex.lock();
                scope(exit) rangeMutex.unlock();

                size_t i = 0;
                for (; i < workUnitSize && !range.empty; range.popFront(), i++)
                {
                    temp[i] = addressOf(range.front);
                }

                temp = temp[0 .. i];
                auto ret = nPopped;
                nPopped += temp.length;
                return ret;
            }

        }
        else
        {

            alias Temp = ElementType!R[];
            Temp temp;

            // Returns:  The previous value of nPopped.
            static if (!bufferTrick) size_t makeTemp()
            {
                import std.array : uninitializedArray;

                if (temp is null)
                {
                    temp = uninitializedArray!Temp(workUnitSize);
                }

                rangeMutex.lock();
                scope(exit) rangeMutex.unlock();

                size_t i = 0;
                for (; i < workUnitSize && !range.empty; range.popFront(), i++)
                {
                    temp[i] = range.front;
                }

                temp = temp[0 .. i];
                auto ret = nPopped;
                nPopped += temp.length;
                return ret;
            }

            static if (bufferTrick) size_t makeTemp()
            {
                import std.algorithm.mutation : swap;
                rangeMutex.lock();
                scope(exit) rangeMutex.unlock();

                // Elide copying by just swapping buffers.
                temp.length = range.buf1.length;
                swap(range.buf1, temp);

                // This is necessary in case popFront() has been called on
                // range before entering the parallel foreach loop.
                temp = temp[range.bufPos..$];

                static if (is(typeof(range._length)))
                {
                    range._length -= (temp.length - range.bufPos);
                }

                range.doBufSwap();
                auto ret = nPopped;
                nPopped += temp.length;
                return ret;
            }
        }

        while (atomicLoad(shouldContinue))
        {
            auto overallIndex = makeTemp();
            if (temp.empty)
            {
                atomicStore(shouldContinue, false);
                break;
            }

            foreach (i; 0 .. temp.length)
            {
                scope(success) overallIndex++;

                static if (hasLvalueElements!R)
                {
                    static if (withIndex)
                    {
                        if (dg(overallIndex, *temp[i])) foreachErr();
                    }
                    else
                    {
                        if (dg(*temp[i])) foreachErr();
                    }
                }
                else
                {
                    static if (withIndex)
                    {
                        if (dg(overallIndex, temp[i])) foreachErr();
                    }
                    else
                    {
                        if (dg(temp[i])) foreachErr();
                    }
                }
            }
        }
    }

    submitAndExecute(pool, &doIt);

    return 0;
};


private struct ParallelForeach(R)
{
    TaskPool pool;
    R range;
    size_t workUnitSize;
    alias E = ElementType!R;

    static if (hasLvalueElements!R)
    {
        alias NoIndexDg = int delegate(ref E);
        alias IndexDg = int delegate(size_t, ref E);
    }
    else
    {
        alias NoIndexDg = int delegate(E);
        alias IndexDg = int delegate(size_t, E);
    }

    int opApply(scope NoIndexDg dg)
    {
        static if (randLen!R)
        {
            mixin(parallelApplyMixinRandomAccess);
        }
        else
        {
            mixin(parallelApplyMixinInputRange);
        }
    }

    int opApply(scope IndexDg dg)
    {
        static if (randLen!R)
        {
            mixin(parallelApplyMixinRandomAccess);
        }
        else
        {
            mixin(parallelApplyMixinInputRange);
        }
    }
}

/*
This struct buffers the output of a callable that outputs data into a
user-supplied buffer into a set of buffers of some fixed size.  It allows these
buffers to be accessed with an input range interface.  This is used internally
in the buffer-recycling overload of TaskPool.asyncBuf, which creates an
instance and forwards it to the input range overload of asyncBuf.
*/
private struct RoundRobinBuffer(C1, C2)
{
    // No need for constraints because they're already checked for in asyncBuf.

    alias Array = Parameters!(C1.init)[0];
    alias T = typeof(Array.init[0]);

    T[][] bufs;
    size_t index;
    C1 nextDel;
    C2 emptyDel;
    bool _empty;
    bool primed;

    this(
        C1 nextDel,
        C2 emptyDel,
        size_t initialBufSize,
        size_t nBuffers
    ) {
        this.nextDel = nextDel;
        this.emptyDel = emptyDel;
        bufs.length = nBuffers;

        foreach (ref buf; bufs)
        {
            buf.length = initialBufSize;
        }
    }

    void prime()
    in
    {
        assert(!empty);
    }
    do
    {
        scope(success) primed = true;
        nextDel(bufs[index]);
    }


    T[] front() @property
    in
    {
        assert(!empty);
    }
    do
    {
        if (!primed) prime();
        return bufs[index];
    }

    void popFront()
    {
        if (empty || emptyDel())
        {
            _empty = true;
            return;
        }

        index = (index + 1) % bufs.length;
        primed = false;
    }

    bool empty() @property const @safe pure nothrow
    {
        return _empty;
    }
}

version (StdUnittest)
{
    // This was the only way I could get nested maps to work.
    private __gshared TaskPool poolInstance;
}

// These test basic functionality but don't stress test for threading bugs.
// These are the tests that should be run every time Phobos is compiled.
@system unittest
{
    import std.algorithm.comparison : equal, min, max;
    import std.algorithm.iteration : filter, map, reduce;
    import std.array : split;
    import std.conv : text;
    import std.exception : assertThrown;
    import std.math.operations : isClose;
    import std.math.algebraic : sqrt, abs;
    import std.math.exponential : log;
    import std.range : indexed, iota, join;
    import std.typecons : Tuple, tuple;
    import std.stdio;

    poolInstance = new TaskPool(2);
    scope(exit) poolInstance.stop();

    // The only way this can be verified is manually.
    debug(std_parallelism) stderr.writeln("totalCPUs = ", totalCPUs);

    auto oldPriority = poolInstance.priority;
    poolInstance.priority = Thread.PRIORITY_MAX;
    assert(poolInstance.priority == Thread.PRIORITY_MAX);

    poolInstance.priority = Thread.PRIORITY_MIN;
    assert(poolInstance.priority == Thread.PRIORITY_MIN);

    poolInstance.priority = oldPriority;
    assert(poolInstance.priority == oldPriority);

    static void refFun(ref uint num)
    {
        num++;
    }

    uint x;

    // Test task().
    auto t = task!refFun(x);
    poolInstance.put(t);
    t.yieldForce;
    assert(t.args[0] == 1);

    auto t2 = task(&refFun, x);
    poolInstance.put(t2);
    t2.yieldForce;
    assert(t2.args[0] == 1);

    // Test scopedTask().
    auto st = scopedTask!refFun(x);
    poolInstance.put(st);
    st.yieldForce;
    assert(st.args[0] == 1);

    auto st2 = scopedTask(&refFun, x);
    poolInstance.put(st2);
    st2.yieldForce;
    assert(st2.args[0] == 1);

    // Test executeInNewThread().
    auto ct = scopedTask!refFun(x);
    ct.executeInNewThread(Thread.PRIORITY_MAX);
    ct.yieldForce;
    assert(ct.args[0] == 1);

    // Test ref return.
    uint toInc = 0;
    static ref T makeRef(T)(ref T num)
    {
        return num;
    }

    auto t3 = task!makeRef(toInc);
    taskPool.put(t3);
    assert(t3.args[0] == 0);
    t3.spinForce++;
    assert(t3.args[0] == 1);

    static void testSafe() @safe {
        static int bump(int num)
        {
            return num + 1;
        }

        auto safePool = new TaskPool(0);
        auto t = task(&bump, 1);
        taskPool.put(t);
        assert(t.yieldForce == 2);

        auto st = scopedTask(&bump, 1);
        taskPool.put(st);
        assert(st.yieldForce == 2);
        safePool.stop();
    }

    auto arr = [1,2,3,4,5];
    auto nums = new uint[5];
    auto nums2 = new uint[5];

    foreach (i, ref elem; poolInstance.parallel(arr))
    {
        elem++;
        nums[i] = cast(uint) i + 2;
        nums2[i] = elem;
    }

    assert(nums == [2,3,4,5,6], text(nums));
    assert(nums2 == nums, text(nums2));
    assert(arr == nums, text(arr));

    // Test const/immutable arguments.
    static int add(int lhs, int rhs)
    {
        return lhs + rhs;
    }
    immutable addLhs = 1;
    immutable addRhs = 2;
    auto addTask = task(&add, addLhs, addRhs);
    auto addScopedTask = scopedTask(&add, addLhs, addRhs);
    poolInstance.put(addTask);
    poolInstance.put(addScopedTask);
    assert(addTask.yieldForce == 3);
    assert(addScopedTask.yieldForce == 3);

    // Test parallel foreach with non-random access range.
    auto range = filter!"a != 666"([0, 1, 2, 3, 4]);

    foreach (i, elem; poolInstance.parallel(range))
    {
        nums[i] = cast(uint) i;
    }

    assert(nums == [0,1,2,3,4]);

    auto logs = new double[1_000_000];
    foreach (i, ref elem; poolInstance.parallel(logs))
    {
        elem = log(i + 1.0);
    }

    foreach (i, elem; logs)
    {
        assert(isClose(elem, log(double(i + 1))));
    }

    assert(poolInstance.amap!"a * a"([1,2,3,4,5]) == [1,4,9,16,25]);
    assert(poolInstance.amap!"a * a"([1,2,3,4,5], new long[5]) == [1,4,9,16,25]);
    assert(poolInstance.amap!("a * a", "-a")([1,2,3]) ==
           [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);

    auto tupleBuf = new Tuple!(int, int)[3];
    poolInstance.amap!("a * a", "-a")([1,2,3], tupleBuf);
    assert(tupleBuf == [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);
    poolInstance.amap!("a * a", "-a")([1,2,3], 5, tupleBuf);
    assert(tupleBuf == [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);

    // Test amap with a non-array buffer.
    auto toIndex = new int[5];
    auto ind = indexed(toIndex, [3, 1, 4, 0, 2]);
    poolInstance.amap!"a * 2"([1, 2, 3, 4, 5], ind);
    assert(equal(ind, [2, 4, 6, 8, 10]));
    assert(equal(toIndex, [8, 4, 10, 2, 6]));
    poolInstance.amap!"a / 2"(ind, ind);
    assert(equal(ind, [1, 2, 3, 4, 5]));
    assert(equal(toIndex, [4, 2, 5, 1, 3]));

    auto buf = new int[5];
    poolInstance.amap!"a * a"([1,2,3,4,5], buf);
    assert(buf == [1,4,9,16,25]);
    poolInstance.amap!"a * a"([1,2,3,4,5], 4, buf);
    assert(buf == [1,4,9,16,25]);

    assert(poolInstance.reduce!"a + b"([1]) == 1);
    assert(poolInstance.reduce!"a + b"([1,2,3,4]) == 10);
    assert(poolInstance.reduce!"a + b"(0.0, [1,2,3,4]) == 10);
    assert(poolInstance.reduce!"a + b"(0.0, [1,2,3,4], 1) == 10);
    assert(poolInstance.reduce!(min, max)([1,2,3,4]) == tuple(1, 4));
    assert(poolInstance.reduce!("a + b", "a * b")(tuple(0, 1), [1,2,3,4]) ==
           tuple(10, 24));

    immutable serialAns = reduce!"a + b"(iota(1000));
    assert(poolInstance.reduce!"a + b"(0, iota(1000)) == serialAns);
    assert(poolInstance.reduce!"a + b"(iota(1000)) == serialAns);

    // Test worker-local storage.
    auto wl = poolInstance.workerLocalStorage(0);
    foreach (i; poolInstance.parallel(iota(1000), 1))
    {
        wl.get = wl.get + i;
    }

    auto wlRange = wl.toRange;
    auto parallelSum = poolInstance.reduce!"a + b"(wlRange);
    assert(parallelSum == 499500);
    assert(wlRange[0 .. 1][0] == wlRange[0]);
    assert(wlRange[1 .. 2][0] == wlRange[1]);

    // Test finish()
    {
        static void slowFun() { Thread.sleep(dur!"msecs"(1)); }

        auto pool1 = new TaskPool();
        auto tSlow = task!slowFun();
        pool1.put(tSlow);
        pool1.finish();
        tSlow.yieldForce;
        // Can't assert that pool1.status == PoolState.stopNow because status
        // doesn't change until after the "done" flag is set and the waiting
        // thread is woken up.

        auto pool2 = new TaskPool();
        auto tSlow2 = task!slowFun();
        pool2.put(tSlow2);
        pool2.finish(true); // blocking
        assert(tSlow2.done);

        // Test fix for https://issues.dlang.org/show_bug.cgi?id=8582 by making pool size zero.
        auto pool3 = new TaskPool(0);
        auto tSlow3 = task!slowFun();
        pool3.put(tSlow3);
        pool3.finish(true); // blocking
        assert(tSlow3.done);

        // This is correct because no thread will terminate unless pool2.status
        // and pool3.status have already been set to stopNow.
        assert(pool2.status == TaskPool.PoolState.stopNow);
        assert(pool3.status == TaskPool.PoolState.stopNow);
    }

    // Test default pool stuff.
    assert(taskPool.size == totalCPUs - 1);

    nums = new uint[1000];
    foreach (i; parallel(iota(1000)))
    {
        nums[i] = cast(uint) i;
    }
    assert(equal(nums, iota(1000)));

    assert(equal(
               poolInstance.map!"a * a"(iota(3_000_001), 10_000),
               map!"a * a"(iota(3_000_001))
           ));

    // The filter is to kill random access and test the non-random access
    // branch.
    assert(equal(
               poolInstance.map!"a * a"(
                   filter!"a == a"(iota(3_000_001)
                                  ), 10_000, 1000),
               map!"a * a"(iota(3_000_001))
           ));

    assert(
        reduce!"a + b"(0UL,
                       poolInstance.map!"a * a"(iota(300_001), 10_000)
                      ) ==
        reduce!"a + b"(0UL,
                       map!"a * a"(iota(300_001))
                      )
    );

    assert(equal(
               iota(1_000_002),
               poolInstance.asyncBuf(filter!"a == a"(iota(1_000_002)))
           ));

    {
        import std.conv : to;
        import std.file : deleteme;

        string temp_file = deleteme ~ "-tempDelMe.txt";
        auto file = File(temp_file, "wb");
        scope(exit)
        {
            file.close();
            import std.file;
            remove(temp_file);
        }

        auto written = [[1.0, 2, 3], [4.0, 5, 6], [7.0, 8, 9]];
        foreach (row; written)
        {
            file.writeln(join(to!(string[])(row), "\t"));
        }

        file = File(temp_file);

        void next(ref char[] buf)
        {
            file.readln(buf);
            import std.string : chomp;
            buf = chomp(buf);
        }

        double[][] read;
        auto asyncReader = taskPool.asyncBuf(&next, &file.eof);

        foreach (line; asyncReader)
        {
            if (line.length == 0) continue;
            auto ls = line.split("\t");
            read ~= to!(double[])(ls);
        }

        assert(read == written);
        file.close();
    }

    // Test Map/AsyncBuf chaining.

    auto abuf = poolInstance.asyncBuf(iota(-1.0, 3_000_000), 100);
    auto temp = poolInstance.map!sqrt(
                    abuf, 100, 5
                );
    auto lmchain = poolInstance.map!"a * a"(temp, 100, 5);
    lmchain.popFront();

    int ii;
    foreach ( elem; (lmchain))
    {
        if (!isClose(elem, ii))
        {
            stderr.writeln(ii, '\t', elem);
        }
        ii++;
    }

    // Test buffer trick in parallel foreach.
    abuf = poolInstance.asyncBuf(iota(-1.0, 1_000_000), 100);
    abuf.popFront();
    auto bufTrickTest = new size_t[abuf.length];
    foreach (i, elem; parallel(abuf))
    {
        bufTrickTest[i] = i;
    }

    assert(equal(iota(1_000_000), bufTrickTest));

    auto myTask = task!(abs)(-1);
    taskPool.put(myTask);
    assert(myTask.spinForce == 1);

    // Test that worker local storage from one pool receives an index of 0
    // when the index is queried w.r.t. another pool.  The only way to do this
    // is non-deterministically.
    foreach (i; parallel(iota(1000), 1))
    {
        assert(poolInstance.workerIndex == 0);
    }

    foreach (i; poolInstance.parallel(iota(1000), 1))
    {
        assert(taskPool.workerIndex == 0);
    }

    // Test exception handling.
    static void parallelForeachThrow()
    {
        foreach (elem; parallel(iota(10)))
        {
            throw new Exception("");
        }
    }

    assertThrown!Exception(parallelForeachThrow());

    static int reduceException(int a, int b)
    {
        throw new Exception("");
    }

    assertThrown!Exception(
        poolInstance.reduce!reduceException(iota(3))
    );

    static int mapException(int a)
    {
        throw new Exception("");
    }

    assertThrown!Exception(
        poolInstance.amap!mapException(iota(3))
    );

    static void mapThrow()
    {
        auto m = poolInstance.map!mapException(iota(3));
        m.popFront();
    }

    assertThrown!Exception(mapThrow());

    struct ThrowingRange
    {
        @property int front()
        {
            return 1;
        }
        void popFront()
        {
            throw new Exception("");
        }
        enum bool empty = false;
    }

    assertThrown!Exception(poolInstance.asyncBuf(ThrowingRange.init));
}

//version = parallelismStressTest;

// These are more like stress tests than real unit tests.  They print out
// tons of stuff and should not be run every time make unittest is run.
version (parallelismStressTest)
{
    @system unittest
    {
        import std.stdio : stderr, writeln, readln;
        import std.range : iota;
        import std.algorithm.iteration : filter, reduce;

        size_t attempt;
        for (; attempt < 10; attempt++)
            foreach (poolSize; [0, 4])
        {

            poolInstance = new TaskPool(poolSize);

            uint[] numbers = new uint[1_000];

            foreach (i; poolInstance.parallel( iota(0, numbers.length)) )
            {
                numbers[i] = cast(uint) i;
            }

            // Make sure it works.
            foreach (i; 0 .. numbers.length)
            {
                assert(numbers[i] == i);
            }

            stderr.writeln("Done creating nums.");


            auto myNumbers = filter!"a % 7 > 0"( iota(0, 1000));
            foreach (num; poolInstance.parallel(myNumbers))
            {
                assert(num % 7 > 0 && num < 1000);
            }
            stderr.writeln("Done modulus test.");

            uint[] squares = poolInstance.amap!"a * a"(numbers, 100);
            assert(squares.length == numbers.length);
            foreach (i, number; numbers)
            {
                assert(squares[i] == number * number);
            }
            stderr.writeln("Done squares.");

            auto sumFuture = task!( reduce!"a + b" )(numbers);
            poolInstance.put(sumFuture);

            ulong sumSquares = 0;
            foreach (elem; numbers)
            {
                sumSquares += elem * elem;
            }

            uint mySum = sumFuture.spinForce();
            assert(mySum == 999 * 1000 / 2);

            auto mySumParallel = poolInstance.reduce!"a + b"(numbers);
            assert(mySum == mySumParallel);
            stderr.writeln("Done sums.");

            auto myTask = task(
            {
                synchronized writeln("Our lives are parallel...Our lives are parallel.");
            });
            poolInstance.put(myTask);

            auto nestedOuter = "abcd";
            auto nestedInner =  iota(0, 10, 2);

            foreach (i, letter; poolInstance.parallel(nestedOuter, 1))
            {
                foreach (j, number; poolInstance.parallel(nestedInner, 1))
                {
                    synchronized writeln(i, ": ", letter, "  ", j, ": ", number);
                }
            }

            poolInstance.stop();
        }

        assert(attempt == 10);
        writeln("Press enter to go to next round of unittests.");
        readln();
    }

    // These unittests are intended more for actual testing and not so much
    // as examples.
    @system unittest
    {
        import std.stdio : stderr;
        import std.range : iota;
        import std.algorithm.iteration : filter, reduce;
        import std.math.algebraic : sqrt;
        import std.math.operations : isClose;
        import std.math.traits : isNaN;
        import std.conv : text;

        foreach (attempt; 0 .. 10)
        foreach (poolSize; [0, 4])
        {
            poolInstance = new TaskPool(poolSize);

            // Test indexing.
            stderr.writeln("Creator Raw Index:  ", poolInstance.threadIndex);
            assert(poolInstance.workerIndex() == 0);

            // Test worker-local storage.
            auto workerLocalStorage = poolInstance.workerLocalStorage!uint(1);
            foreach (i; poolInstance.parallel(iota(0U, 1_000_000)))
            {
                workerLocalStorage.get++;
            }
            assert(reduce!"a + b"(workerLocalStorage.toRange) ==
            1_000_000 + poolInstance.size + 1);

            // Make sure work is reasonably balanced among threads.  This test is
            // non-deterministic and is more of a sanity check than something that
            // has an absolute pass/fail.
            shared(uint)[void*] nJobsByThread;
            foreach (thread; poolInstance.pool)
            {
                nJobsByThread[cast(void*) thread] = 0;
            }
            nJobsByThread[ cast(void*) Thread.getThis()] = 0;

            foreach (i; poolInstance.parallel( iota(0, 1_000_000), 100 ))
            {
                atomicOp!"+="( nJobsByThread[ cast(void*) Thread.getThis() ], 1);
            }

            stderr.writeln("\nCurrent thread is:  ",
            cast(void*) Thread.getThis());
            stderr.writeln("Workload distribution:  ");
            foreach (k, v; nJobsByThread)
            {
                stderr.writeln(k, '\t', v);
            }

            // Test whether amap can be nested.
            real[][] matrix = new real[][](1000, 1000);
            foreach (i; poolInstance.parallel( iota(0, matrix.length) ))
            {
                foreach (j; poolInstance.parallel( iota(0, matrix[0].length) ))
                {
                    matrix[i][j] = i * j;
                }
            }

            // Get around weird bugs having to do w/ sqrt being an intrinsic:
            static real mySqrt(real num)
            {
                return sqrt(num);
            }

            static real[] parallelSqrt(real[] nums)
            {
                return poolInstance.amap!mySqrt(nums);
            }

            real[][] sqrtMatrix = poolInstance.amap!parallelSqrt(matrix);

            foreach (i, row; sqrtMatrix)
            {
                foreach (j, elem; row)
                {
                    real shouldBe = sqrt( cast(real) i * j);
                    assert(isClose(shouldBe, elem));
                    sqrtMatrix[i][j] = shouldBe;
                }
            }

            auto saySuccess = task(
            {
                stderr.writeln(
                    "Success doing matrix stuff that involves nested pool use.");
            });
            poolInstance.put(saySuccess);
            saySuccess.workForce();

            // A more thorough test of amap, reduce:  Find the sum of the square roots of
            // matrix.

            static real parallelSum(real[] input)
            {
                return poolInstance.reduce!"a + b"(input);
            }

            auto sumSqrt = poolInstance.reduce!"a + b"(
                               poolInstance.amap!parallelSum(
                                   sqrtMatrix
                               )
                           );

            assert(isClose(sumSqrt, 4.437e8, 1e-2));
            stderr.writeln("Done sum of square roots.");

            // Test whether tasks work with function pointers.
            /+ // This part is buggy and needs to be fixed...
            auto nanTask = task(&isNaN, 1.0L);
            poolInstance.put(nanTask);
            assert(nanTask.spinForce == false);

            if (poolInstance.size > 0)
            {
                // Test work waiting.
                static void uselessFun()
                {
                    foreach (i; 0 .. 1_000_000) {}
                }

                auto uselessTasks = new typeof(task(&uselessFun))[1000];
                foreach (ref uselessTask; uselessTasks)
                {
                    uselessTask = task(&uselessFun);
                }
                foreach (ref uselessTask; uselessTasks)
                {
                    poolInstance.put(uselessTask);
                }
                foreach (ref uselessTask; uselessTasks)
                {
                    uselessTask.workForce();
                }
            }
             +/

            // Test the case of non-random access + ref returns.
            int[] nums = [1,2,3,4,5];
            static struct RemoveRandom
            {
                int[] arr;

                ref int front()
                {
                    return arr.front;
                }
                void popFront()
                {
                    arr.popFront();
                }
                bool empty()
                {
                    return arr.empty;
                }
            }

            auto refRange = RemoveRandom(nums);
            foreach (ref elem; poolInstance.parallel(refRange))
            {
                elem++;
            }
            assert(nums == [2,3,4,5,6], text(nums));
            stderr.writeln("Nums:  ", nums);

            poolInstance.stop();
        }
    }
}

@system unittest
{
    static struct __S_12733
    {
        invariant() { assert(checksum == 1_234_567_890); }
        this(ulong u){n = u;}
        void opAssign(__S_12733 s){this.n = s.n;}
        ulong n;
        ulong checksum = 1_234_567_890;
    }

    static auto __genPair_12733(ulong n) { return __S_12733(n); }
    immutable ulong[] data = [ 2UL^^59-1, 2UL^^59-1, 2UL^^59-1, 112_272_537_195_293UL ];

    auto result = taskPool.amap!__genPair_12733(data);
}

@safe unittest
{
    import std.range : iota;

    // this test was in std.range, but caused cycles.
    assert(__traits(compiles, { foreach (i; iota(0, 100UL).parallel) {} }));
}

@safe unittest
{
    import std.algorithm.iteration : each;

    long[] arr;
    static assert(is(typeof({
        arr.parallel.each!"a++";
    })));
}

// https://issues.dlang.org/show_bug.cgi?id=17539
@system unittest
{
    import std.random : rndGen;
    // ensure compilation
    try foreach (rnd; rndGen.parallel) break;
    catch (ParallelForeachError e) {}
}
