⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 req_wait.c

📁 MPI stands for the Message Passing Interface. Written by the MPI Forum (a large committee comprising
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana *                         University Research and Technology *                         Corporation.  All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University *                         of Tennessee Research Foundation.  All rights *                         reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,  *                         University of Stuttgart.  All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. *                         All rights reserved. * Copyright (c) 2006      Cisco Systems, Inc.  All rights reserved. * $COPYRIGHT$ *  * Additional copyrights may follow *  * $HEADER$ */#include "ompi_config.h"#include "ompi/constants.h"#include "ompi/request/request.h"#include "ompi/request/grequest.h"int ompi_request_wait(    ompi_request_t ** req_ptr,    ompi_status_public_t * status){    ompi_request_t *req = *req_ptr;    if(req->req_complete == false) {#if OMPI_ENABLE_PROGRESS_THREADS        /* poll for completion */        if(opal_progress_spin(&req->req_complete))            goto finished;#endif        /* give up and sleep until completion */        OPAL_THREAD_LOCK(&ompi_request_lock);        ompi_request_waiting++;        while (req->req_complete == false) {            opal_condition_wait(&ompi_request_cond, &ompi_request_lock);        }        ompi_request_waiting--;        OPAL_THREAD_UNLOCK(&ompi_request_lock);    }#if OMPI_ENABLE_PROGRESS_THREADSfinished:#endif    /* return status.  If it's a generalized request, we *have* to       invoke the query_fn, even if the user procided STATUS_IGNORE.       MPI-2:8.2. */    if (OMPI_REQUEST_GEN == req->req_type) {        ompi_grequest_invoke_query(req, &req->req_status);    }    if( MPI_STATUS_IGNORE != status ) {        /* See MPI-1.2, sec 3.2.5, p.22 */        status->MPI_TAG    = req->req_status.MPI_TAG;        status->MPI_SOURCE = req->req_status.MPI_SOURCE;        status->_count     = req->req_status._count;        status->_cancelled = req->req_status._cancelled;    }    if( req->req_persistent ) {        if( req->req_state == OMPI_REQUEST_INACTIVE ) {            return OMPI_SUCCESS;        }        req->req_state = OMPI_REQUEST_INACTIVE;        return req->req_status.MPI_ERROR;    }    /* If there was an error, don't free the request -- just return       the single error. */    if (MPI_SUCCESS != req->req_status.MPI_ERROR) {        return req->req_status.MPI_ERROR;    }    /* If there's an error while freeing the request, assume that the       request is still there.  Otherwise, Bad Things will happen       later! */    return ompi_request_free(req_ptr);}int ompi_request_wait_any(    size_t count,    ompi_request_t ** requests,    int *index,    ompi_status_public_t * status){#if OMPI_ENABLE_PROGRESS_THREADS    int c;#endif    size_t i=0, num_requests_null_inactive=0;    int rc = OMPI_SUCCESS;    int completed = -1;    ompi_request_t **rptr=NULL;    ompi_request_t *request=NULL;#if OMPI_ENABLE_PROGRESS_THREADS    /* poll for completion */    OPAL_THREAD_ADD32(&opal_progress_thread_count,1);    for (c = 0; completed < 0 && c < opal_progress_spin_count; c++) {        rptr = requests;        num_requests_null_inactive = 0;        for (i = 0; i < count; i++, rptr++) {            request = *rptr;            /*             * Check for null or completed persistent request.             * For MPI_REQUEST_NULL, the req_state is always OMPI_REQUEST_INACTIVE             */            if( request->req_state == OMPI_REQUEST_INACTIVE ) {                num_requests_null_inactive++;                continue;            }            if (true == request->req_complete) {                completed = i;                OPAL_THREAD_ADD32(&opal_progress_thread_count,-1);                goto finished;            }        }        if( num_requests_null_inactive == count ) {            OPAL_THREAD_ADD32(&opal_progress_thread_count,-1);            goto finished;        }        opal_progress();    }    OPAL_THREAD_ADD32(&opal_progress_thread_count,-1);#endif    /* give up and sleep until completion */    OPAL_THREAD_LOCK(&ompi_request_lock);    ompi_request_waiting++;    do {        rptr = requests;        num_requests_null_inactive = 0;        for (i = 0; i < count; i++, rptr++) {            request = *rptr;            /*             * Check for null or completed persistent request.             * For MPI_REQUEST_NULL, the req_state is always OMPI_REQUEST_INACTIVE.             */            if( request->req_state == OMPI_REQUEST_INACTIVE ) {                num_requests_null_inactive++;                continue;            }            if (request->req_complete == true) {                completed = i;                break;            }        }        if(num_requests_null_inactive == count)            break;        if (completed < 0) {            opal_condition_wait(&ompi_request_cond, &ompi_request_lock);        }    } while (completed < 0);    ompi_request_waiting--;    OPAL_THREAD_UNLOCK(&ompi_request_lock);#if OMPI_ENABLE_PROGRESS_THREADSfinished:#endif  /* OMPI_ENABLE_PROGRESS_THREADS */    if(num_requests_null_inactive == count) {        *index = MPI_UNDEFINED;        if (MPI_STATUS_IGNORE != status) {            *status = ompi_status_empty;        }    } else {        assert( true == request->req_complete );        /* Per note above, we have to call gen request query_fn even           if STATUS_IGNORE was provided */        if (OMPI_REQUEST_GEN == request->req_type) {            rc = ompi_grequest_invoke_query(request, &request->req_status);        }        if (MPI_STATUS_IGNORE != status) {            /* See MPI-1.2, sec 3.2.5, p.22 */            int old_error = status->MPI_ERROR;            *status = request->req_status;            status->MPI_ERROR = old_error;        }        rc = request->req_status.MPI_ERROR;        if( request->req_persistent ) {            request->req_state = OMPI_REQUEST_INACTIVE;        } else if (MPI_SUCCESS == rc) {            /* Only free the request if there is no error on it */            /* If there's an error while freeing the request,               assume that the request is still there.  Otherwise,               Bad Things will happen later! */            rc = ompi_request_free(rptr);        }        *index = completed;    }    return rc;}int ompi_request_wait_all(    size_t count,    ompi_request_t ** requests,    ompi_status_public_t * statuses){    size_t completed = 0, i;    ompi_request_t **rptr;    ompi_request_t *request;    int mpi_error = OMPI_SUCCESS;    rptr = requests;    for (i = 0; i < count; i++) {        request = *rptr++;        if (request->req_complete == true) {            completed++;        }    }    /* if all requests have not completed -- defer acquiring lock     * unless required     */    if (completed != count) {        /*         * acquire lock and test for completion - if all requests are         * not completed pend on condition variable until a request         * completes         */        OPAL_THREAD_LOCK(&ompi_request_lock);        ompi_request_waiting++;#if OMPI_HAVE_THREAD_SUPPORT        /*         * confirm the status of the pending requests. We have to do it before         * taking the condition or otherwise we can miss some requests completion (the         * one that happpens between our initial test and the aquisition of the lock).         */        rptr = requests;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -