/*
 * kmp_wait_release.h -- Wait/Release implementation
 */


//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//


#ifndef KMP_WAIT_RELEASE_H
#define KMP_WAIT_RELEASE_H

#include "kmp.h"
#include "kmp_itt.h"

/*!
@defgroup WAIT_RELEASE Wait/Release operations

The definitions and functions here implement the lowest level thread
synchronizations of suspending a thread and awaking it. They are used
to build higher level operations such as barriers and fork/join.
*/

/*!
@ingroup WAIT_RELEASE
@{
*/

/*! 
 * The flag_type describes the storage used for the flag.
 */
enum flag_type {
    flag32,        /**< 32 bit flags */
    flag64,        /**< 64 bit flags */
    flag_oncore    /**< special 64-bit flag for on-core barrier (hierarchical) */
};

/*!
 * Base class for wait/release volatile flag
 */
template <typename P>
class kmp_flag {
    volatile P * loc;  /**< Pointer to the flag storage that is modified by another thread */
    flag_type t;       /**< "Type" of the flag in loc */
 public:
    typedef P flag_t;
    kmp_flag(volatile P *p, flag_type ft) : loc(p), t(ft) {}
    /*!
     * @result the pointer to the actual flag
     */
    volatile P * get() { return loc; }
    /*!
     * @result the flag_type
     */
    flag_type get_type() { return t; }
    // Derived classes must provide the following:
    /*
    kmp_info_t * get_waiter(kmp_uint32 i);
    kmp_uint32 get_num_waiters();
    bool done_check();
    bool done_check_val(P old_loc);
    bool notdone_check();
    P internal_release();
    P set_sleeping();
    P unset_sleeping();
    bool is_sleeping();
    bool is_sleeping_val(P old_loc);
    */
};

/* Spin wait loop that first does pause, then yield, then sleep. A thread that calls __kmp_wait_*
   must make certain that another thread calls __kmp_release to wake it back up to prevent deadlocks!  */
