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

#ifndef WTF_ParkingLot_h
#define WTF_ParkingLot_h

#include <chrono>
#include <functional>
#include <wtf/Atomics.h>
#include <wtf/ScopedLambda.h>
#include <wtf/Threading.h>

namespace WTF {

class ParkingLot {
    ParkingLot() = delete;
    ParkingLot(const ParkingLot&) = delete;

public:
    typedef std::chrono::steady_clock Clock;
    
    // Parks the thread in a queue associated with the given address, which cannot be null. The
    // parking only succeeds if the validation function returns true while the queue lock is held.
    //
    // If validation returns false, it will unlock the internal parking queue and then it will
    // return a null ParkResult (wasUnparked = false, token = 0) without doing anything else.
    //
    // If validation returns true, it will enqueue the thread, unlock the parking queue lock, call
    // the beforeSleep function, and then it will sleep so long as the thread continues to be on the
    // queue and the timeout hasn't fired. Finally, this returns wasUnparked = true if we actually
    // got unparked or wasUnparked = false if the timeout was hit. When wasUnparked = true, the
    // token will contain whatever token was returned from the callback to unparkOne(), or 0 if the
    // thread was unparked using unparkAll() or the form of unparkOne() that doesn't take a
    // callback.
    //
    // Note that beforeSleep is called with no locks held, so it's OK to do pretty much anything so
    // long as you don't recursively call parkConditionally(). You can call unparkOne()/unparkAll()
    // though. It's useful to use beforeSleep() to unlock some mutex in the implementation of
    // Condition::wait().
    struct ParkResult {
        bool wasUnparked { false };
        intptr_t token { 0 };
    };
    template<typename ValidationFunctor, typename BeforeSleepFunctor>
    static ParkResult parkConditionally(
        const void* address,
        const ValidationFunctor& validation,
        const BeforeSleepFunctor& beforeSleep,
        Clock::time_point timeout)
    {
        return parkConditionallyImpl(
            address,
            scopedLambdaRef<bool()>(validation),
            scopedLambdaRef<void()>(beforeSleep),
            timeout);
    }

    // Simple version of parkConditionally() that covers the most common case: you want to park
    // indefinitely so long as the value at the given address hasn't changed.
    template<typename T, typename U>
    static ParkResult compareAndPark(const Atomic<T>* address, U expected)
    {
        return parkConditionally(
            address,
            [address, expected] () -> bool {
                U value = address->load();
                return value == expected;
            },
            [] () { },
            Clock::time_point::max());
    }

    // Unparking status given to you anytime you unparkOne().
    struct UnparkResult {
        // True if some thread was unparked.
        bool didUnparkThread { false };
        // True if there may be more threads on this address. This may be conservatively true.
        bool mayHaveMoreThreads { false };
        // This bit is randomly set to true indicating that it may be profitable to unlock the lock
        // using a fair unlocking protocol. This is most useful when used in conjunction with
        // unparkOne(address, callback).
        bool timeToBeFair { false };
    };

    // Unparks one thread from the queue associated with the given address, which cannot be null.
    // Returns true if there may still be other threads on that queue, or false if there definitely
    // are no more threads on the queue.
    WTF_EXPORT_PRIVATE static UnparkResult unparkOne(const void* address);

    // This is an expert-mode version of unparkOne() that allows for really good thundering herd
    // avoidance and eventual stochastic fairness in adaptive mutexes.
    //
    // Unparks one thread from the queue associated with the given address, and calls the given
    // callback while the address is locked. Reports to the callback whether any thread got
    // unparked, whether there may be any other threads still on the queue, and whether this may be
    // a good time to do fair unlocking. The callback returns an intptr_t token, which is returned
    // to the unparked thread via ParkResult::token.
    //
    // WTF::Lock and WTF::Condition both use this form of unparkOne() because it allows them to use
    // the ParkingLot's internal queue lock to serialize some decision-making. For example, if
    // UnparkResult::mayHaveMoreThreads is false inside the callback, then we know that at that
    // moment nobody can add any threads to the queue because the queue lock is still held. Also,
    // WTF::Lock uses the timeToBeFair and token mechanism to implement eventual fairness.
    template<typename Callback>
    static void unparkOne(const void* address, const Callback& callback)
    {
        unparkOneImpl(address, scopedLambdaRef<intptr_t(UnparkResult)>(callback));
    }

    // Unparks every thread from the queue associated with the given address, which cannot be null.
    WTF_EXPORT_PRIVATE static void unparkAll(const void* address);

    // Locks the parking lot and walks all of the parked threads and the addresses they are waiting
    // on. Threads that are on the same queue are guaranteed to be walked from first to last, but the
    // queues may be randomly interleaved. For example, if the queue for address A1 has T1 and T2 and
    // the queue for address A2 has T3 and T4, then you might see iteration orders like:
    //
    // A1,T1 A1,T2 A2,T3 A2,T4
    // A2,T3 A2,T4 A1,T1 A1,T2
    // A1,T1 A2,T3 A1,T2 A2,T4
    // A1,T1 A2,T3 A2,T4 A1,T2
    //
    // As well as many other possible interleavings that all have T1 before T2 and T3 before T4 but are
    // otherwise unconstrained. This method is useful primarily for debugging. It's also used by unit
    // tests.
    template<typename Func>
    static void forEach(const Func& func)
    {
        forEachImpl(scopedLambdaRef<void(ThreadIdentifier, const void*)>(func));
    }

private:
    WTF_EXPORT_PRIVATE static ParkResult parkConditionallyImpl(
        const void* address,
        const ScopedLambda<bool()>& validation,
        const ScopedLambda<void()>& beforeSleep,
        Clock::time_point timeout);
    
    WTF_EXPORT_PRIVATE static void unparkOneImpl(
        const void* address, const ScopedLambda<intptr_t(UnparkResult)>& callback);

    WTF_EXPORT_PRIVATE static void forEachImpl(const ScopedLambda<void(ThreadIdentifier, const void*)>&);
};

} // namespace WTF

using WTF::ParkingLot;

#endif // WTF_ParkingLot_h

