int ompi_request_finalize(void) { OMPI_REQUEST_FINI( &ompi_request_null.request ); OBJ_DESTRUCT( &ompi_request_null.request ); OMPI_REQUEST_FINI( &ompi_request_empty ); OBJ_DESTRUCT( &ompi_request_empty ); OBJ_DESTRUCT( &ompi_request_cond ); OBJ_DESTRUCT( &ompi_request_lock ); OBJ_DESTRUCT( &ompi_request_f_to_c_table ); return OMPI_SUCCESS; }
int ompi_request_persistent_proc_null_free(ompi_request_t** request) { OMPI_REQUEST_FINI(*request); (*request)->req_state = OMPI_REQUEST_INVALID; OBJ_RELEASE(*request); *request = &ompi_request_null.request; return OMPI_SUCCESS; }
/* * MPI has some weird semantics with respect to generalized requests * -- different than all other MPI object types. So we move some * cleanup stuff here to the destructor rather than in * greqeust_request_free -- mainly because the cleanup may be required * in two different places. * * Specifically, generalized requests can be completed (and therefore * released) the following ways: * * 1. Call to MPI_GREQUEST_COMPLETE and then a corresponding call to * some flavor of MPI_TEST* or MPI_WAIT*. This will both complete the * requests and destroy the coresponding MPI generalized request * object. * * 2. Call MPI_REQUEST_FREE and then (!) -- with some other * still-valid copy of the handler -- call MPI_GREQUEST_COMPLETE. * * 3. Reverse the order of #2 -- call MPI_GREQUEST_COMPLETE and then * MPI_REQUEST_FREE. * * So any one of these functions may actually be the one that * de-allocates the back-end request object. Hence, this is perfect * for our reference counting system -- so the call to the gen request * free_fn() is back here in the destructor, whenever the object is * actually freed. * * Hence, the following must occur before a grequest is freed: * * - ompi_grequest_complete() (i.e., GREQUEST_COMPLETE) is invoked * - ompi_grequest_free() is invoked * * Remember that ompi_grequest_free() is invoked by MPI_TEST* and * MPI_WAIT* when the request was previously marked as complete and * TEST* / WAIT* notified the user as such, and this function is also * invoked by REQUEST_FREE). Hence, these two functions will *always* * be invoked, but the order in which they are invoked is up to the * user. So this is a perfect opprotunity for the OBJ_* reference * count system. When we create an ompi_grequest_t in * ompi_grequest_start(), we both OBJ_NEW and OBJ_RETAIN it so that * its reference count goes to 0. Then in ompi_grequest_complete() * and ompi_grequest_free(), we OBJ_RELEASE it. Hence, when both of * them have RELEASEd -- regardless of the order in which the * functions were invoked, then the destructor is invoked and * everything is cleaned up (and we invoked the grequest free_fn). */ static void ompi_grequest_destruct(ompi_grequest_t* greq) { MPI_Fint ierr; if (greq->greq_free.c_free != NULL) { if (greq->greq_funcs_are_c) { greq->greq_free.c_free(greq->greq_state); } else { greq->greq_free.f_free((MPI_Aint*)greq->greq_state, &ierr); } } OMPI_REQUEST_FINI(&greq->greq_base); }
int mca_pml_ucx_cleanup(void) { PML_UCX_VERBOSE(1, "mca_pml_ucx_cleanup"); opal_progress_unregister(mca_pml_ucx_progress); ompi_pml_ucx.completed_send_req.req_state = OMPI_REQUEST_INVALID; OMPI_REQUEST_FINI(&ompi_pml_ucx.completed_send_req); OBJ_DESTRUCT(&ompi_pml_ucx.completed_send_req); OBJ_DESTRUCT(&ompi_pml_ucx.convs); OBJ_DESTRUCT(&ompi_pml_ucx.persistent_reqs); if (ompi_pml_ucx.ucp_worker) { ucp_worker_destroy(ompi_pml_ucx.ucp_worker); ompi_pml_ucx.ucp_worker = NULL; } return OMPI_SUCCESS; }
static void mca_pml_yalla_recv_request_destruct(mca_pml_yalla_recv_request_t *rreq) { OMPI_REQUEST_FINI(&rreq->super.ompi); }
static void mca_pml_yalla_send_request_destruct(mca_pml_yalla_send_request_t *sreq) { OMPI_REQUEST_FINI(&sreq->super.ompi); }