template <class C>
static inline void __kmp_wait_template(kmp_info_t *this_thr, C *flag, int final_spin
                                       USE_ITT_BUILD_ARG(void * itt_sync_obj) )
{
    // NOTE: We may not belong to a team at this point.
    volatile typename C::flag_t *spin = flag->get();
    kmp_uint32 spins;
    kmp_uint32 hibernate;
    int th_gtid;
    int tasks_completed = FALSE;

    KMP_FSYNC_SPIN_INIT(spin, NULL);
    if (flag->done_check()) {
        KMP_FSYNC_SPIN_ACQUIRED(spin);
        return;
    }
    th_gtid = this_thr->th.th_info.ds.ds_gtid;
    KA_TRACE(20, ("__kmp_wait_sleep: T#%d waiting for flag(%p)\n", th_gtid, flag));

#if OMPT_SUPPORT && OMPT_BLAME
    if (ompt_status == ompt_status_track_callback) {
        if (this_thr->th.ompt_thread_info.state == ompt_state_idle){
            if (ompt_callbacks.ompt_callback(ompt_event_idle_begin)) {
                ompt_callbacks.ompt_callback(ompt_event_idle_begin)(th_gtid + 1);
            }
        } else if (ompt_callbacks.ompt_callback(ompt_event_wait_barrier_begin)) {
            KMP_DEBUG_ASSERT(this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier ||
                             this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier_implicit ||
                             this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier_explicit);

            ompt_lw_taskteam_t* team = this_thr->th.th_team->t.ompt_serialized_team_info;
            ompt_parallel_id_t pId;
            ompt_task_id_t tId;
            if (team){
                pId = team->ompt_team_info.parallel_id;
                tId = team->ompt_task_info.task_id;
            } else {
                pId = this_thr->th.th_team->t.ompt_team_info.parallel_id;
                tId = this_thr->th.th_current_task->ompt_task_info.task_id;
            }
            ompt_callbacks.ompt_callback(ompt_event_wait_barrier_begin)(pId, tId);
        }
    }
#endif

    // Setup for waiting
    KMP_INIT_YIELD(spins);

    if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) {
        // The worker threads cannot rely on the team struct existing at this point.
        // Use the bt values cached in the thread struct instead.
#ifdef KMP_ADJUST_BLOCKTIME
        if (__kmp_zero_bt && !this_thr->th.th_team_bt_set)
            // Force immediate suspend if not set by user and more threads than available procs
            hibernate = 0;
        else
            hibernate = this_thr->th.th_team_bt_intervals;
#else
        hibernate = this_thr->th.th_team_bt_intervals;
#endif /* KMP_ADJUST_BLOCKTIME */

        /* If the blocktime is nonzero, we want to make sure that we spin wait for the entirety
           of the specified #intervals, plus up to one interval more.  This increment make
           certain that this thread doesn't go to sleep too soon.  */
        if (hibernate != 0)
            hibernate++;

        // Add in the current time value.
        hibernate += TCR_4(__kmp_global.g.g_time.dt.t_value);
        KF_TRACE(20, ("__kmp_wait_sleep: T#%d now=%d, hibernate=%d, intervals=%d\n",
                      th_gtid, __kmp_global.g.g_time.dt.t_value, hibernate,
                      hibernate - __kmp_global.g.g_time.dt.t_value));
    }
    KMP_MB();

    // Main wait spin loop
    while (flag->notdone_check()) {
        int in_pool;

        /* If the task team is NULL, it means one of things:
           1) A newly-created thread is first being released by __kmp_fork_barrier(), and
              its task team has not been set up yet.
           2) All tasks have been executed to completion, this thread has decremented the task
              team's ref ct and possibly deallocated it, and should no longer reference it.
           3) Tasking is off for this region.  This could be because we are in a serialized region
              (perhaps the outer one), or else tasking was manually disabled (KMP_TASKING=0).  */
        kmp_task_team_t * task_team = NULL;
        if (__kmp_tasking_mode != tskm_immediate_exec) {
            task_team = this_thr->th.th_task_team;
            if (task_team != NULL) {
                if (!TCR_SYNC_4(task_team->tt.tt_active)) {
                    KMP_DEBUG_ASSERT(!KMP_MASTER_TID(this_thr->th.th_info.ds.ds_tid));
                    __kmp_unref_task_team(task_team, this_thr);
                } else if (KMP_TASKING_ENABLED(task_team)) {
                    flag->execute_tasks(this_thr, th_gtid, final_spin, &tasks_completed
                                        USE_ITT_BUILD_ARG(itt_sync_obj), 0);
                }
            } // if
        } // if

        KMP_FSYNC_SPIN_PREPARE(spin);
        if (TCR_4(__kmp_global.g.g_done)) {
            if (__kmp_global.g.g_abort)
                __kmp_abort_thread();
            break;
        }

        // If we are oversubscribed, or have waited a bit (and KMP_LIBRARY=throughput), then yield
        KMP_YIELD(TCR_4(__kmp_nth) > __kmp_avail_proc);
        // TODO: Should it be number of cores instead of thread contexts? Like:
        // KMP_YIELD(TCR_4(__kmp_nth) > __kmp_ncores);
        // Need performance improvement data to make the change...
        KMP_YIELD_SPIN(spins);

        // Check if this thread was transferred from a team
        // to the thread pool (or vice-versa) while spinning.
        in_pool = !!TCR_4(this_thr->th.th_in_pool);
        if (in_pool != !!this_thr->th.th_active_in_pool) {
            if (in_pool) { // Recently transferred from team to pool
                KMP_TEST_THEN_INC32((kmp_int32 *)&__kmp_thread_pool_active_nth);
                this_thr->th.th_active_in_pool = TRUE;
                /* Here, we cannot assert that:
                   KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) <= __kmp_thread_pool_nth);
                   __kmp_thread_pool_nth is inc/dec'd by the master thread while the fork/join
                   lock is held, whereas __kmp_thread_pool_active_nth is inc/dec'd asynchronously
                   by the workers.  The two can get out of sync for brief periods of time.  */
            }
            else { // Recently transferred from pool to team
                KMP_TEST_THEN_DEC32((kmp_int32 *) &__kmp_thread_pool_active_nth);
                KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) >= 0);
                this_thr->th.th_active_in_pool = FALSE;
            }
        }

        // Don't suspend if KMP_BLOCKTIME is set to "infinite"
        if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME)
            continue;

        // Don't suspend if there is a likelihood of new tasks being spawned.
        if ((task_team != NULL) && TCR_4(task_team->tt.tt_found_tasks))
            continue;

        // If we have waited a bit more, fall asleep
        if (TCR_4(__kmp_global.g.g_time.dt.t_value) < hibernate)
            continue;

        KF_TRACE(50, ("__kmp_wait_sleep: T#%d suspend time reached\n", th_gtid));

        flag->suspend(th_gtid);

        if (TCR_4(__kmp_global.g.g_done)) {
            if (__kmp_global.g.g_abort)
                __kmp_abort_thread();
            break;
        }
        // TODO: If thread is done with work and times out, disband/free
    }

