// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_SEMAPHORE
#define _LIBCPP_SEMAPHORE

/*
    semaphore synopsis

namespace std {

template<ptrdiff_t least_max_value = implementation-defined>
class counting_semaphore
{
public:
static constexpr ptrdiff_t max() noexcept;

constexpr explicit counting_semaphore(ptrdiff_t desired);
~counting_semaphore();

counting_semaphore(const counting_semaphore&) = delete;
counting_semaphore& operator=(const counting_semaphore&) = delete;

void release(ptrdiff_t update = 1);
void acquire();
bool try_acquire() noexcept;
template<class Rep, class Period>
    bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
template<class Clock, class Duration>
    bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);

private:
ptrdiff_t counter; // exposition only
};

using binary_semaphore = counting_semaphore<1>;

}

*/

#include <__availability>
#include <__config>
#include <__thread/timed_backoff_policy.h>
#include <__threading_support>
#include <atomic>
#include <version>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

#ifdef _LIBCPP_HAS_NO_THREADS
# error <semaphore> is not supported on this single threaded system
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#if _LIBCPP_STD_VER >= 14

_LIBCPP_BEGIN_NAMESPACE_STD

/*

__atomic_semaphore_base is the general-case implementation.
It is a typical Dijkstra semaphore algorithm over atomics, wait and notify
functions. It avoids contention against users' own use of those facilities.

*/

class __atomic_semaphore_base
{
    __atomic_base<ptrdiff_t> __a;

public:
    _LIBCPP_INLINE_VISIBILITY
    constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a(__count)
    {
    }
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    void release(ptrdiff_t __update = 1)
    {
        if(0 < __a.fetch_add(__update, memory_order_release))
            ;
        else if(__update > 1)
            __a.notify_all();
        else
            __a.notify_one();
    }
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    void acquire()
    {
        auto const __test_fn = [this]() -> bool {
            auto __old = __a.load(memory_order_relaxed);
            return (__old != 0) && __a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed);
        };
        __cxx_atomic_wait(&__a.__a_, __test_fn);
    }
    template <class Rep, class Period>
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
    {
        if (__rel_time == chrono::duration<Rep, Period>::zero())
            return try_acquire();
        auto const __test_fn = [this]() { return try_acquire(); };
        return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
    }
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    bool try_acquire()
    {
        auto __old = __a.load(memory_order_acquire);
        while (true) {
            if (__old == 0)
                return false;
            if (__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed))
                return true;
        }
    }
};

#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())

template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
class counting_semaphore
{
    __atomic_semaphore_base __semaphore;

public:
    static constexpr ptrdiff_t max() noexcept {
        return __least_max_value;
    }

    _LIBCPP_INLINE_VISIBILITY
    constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore(__count) { }
    ~counting_semaphore() = default;

    counting_semaphore(const counting_semaphore&) = delete;
    counting_semaphore& operator=(const counting_semaphore&) = delete;

    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    void release(ptrdiff_t __update = 1)
    {
        __semaphore.release(__update);
    }
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    void acquire()
    {
        __semaphore.acquire();
    }
    template<class Rep, class Period>
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
    {
        return __semaphore.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
    }
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    bool try_acquire()
    {
        return __semaphore.try_acquire();
    }
    template <class Clock, class Duration>
    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
    bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time)
    {
        auto const current = Clock::now();
        if (current >= __abs_time)
            return try_acquire();
        else
            return try_acquire_for(__abs_time - current);
    }
};

using binary_semaphore = counting_semaphore<1>;

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_STD_VER >= 14

_LIBCPP_POP_MACROS

#endif //_LIBCPP_SEMAPHORE
