/*
 * Copyright (C) 2016-2017 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. 
 */

// On Mac, you can build this like so:
// xcrun clang++ -o LockFairnessTest Source/WTF/benchmarks/LockFairnessTest.cpp -O3 -W -ISource/WTF -ISource/WTF/icu -ISource/WTF/benchmarks -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++14 -fvisibility=hidden

#include "config.h"

#include "ToyLocks.h"
#include <thread>
#include <unistd.h>
#include <wtf/CommaPrinter.h>
#include <wtf/Compiler.h>
#include <wtf/DataLog.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>
#include <wtf/ParkingLot.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Threading.h>
#include <wtf/ThreadingPrimitives.h>
#include <wtf/Vector.h>
#include <wtf/WordLock.h>
#include <wtf/text/CString.h>

namespace {

NO_RETURN void usage()
{
    printf("Usage: LockFairnessTest yieldspinlock|pausespinlock|wordlock|lock|barginglock|bargingwordlock|thunderlock|thunderwordlock|cascadelock|cascadewordlockhandofflock|unfairlock|mutex|all <num threads> <seconds per test> <microseconds in critical section>\n");
    exit(1);
}

unsigned numThreads;
double secondsPerTest;
unsigned microsecondsInCriticalSection;

struct Benchmark {
    template<typename LockType>
    static void run(const char* name)
    {
        LockType lock;
        std::unique_ptr<unsigned[]> counts = makeUniqueWithoutFastMallocCheck<unsigned[]>(numThreads);
        std::unique_ptr<RefPtr<Thread>[]> threads = makeUniqueWithoutFastMallocCheck<RefPtr<Thread>[]>(numThreads);
    
        volatile bool keepGoing = true;
    
        lock.lock();
    
        for (unsigned threadIndex = numThreads; threadIndex--;) {
            counts[threadIndex] = 0;
            threads[threadIndex] = Thread::create(
                "Benchmark Thread",
                [&, threadIndex] () {
                    if (!microsecondsInCriticalSection) {
                        while (keepGoing) {
                            lock.lock();
                            counts[threadIndex]++;
                            lock.unlock();
                        }
                        return;
                    }
                    
                    while (keepGoing) {
                        lock.lock();
                        counts[threadIndex]++;
                        usleep(microsecondsInCriticalSection);
                        lock.unlock();
                    }
                });
        }
    
        sleep(100_ms);
        lock.unlock();
    
        sleep(Seconds { secondsPerTest });
    
        keepGoing = false;
        lock.lock();
    
        dataLog(name, ": ");
        CommaPrinter comma;
        for (unsigned threadIndex = numThreads; threadIndex--;)
            dataLog(comma, counts[threadIndex]);
        dataLog("\n");
    
        lock.unlock();
        for (unsigned threadIndex = numThreads; threadIndex--;)
            threads[threadIndex]->waitForCompletion();
    }
};

} // anonymous namespace

int main(int argc, char** argv)
{
    WTF::initializeThreading();
    
    if (argc != 5
        || sscanf(argv[2], "%u", &numThreads) != 1
        || sscanf(argv[3], "%lf", &secondsPerTest) != 1
        || sscanf(argv[4], "%u", &microsecondsInCriticalSection) != 1)
        usage();
    
    runEverything<Benchmark>(argv[1]);
    
    return 0;
}
