//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <thread>

// class thread

// template <class F, class ...Args> thread(F&& f, Args&&... args);

// UNSUPPORTED: no-threads
// UNSUPPORTED: sanitizer-new-delete

#include <thread>
#include <new>
#include <atomic>
#include <cstdlib>
#include <cassert>
#include <vector>

#include "test_macros.h"

std::atomic<unsigned> throw_one(0xFFFF);
std::atomic<unsigned> outstanding_new(0);


void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
{
    unsigned expected = throw_one;
    do {
        if (expected == 0) TEST_THROW(std::bad_alloc());
    } while (!throw_one.compare_exchange_weak(expected, expected - 1));
    ++outstanding_new;
    void* ret = std::malloc(s);
    if (!ret) {
      std::abort(); // placate MSVC's unchecked malloc warning (assert() won't silence it)
    }
    return ret;
}

void  operator delete(void* p) TEST_NOEXCEPT
{
    if (!p) return;
    --outstanding_new;
    std::free(p);
}

bool f_run = false;

struct F {
    std::vector<int> v_;  // so f's copy-ctor calls operator new
    explicit F() : v_(10) {}
    void operator()() const { f_run = true; }
};
F f;

class G
{
    int alive_;
public:
    static int n_alive;
    static bool op_run;

    G() : alive_(1) {++n_alive;}
    G(const G& g) : alive_(g.alive_) {++n_alive;}
    ~G() {alive_ = 0; --n_alive;}

    void operator()()
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        op_run = true;
    }

    void operator()(int i, double j)
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        assert(i == 5);
        assert(j == 5.5);
        op_run = true;
    }
};

int G::n_alive = 0;
bool G::op_run = false;

#if TEST_STD_VER >= 11

class MoveOnly
{
    MoveOnly(const MoveOnly&);
public:
    MoveOnly() {}
    MoveOnly(MoveOnly&&) {}

    void operator()(MoveOnly&&)
    {
    }
};

#endif

// Test throwing std::bad_alloc
//-----------------------------
// Concerns:
//  A Each allocation performed during thread construction should be performed
//    in the parent thread so that std::terminate is not called if
//    std::bad_alloc is thrown by new.
//  B std::thread's constructor should properly handle exceptions and not leak
//    memory.
// Plan:
//  1 Create a thread and count the number of allocations, 'numAllocs', it
//    performs.
//  2 For each allocation performed run a test where that allocation throws.
//    2.1 check that the exception can be caught in the parent thread.
//    2.2 Check that the functor has not been called.
//    2.3 Check that no memory allocated by the creation of the thread is leaked.
//  3 Finally check that a thread runs successfully if we throw after
//    'numAllocs + 1' allocations.

int numAllocs;

void test_throwing_new_during_thread_creation() {
#ifndef TEST_HAS_NO_EXCEPTIONS
    throw_one = 0xFFF;
    {
        std::thread t(f);
        t.join();
    }
    numAllocs = 0xFFF - throw_one;
    // i <= numAllocs means the last iteration is expected not to throw.
    for (int i=0; i <= numAllocs; ++i) {
        throw_one = i;
        f_run = false;
        unsigned old_outstanding = outstanding_new;
        try {
            std::thread t(f);
            assert(i == numAllocs); // Only final iteration will not throw.
            t.join();
            assert(f_run);
        } catch (std::bad_alloc const&) {
            assert(i < numAllocs);
            assert(!f_run); // (2.2)
        }
        ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(old_outstanding == outstanding_new); // (2.3)
    }
    f_run = false;
    throw_one = 0xFFF;
#endif
}

int main(int, char**)
{
    test_throwing_new_during_thread_creation();
    {
        std::thread t(f);
        t.join();
        assert(f_run == true);
    }

    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        {
            G g;
            std::thread t(g);
            t.join();
        }
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    G::op_run = false;
#ifndef TEST_HAS_NO_EXCEPTIONS
    // The test below expects `std::thread` to call `new`, which may not be the
    // case for all implementations.
    LIBCPP_ASSERT(numAllocs > 0); // libc++ should call new.
    if (numAllocs > 0) {
        try
        {
            throw_one = 0;
            assert(G::n_alive == 0);
            assert(!G::op_run);
            std::thread t((G()));
            assert(false);
        }
        catch (std::bad_alloc const&)
        {
            throw_one = 0xFFFF;
            assert(G::n_alive == 0);
            assert(!G::op_run);
        }
    }
#endif
#if TEST_STD_VER >= 11
    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        {
            G g;
            std::thread t(g, 5, 5.5);
            t.join();
        }
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    {
        std::thread t = std::thread(MoveOnly(), MoveOnly());
        t.join();
    }
#endif

    return 0;
}
