// -*- 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 <__threading_support>
#include <atomic>
#include <cassert>

#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

#if _LIBCPP_STD_VER < 14
# error <semaphore> is requires C++14 or later
#endif

_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 Dijsktra 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_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_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_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;

#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_INLINE_VISIBILITY
    void release(ptrdiff_t __update = 1)
    {
        __semaphore.release(__update);
    }
    _LIBCPP_INLINE_VISIBILITY
    void acquire()
    {
        __semaphore.acquire();
    }
    template<class Rep, class Period>
    _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_INLINE_VISIBILITY
    bool try_acquire()
    {
        return try_acquire_for(chrono::nanoseconds::zero());
    }
    template <class Clock, class Duration>
    _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_SEMAPHORE
