/**
`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 (__traits(compiles, () @safe => fun(args)) && isSafeTask!F)
{
    return new Task!(run, F, Args)(fun, args);
}

@safe unittest
{
    static struct Oops {
        int convert() {
            *cast(int*) 0xcafebabe = 0xdeadbeef;
            return 0;
        }
        alias convert this;
    }
    static void foo(int) @safe {}

    static assert(!__traits(compiles, task(&foo, Oops.init)));
    static assert(!__traits(compiles, scopedTask(&foo, Oops.init)));
}

/**
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 (__traits(compiles, () @safe => 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) {}
}
