/*
 * 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_Lock_h
#define WTF_Lock_h

#include <wtf/Atomics.h>
#include <wtf/Compiler.h>
#include <wtf/Locker.h>
#include <wtf/Noncopyable.h>

namespace TestWebKitAPI {
struct LockInspector;
};

namespace WTF {

// This is a fully adaptive mutex that only requires 1 byte of storage. It has fast paths that are
// competetive to a spinlock (uncontended locking is inlined and is just a CAS, microcontention is
// handled by spinning and yielding), and a slow path that is competetive to std::mutex (if a lock
// cannot be acquired in a short period of time, the thread is put to sleep until the lock is
// available again). It uses less memory than a std::mutex. This lock guarantees eventual stochastic
// fairness, even in programs that relock the lock immediately after unlocking it. Except when there
// are collisions between this lock and other locks in the ParkingLot, this lock will guarantee that
// at worst one call to unlock() per millisecond will do a direct hand-off to the thread that is at
// the head of the queue. When there are collisions, each collision increases the fair unlock delay
// by one millisecond in the worst case.

// This is a struct without a constructor or destructor so that it can be statically initialized.
// Use Lock in instance variables.
struct LockBase {
    void lock()
    {
        if (LIKELY(m_byte.compareExchangeWeak(0, isHeldBit, std::memory_order_acquire))) {
            // Lock acquired!
            return;
        }

        lockSlow();
    }

    bool tryLock()
    {
        for (;;) {
            uint8_t currentByteValue = m_byte.load();
            if (currentByteValue & isHeldBit)
                return false;
            if (m_byte.compareExchangeWeak(currentByteValue, currentByteValue | isHeldBit))
                return true;
        }
    }

    // Need this version for std::unique_lock.
    bool try_lock()
    {
        return tryLock();
    }

    // Relinquish the lock. Either one of the threads that were waiting for the lock, or some other
    // thread that happens to be running, will be able to grab the lock. This bit of unfairness is
    // called barging, and we allow it because it maximizes throughput. However, we bound how unfair
    // barging can get by ensuring that every once in a while, when there is a thread waiting on the
    // lock, we hand the lock to that thread directly. Every time unlock() finds a thread waiting,
    // we check if the last time that we did a fair unlock was more than roughly 1ms ago; if so, we
    // unlock fairly. Fairness matters most for long critical sections, and this virtually
    // guarantees that long critical sections always get a fair lock.
    void unlock()
    {
        if (LIKELY(m_byte.compareExchangeWeak(isHeldBit, 0, std::memory_order_release))) {
            // Lock released and nobody was waiting!
            return;
        }

        unlockSlow();
    }

    // This is like unlock() but it guarantees that we unlock the lock fairly. For short critical
    // sections, this is much slower than unlock(). For long critical sections, unlock() will learn
    // to be fair anyway. However, if you plan to relock the lock right after unlocking and you want
    // to ensure that some other thread runs in the meantime, this is probably the function you
    // want.
    void unlockFairly()
    {
        if (LIKELY(m_byte.compareExchangeWeak(isHeldBit, 0, std::memory_order_release))) {
            // Lock released and nobody was waiting!
            return;
        }

        unlockFairlySlow();
    }

    bool isHeld() const
    {
        return m_byte.load(std::memory_order_acquire) & isHeldBit;
    }

    bool isLocked() const
    {
        return isHeld();
    }

protected:
    friend struct TestWebKitAPI::LockInspector;
    
    static const uint8_t isHeldBit = 1;
    static const uint8_t hasParkedBit = 2;

    WTF_EXPORT_PRIVATE void lockSlow();
    WTF_EXPORT_PRIVATE void unlockSlow();
    WTF_EXPORT_PRIVATE void unlockFairlySlow();
    
    enum Fairness {
        Fair,
        Unfair
    };
    void unlockSlowImpl(Fairness);
    
    enum Token {
        BargingOpportunity,
        DirectHandoff
    };

    // Method used for testing only.
    bool isFullyReset() const
    {
        return !m_byte.load();
    }

    Atomic<uint8_t> m_byte;
};

class Lock : public LockBase {
    WTF_MAKE_NONCOPYABLE(Lock);
    WTF_MAKE_FAST_ALLOCATED;
public:
    Lock()
    {
        m_byte.store(0, std::memory_order_relaxed);
    }
};

typedef LockBase StaticLock;
typedef Locker<LockBase> LockHolder;

} // namespace WTF

using WTF::Lock;
using WTF::LockHolder;
using WTF::StaticLock;

#endif // WTF_Lock_h

