Blame src/mpid/ch4/src/ch4_progress.h

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2006 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  Portions of this code were written by Intel Corporation.
Packit Service c5cf8c
 *  Copyright (C) 2011-2016 Intel Corporation.  Intel provides this material
Packit Service c5cf8c
 *  to Argonne National Laboratory subject to Software Grant and Corporate
Packit Service c5cf8c
 *  Contributor License Agreement dated February 8, 2012.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#ifndef CH4_PROGRESS_H_INCLUDED
Packit Service c5cf8c
#define CH4_PROGRESS_H_INCLUDED
Packit Service c5cf8c
Packit Service c5cf8c
#include "ch4_impl.h"
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPIDI_Progress_test
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPIDI_Progress_test(int flags)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno, made_progress, i;
Packit Service c5cf8c
    mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_PROGRESS_TEST);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_PROGRESS_TEST);
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef HAVE_SIGNAL
Packit Service c5cf8c
    if (MPIDI_CH4_Global.sigusr1_count > MPIDI_CH4_Global.my_sigusr1_count) {
Packit Service c5cf8c
        MPIDI_CH4_Global.my_sigusr1_count = MPIDI_CH4_Global.sigusr1_count;
Packit Service c5cf8c
        mpi_errno = MPIDI_check_for_failed_procs();
Packit Service c5cf8c
        if (mpi_errno)
Packit Service c5cf8c
            MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
    if (OPA_load_int(&MPIDI_CH4_Global.active_progress_hooks) && (flags & MPIDI_PROGRESS_HOOKS)) {
Packit Service c5cf8c
        for (i = 0; i < MAX_PROGRESS_HOOKS; i++) {
Packit Service c5cf8c
            progress_func_ptr_t func_ptr = NULL;
Packit Service c5cf8c
            MPID_THREAD_CS_ENTER(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
            MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
            if (MPIDI_CH4_Global.progress_hooks[i].active == TRUE) {
Packit Service c5cf8c
                func_ptr = MPIDI_CH4_Global.progress_hooks[i].func_ptr;
Packit Service c5cf8c
                MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
                MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
                MPIR_Assert(func_ptr != NULL);
Packit Service c5cf8c
                mpi_errno = func_ptr(&made_progress);
Packit Service c5cf8c
                if (mpi_errno)
Packit Service c5cf8c
                    MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
            } else {
Packit Service c5cf8c
                MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
                MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
            }
Packit Service c5cf8c
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    /* todo: progress unexp_list */
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPIDI_workq_vni_progress();
Packit Service c5cf8c
    if (mpi_errno != MPI_SUCCESS)
Packit Service c5cf8c
        MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4_Global.vni_lock);
Packit Service c5cf8c
Packit Service c5cf8c
    if (flags & MPIDI_PROGRESS_NM) {
Packit Service c5cf8c
        mpi_errno = MPIDI_NM_progress(0, 0);
Packit Service c5cf8c
        if (mpi_errno != MPI_SUCCESS) {
Packit Service c5cf8c
            MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
#ifndef MPIDI_CH4_DIRECT_NETMOD
Packit Service c5cf8c
    if (flags & MPIDI_PROGRESS_SHM) {
Packit Service c5cf8c
        mpi_errno = MPIDI_SHM_progress(0, 0);
Packit Service c5cf8c
        if (mpi_errno != MPI_SUCCESS) {
Packit Service c5cf8c
            MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4_Global.vni_lock);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_PROGRESS_TEST);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_Progress_test
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_test(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    return MPIDI_Progress_test(MPIDI_PROGRESS_ALL);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_poke(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_POKE);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_POKE);
Packit Service c5cf8c
Packit Service c5cf8c
    ret = MPID_Progress_test();
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_POKE);
Packit Service c5cf8c
    return ret;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX void MPID_Progress_start(MPID_Progress_state * state)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_START);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_START);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_START);
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX void MPID_Progress_end(MPID_Progress_state * state)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_END);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_END);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_END);
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_wait(MPID_Progress_state * state)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_WAIT);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_WAIT);
Packit Service c5cf8c
Packit Service c5cf8c
    if (MPIDI_CH4_MT_MODEL != MPIDI_CH4_MT_DIRECT) {
Packit Service c5cf8c
        ret = MPID_Progress_test();
Packit Service c5cf8c
        if (unlikely(ret))
Packit Service c5cf8c
            MPIR_ERR_POP(ret);
Packit Service c5cf8c
        MPID_THREAD_CS_YIELD(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit Service c5cf8c
        goto fn_exit;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    state->progress_count = OPA_load_int(&MPIDI_CH4_Global.progress_count);
Packit Service c5cf8c
    do {
Packit Service c5cf8c
        ret = MPID_Progress_test();
Packit Service c5cf8c
        if (unlikely(ret))
Packit Service c5cf8c
            MPIR_ERR_POP(ret);
Packit Service c5cf8c
        if (state->progress_count != OPA_load_int(&MPIDI_CH4_Global.progress_count))
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        MPID_THREAD_CS_YIELD(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit Service c5cf8c
    } while (1);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_WAIT);
Packit Service c5cf8c
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
    return ret;
Packit Service c5cf8c
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_Progress_register
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_register(int (*progress_fn) (int *), int *id)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_REGISTER);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_REGISTER);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    for (i = 0; i < MAX_PROGRESS_HOOKS; i++) {
Packit Service c5cf8c
        if (MPIDI_CH4_Global.progress_hooks[i].func_ptr == NULL) {
Packit Service c5cf8c
            MPIDI_CH4_Global.progress_hooks[i].func_ptr = progress_fn;
Packit Service c5cf8c
            MPIDI_CH4_Global.progress_hooks[i].active = FALSE;
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (i >= MAX_PROGRESS_HOOKS)
Packit Service c5cf8c
        goto fn_fail;
Packit Service c5cf8c
Packit Service c5cf8c
    OPA_incr_int(&MPIDI_CH4_Global.active_progress_hooks);
Packit Service c5cf8c
Packit Service c5cf8c
    (*id) = i;
Packit Service c5cf8c
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_REGISTER);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
Packit Service c5cf8c
                                     "MPID_Progress_register", __LINE__,
Packit Service c5cf8c
                                     MPI_ERR_INTERN, "**progresshookstoomany", 0);
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_Progress_deregister
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_deregister(int id)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_DEREGISTER);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_DEREGISTER);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_Assert(id >= 0);
Packit Service c5cf8c
    MPIR_Assert(id < MAX_PROGRESS_HOOKS);
