// -*- 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 <__config>
#include <__availability>
#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
    __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 = [=]() -> 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 = [=]() -> 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
    __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
    counting_semaphore(ptrdiff_t __count = 0) : __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