#if OMPT_SUPPORT && OMPT_BLAME
    if (ompt_status == ompt_status_track_callback) {
        if (this_thr->th.ompt_thread_info.state == ompt_state_idle){
            if (ompt_callbacks.ompt_callback(ompt_event_idle_end)) {
                ompt_callbacks.ompt_callback(ompt_event_idle_end)(th_gtid + 1);
            }
        } else if (ompt_callbacks.ompt_callback(ompt_event_wait_barrier_end)) {
            KMP_DEBUG_ASSERT(this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier ||
                             this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier_implicit ||
                             this_thr->th.ompt_thread_info.state == ompt_state_wait_barrier_explicit);

            ompt_lw_taskteam_t* team = this_thr->th.th_team->t.ompt_serialized_team_info;
            ompt_parallel_id_t pId;
            ompt_task_id_t tId;
            if (team){
                pId = team->ompt_team_info.parallel_id;
                tId = team->ompt_task_info.task_id;
            } else {
                pId = this_thr->th.th_team->t.ompt_team_info.parallel_id;
                tId = this_thr->th.th_current_task->ompt_task_info.task_id;
            }
            ompt_callbacks.ompt_callback(ompt_event_wait_barrier_end)(pId, tId);
        }
    }
#endif

    KMP_FSYNC_SPIN_ACQUIRED(spin);
}

/* Release any threads specified as waiting on the flag by releasing the flag and resume the waiting thread
   if indicated by the sleep bit(s). A thread that calls __kmp_wait_template must call this function to wake
   up the potentially sleeping thread and prevent deadlocks!  */
template <class C>
static inline void __kmp_release_template(C *flag)
{
#ifdef KMP_DEBUG
    // FIX ME
    kmp_info_t * wait_thr = flag->get_waiter(0);
    int target_gtid = wait_thr->th.th_info.ds.ds_gtid;
    int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
#endif
    KF_TRACE(20, ("__kmp_release: T#%d releasing T#%d spin(%p)\n", gtid, target_gtid, flag->get()));
    KMP_DEBUG_ASSERT(flag->get());
    KMP_FSYNC_RELEASING(flag->get());

    typename C::flag_t old_spin = flag->internal_release();

    KF_TRACE(100, ("__kmp_release: T#%d old spin(%p)=%d, set new spin=%d\n",
                   gtid, flag->get(), old_spin, *(flag->get())));

    if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) {
        // Only need to check sleep stuff if infinite block time not set
        if (flag->is_sleeping_val(old_spin)) {
            for (unsigned int i=0; i<flag->get_num_waiters(); ++i) {
                kmp_info_t * waiter = flag->get_waiter(i);
                int wait_gtid = waiter->th.th_info.ds.ds_gtid;
                // Wake up thread if needed
                KF_TRACE(50, ("__kmp_release: T#%d waking up thread T#%d since sleep spin(%p) set\n",
                              gtid, wait_gtid, flag->get()));
                flag->resume(wait_gtid);
            }
        } else {
            KF_TRACE(50, ("__kmp_release: T#%d don't wake up thread T#%d since sleep spin(%p) not set\n",
                          gtid, target_gtid, flag->get()));
        }
    }
}

