// -*- C++ -*-
//===--------------------------- semaphore --------------------------------===//
//
// 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 <__threading_support>
#include <atomic>

#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, to be used for
user-requested least-max values that exceed the OS implementation support
(incl. when the OS has no support of its own) and for binary semaphores.

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)
    {
        auto const __test_fn = [this]() -> bool {
            auto __old = __a.load(memory_order_acquire);
            while(1) {
                if (__old == 0)
                    return false;
                if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed))
                    return true;
            }
        };
        return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
    }
};

#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES

/*

__platform_semaphore_base a simple wrapper for the OS semaphore type. That
is, every call is routed to the OS in the most direct manner possible.

*/

class __platform_semaphore_base
{
    __libcpp_semaphore_t __semaphore;

public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __platform_semaphore_base(ptrdiff_t __count) :
        __semaphore()
    {
        __libcpp_semaphore_init(&__semaphore, __count);
    }
    _LIBCPP_INLINE_VISIBILITY
    ~__platform_semaphore_base() {
        __libcpp_semaphore_destroy(&__semaphore);
    }
    _LIBCPP_INLINE_VISIBILITY
    void release(ptrdiff_t __update)
    {
        for(; __update; --__update)
            __libcpp_semaphore_post(&__semaphore);
    }
    _LIBCPP_INLINE_VISIBILITY
    void acquire()
    {
        __libcpp_semaphore_wait(&__semaphore);
    }
    _LIBCPP_INLINE_VISIBILITY
    bool try_acquire_for(chrono::nanoseconds __rel_time)
    {
        return __libcpp_semaphore_wait_timed(&__semaphore, __rel_time);
    }
};

template<ptrdiff_t __least_max_value>
using __semaphore_base =
    typename conditional<(__least_max_value > 1 && __least_max_value <= _LIBCPP_SEMAPHORE_MAX),
                         __platform_semaphore_base,
                         __atomic_semaphore_base>::type;

#else

template<ptrdiff_t __least_max_value>
using __semaphore_base =
    __atomic_semaphore_base;

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

#endif //_LIBCPP_NO_NATIVE_SEMAPHORES

template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
class counting_semaphore
{
    __semaphore_base<__least_max_value> __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 try_acquire_for(chrono::nanoseconds::zero());
    }
    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