Packit Service c5cf8c
    MPIR_Assert(MPIDI_CH4_Global.progress_hooks[id].func_ptr != NULL);
Packit Service c5cf8c
    MPIDI_CH4_Global.progress_hooks[id].func_ptr = NULL;
Packit Service c5cf8c
    MPIDI_CH4_Global.progress_hooks[id].active = FALSE;
Packit Service c5cf8c
Packit Service c5cf8c
    OPA_decr_int(&MPIDI_CH4_Global.active_progress_hooks);
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_DEREGISTER);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_Progress_activate
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_activate(int id)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_ACTIVATE);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_ACTIVATE);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_Assert(id >= 0);
Packit Service c5cf8c
    MPIR_Assert(id < MAX_PROGRESS_HOOKS);
Packit Service c5cf8c
    /* Asserting that active == FALSE shouldn't be done outside the global lock
Packit Service c5cf8c
     * model. With fine-grained locks, two threads might try to activate the same
Packit Service c5cf8c
     * hook concurrently, in which case one of them will correctly detect that
Packit Service c5cf8c
     * active == TRUE because the other thread set it.*/
Packit Service c5cf8c
Packit Service c5cf8c
    if (MPIDI_CH4_Global.progress_hooks[id].active == FALSE) {
Packit Service c5cf8c
        MPIR_Assert(MPIDI_CH4_Global.progress_hooks[id].func_ptr != NULL);
Packit Service c5cf8c
        MPIDI_CH4_Global.progress_hooks[id].active = TRUE;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_ACTIVATE);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_Progress_deactivate
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
MPL_STATIC_INLINE_PREFIX int MPID_Progress_deactivate(int id)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_PROGRESS_DEACTIVATE);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_PROGRESS_DEACTIVATE);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_ENTER(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_Assert(id >= 0);
Packit Service c5cf8c
    MPIR_Assert(id < MAX_PROGRESS_HOOKS);
Packit Service c5cf8c
    /* We shouldn't assert that active == TRUE here for the same reasons
Packit Service c5cf8c
     * as not asserting active == FALSE in Progress_activate */
Packit Service c5cf8c
Packit Service c5cf8c
    if (MPIDI_CH4_Global.progress_hooks[id].active == TRUE) {
Packit Service c5cf8c
        MPIR_Assert(MPIDI_CH4_Global.progress_hooks[id].func_ptr != NULL);
Packit Service c5cf8c
        MPIDI_CH4_Global.progress_hooks[id].active = FALSE;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(VNI, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPID_THREAD_CS_EXIT(POBJ, MPIDI_CH4I_THREAD_PROGRESS_HOOK_MUTEX);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_PROGRESS_DEACTIVATE);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#endif /* CH4_PROGRESS_H_INCLUDED */