template <typename FlagType>
struct flag_traits {};

template <>
struct flag_traits<kmp_uint32> {
    typedef kmp_uint32 flag_t;
    static const flag_type t = flag32;
    static inline flag_t tcr(flag_t f) { return TCR_4(f); }
    static inline flag_t test_then_add4(volatile flag_t *f) { return KMP_TEST_THEN_ADD4_32((volatile kmp_int32 *)f); }
    static inline flag_t test_then_or(volatile flag_t *f, flag_t v) { return KMP_TEST_THEN_OR32((volatile kmp_int32 *)f, v); }
    static inline flag_t test_then_and(volatile flag_t *f, flag_t v) { return KMP_TEST_THEN_AND32((volatile kmp_int32 *)f, v); }
};

template <>
struct flag_traits<kmp_uint64> {
    typedef kmp_uint64 flag_t;
    static const flag_type t = flag64;
    static inline flag_t tcr(flag_t f) { return TCR_8(f); }
    static inline flag_t test_then_add4(volatile flag_t *f) { return KMP_TEST_THEN_ADD4_64((volatile kmp_int64 *)f); }
    static inline flag_t test_then_or(volatile flag_t *f, flag_t v) { return KMP_TEST_THEN_OR64((volatile kmp_int64 *)f, v); }
    static inline flag_t test_then_and(volatile flag_t *f, flag_t v) { return KMP_TEST_THEN_AND64((volatile kmp_int64 *)f, v); }
};

template <typename FlagType>
class kmp_basic_flag : public kmp_flag<FlagType> {
    typedef flag_traits<FlagType> traits_type;
    FlagType checker;  /**< Value to compare flag to to check if flag has been released. */
    kmp_info_t * waiting_threads[1];  /**< Array of threads sleeping on this thread. */
    kmp_uint32 num_waiting_threads;       /**< Number of threads sleeping on this thread. */
public:
    kmp_basic_flag(volatile FlagType *p) : kmp_flag<FlagType>(p, traits_type::t), num_waiting_threads(0) {}
    kmp_basic_flag(volatile FlagType *p, kmp_info_t *thr) : kmp_flag<FlagType>(p, traits_type::t), num_waiting_threads(1) {
        waiting_threads[0] = thr; 
    }
    kmp_basic_flag(volatile FlagType *p, FlagType c) : kmp_flag<FlagType>(p, traits_type::t), checker(c), num_waiting_threads(0) {}
    /*!
     * param i in   index into waiting_threads
     * @result the thread that is waiting at index i
     */
    kmp_info_t * get_waiter(kmp_uint32 i) { 
        KMP_DEBUG_ASSERT(i<num_waiting_threads);
        return waiting_threads[i]; 
    }
    /*!
     * @result num_waiting_threads
     */
    kmp_uint32 get_num_waiters() { return num_waiting_threads; }
    /*!
     * @param thr in   the thread which is now waiting
     *
     * Insert a waiting thread at index 0.
     */
    void set_waiter(kmp_info_t *thr) { 
        waiting_threads[0] = thr; 
        num_waiting_threads = 1;
    }
    /*!
     * @result true if the flag object has been released.
     */
    bool done_check() { return traits_type::tcr(*(this->get())) == checker; }
    /*!
     * @param old_loc in   old value of flag
     * @result true if the flag's old value indicates it was released.
     */
    bool done_check_val(FlagType old_loc) { return old_loc == checker; }
    /*!
     * @result true if the flag object is not yet released.
     * Used in __kmp_wait_template like:
     * @code
     * while (flag.notdone_check()) { pause(); }
     * @endcode
     */
    bool notdone_check() { return traits_type::tcr(*(this->get())) != checker; }
    /*!
     * @result Actual flag value before release was applied.
     * Trigger all waiting threads to run by modifying flag to release state.
     */
    FlagType internal_release() {
        return traits_type::test_then_add4((volatile FlagType *)this->get());
    }
    /*!
     * @result Actual flag value before sleep bit(s) set.
     * Notes that there is at least one thread sleeping on the flag by setting sleep bit(s).
     */
    FlagType set_sleeping() { 
        return traits_type::test_then_or((volatile FlagType *)this->get(), KMP_BARRIER_SLEEP_STATE);
    }
    /*!
     * @result Actual flag value before sleep bit(s) cleared.
     * Notes that there are no longer threads sleeping on the flag by clearing sleep bit(s).
     */
    FlagType unset_sleeping() { 
        return traits_type::test_then_and((volatile FlagType *)this->get(), ~KMP_BARRIER_SLEEP_STATE);
    }
    /*! 
     * @param old_loc in   old value of flag
     * Test whether there are threads sleeping on the flag's old value in old_loc.
     */
    bool is_sleeping_val(FlagType old_loc) { return old_loc & KMP_BARRIER_SLEEP_STATE; }
    /*! 
     * Test whether there are threads sleeping on the flag.
     */
    bool is_sleeping() { return is_sleeping_val(*(this->get())); }
};

class kmp_flag_32 : public kmp_basic_flag<kmp_uint32> {
public:
    kmp_flag_32(volatile kmp_uint32 *p) : kmp_basic_flag<kmp_uint32>(p) {}
    kmp_flag_32(volatile kmp_uint32 *p, kmp_info_t *thr) : kmp_basic_flag<kmp_uint32>(p, thr) {}
    kmp_flag_32(volatile kmp_uint32 *p, kmp_uint32 c) : kmp_basic_flag<kmp_uint32>(p, c) {}
    void suspend(int th_gtid) { __kmp_suspend_32(th_gtid, this); }
    void resume(int th_gtid) { __kmp_resume_32(th_gtid, this); }
    int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished
                      USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) {
        return __kmp_execute_tasks_32(this_thr, gtid, this, final_spin, thread_finished
                                      USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
    }
    void wait(kmp_info_t *this_thr, int final_spin
              USE_ITT_BUILD_ARG(void * itt_sync_obj)) {
        __kmp_wait_template(this_thr, this, final_spin
                            USE_ITT_BUILD_ARG(itt_sync_obj));
    }
    void release() { __kmp_release_template(this); }
};

class kmp_flag_64 : public kmp_basic_flag<kmp_uint64> {
public:
    kmp_flag_64(volatile kmp_uint64 *p) : kmp_basic_flag<kmp_uint64>(p) {}
    kmp_flag_64(volatile kmp_uint64 *p, kmp_info_t *thr) : kmp_basic_flag<kmp_uint64>(p, thr) {}
    kmp_flag_64(volatile kmp_uint64 *p, kmp_uint64 c) : kmp_basic_flag<kmp_uint64>(p, c) {}
    void suspend(int th_gtid) { __kmp_suspend_64(th_gtid, this); }
    void resume(int th_gtid) { __kmp_resume_64(th_gtid, this); }
    int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished
                      USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) {
        return __kmp_execute_tasks_64(this_thr, gtid, this, final_spin, thread_finished
                                      USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
    }
    void wait(kmp_info_t *this_thr, int final_spin
              USE_ITT_BUILD_ARG(void * itt_sync_obj)) {
        __kmp_wait_template(this_thr, this, final_spin
                            USE_ITT_BUILD_ARG(itt_sync_obj));
    }
    void release() { __kmp_release_template(this); }
};

// Hierarchical 64-bit on-core barrier instantiation
class kmp_flag_oncore : public kmp_flag<kmp_uint64> {
    kmp_uint64 checker;
    kmp_info_t * waiting_threads[1];
    kmp_uint32 num_waiting_threads;
    kmp_uint32 offset;      /**< Portion of flag that is of interest for an operation. */
    bool flag_switch;       /**< Indicates a switch in flag location. */
    enum barrier_type bt;   /**< Barrier type. */
    kmp_info_t * this_thr;  /**< Thread that may be redirected to different flag location. */
#if USE_ITT_BUILD
    void *itt_sync_obj;     /**< ITT object that must be passed to new flag location. */
#endif
    unsigned char& byteref(volatile kmp_uint64* loc, size_t offset) { return ((unsigned char *)loc)[offset]; }
public:
    kmp_flag_oncore(volatile kmp_uint64 *p)
        : kmp_flag<kmp_uint64>(p, flag_oncore), num_waiting_threads(0), flag_switch(false) {}
    kmp_flag_oncore(volatile kmp_uint64 *p, kmp_uint32 idx)
        : kmp_flag<kmp_uint64>(p, flag_oncore), num_waiting_threads(0), offset(idx), flag_switch(false) {}
    kmp_flag_oncore(volatile kmp_uint64 *p, kmp_uint64 c, kmp_uint32 idx, enum barrier_type bar_t,
                    kmp_info_t * thr
#if USE_ITT_BUILD
                    , void *itt
#endif
                    ) 
        : kmp_flag<kmp_uint64>(p, flag_oncore), checker(c), num_waiting_threads(0), offset(idx),
          flag_switch(false), bt(bar_t), this_thr(thr)
#if USE_ITT_BUILD
        , itt_sync_obj(itt)
#endif
        {}
    kmp_info_t * get_waiter(kmp_uint32 i) { 
        KMP_DEBUG_ASSERT(i<num_waiting_threads);
        return waiting_threads[i]; 
    }
    kmp_uint32 get_num_waiters() { return num_waiting_threads; }
    void set_waiter(kmp_info_t *thr) { 
        waiting_threads[0] = thr; 
        num_waiting_threads = 1;
    }
    bool done_check_val(kmp_uint64 old_loc) { return byteref(&old_loc,offset) == checker; }
    bool done_check() { return done_check_val(*get()); }
    bool notdone_check() { 
        // Calculate flag_switch
        if (this_thr->th.th_bar[bt].bb.wait_flag == KMP_BARRIER_SWITCH_TO_OWN_FLAG)
            flag_switch = true;
        if (byteref(get(),offset) != 1 && !flag_switch) 
            return true;
        else if (flag_switch) {
            this_thr->th.th_bar[bt].bb.wait_flag = KMP_BARRIER_SWITCHING;
            kmp_flag_64 flag(&this_thr->th.th_bar[bt].bb.b_go, (kmp_uint64)KMP_BARRIER_STATE_BUMP);
            __kmp_wait_64(this_thr, &flag, TRUE
#if USE_ITT_BUILD
                          , itt_sync_obj
#endif
                          );
        }
        return false;
    }
    kmp_uint64 internal_release() { 
        kmp_uint64 old_val;
        if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
            old_val = *get();
            byteref(get(),offset) = 1;
        }
        else {
            kmp_uint64 mask=0;
            byteref(&mask,offset) = 1;
            old_val = KMP_TEST_THEN_OR64((volatile kmp_int64 *)get(), mask);
        }
        return old_val;
    }
    kmp_uint64 set_sleeping() { 
        return KMP_TEST_THEN_OR64((kmp_int64 volatile *)get(), KMP_BARRIER_SLEEP_STATE);
    }
    kmp_uint64 unset_sleeping() { 
        return KMP_TEST_THEN_AND64((kmp_int64 volatile *)get(), ~KMP_BARRIER_SLEEP_STATE);
    }
    bool is_sleeping_val(kmp_uint64 old_loc) { return old_loc & KMP_BARRIER_SLEEP_STATE; }
    bool is_sleeping() { return is_sleeping_val(*get()); }
    void wait(kmp_info_t *this_thr, int final_spin
              USE_ITT_BUILD_ARG(void * itt_sync_obj)) {
        __kmp_wait_template(this_thr, this, final_spin
                            USE_ITT_BUILD_ARG(itt_sync_obj));
    }
    void release() { __kmp_release_template(this); }
    void suspend(int th_gtid) { __kmp_suspend_oncore(th_gtid, this); }
    void resume(int th_gtid) { __kmp_resume_oncore(th_gtid, this); }
    int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished
                      USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) {
        return __kmp_execute_tasks_oncore(this_thr, gtid, this, final_spin, thread_finished
                                      USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
    }
};

/*!
@}
*/

#endif // KMP_WAIT_RELEASE_H
