1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include "mpiimpl.h"
7 #include "utlist.h"
8 
9 /* -- Begin Profiling Symbol Block for routine MPI_T_pvar_handle_free */
10 #if defined(HAVE_PRAGMA_WEAK)
11 #pragma weak MPI_T_pvar_handle_free = PMPI_T_pvar_handle_free
12 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
13 #pragma _HP_SECONDARY_DEF PMPI_T_pvar_handle_free  MPI_T_pvar_handle_free
14 #elif defined(HAVE_PRAGMA_CRI_DUP)
15 #pragma _CRI duplicate MPI_T_pvar_handle_free as PMPI_T_pvar_handle_free
16 #elif defined(HAVE_WEAK_ATTRIBUTE)
17 int MPI_T_pvar_handle_free(MPI_T_pvar_session session, MPI_T_pvar_handle * handle)
18     __attribute__ ((weak, alias("PMPI_T_pvar_handle_free")));
19 #endif
20 /* -- End Profiling Symbol Block */
21 
22 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
23    the MPI routines */
24 #ifndef MPICH_MPI_FROM_PMPI
25 #undef MPI_T_pvar_handle_free
26 #define MPI_T_pvar_handle_free PMPI_T_pvar_handle_free
27 
28 /* any non-MPI functions go here, especially non-static ones */
29 
MPIR_T_pvar_handle_free_impl(MPI_T_pvar_session session,MPI_T_pvar_handle * handle)30 int MPIR_T_pvar_handle_free_impl(MPI_T_pvar_session session, MPI_T_pvar_handle * handle)
31 {
32     int mpi_errno = MPI_SUCCESS;
33     MPIR_T_pvar_handle_t *hnd = *handle;
34 
35     DL_DELETE(session->hlist, hnd);
36 
37     /* Unlink handle from pvar if it is a watermark */
38     if (MPIR_T_pvar_is_watermark(hnd)) {
39         MPIR_T_pvar_watermark_t *mark = (MPIR_T_pvar_watermark_t *) hnd->addr;
40         if (MPIR_T_pvar_is_first(hnd)) {
41             mark->first_used = 0;
42             mark->first_started = 0;
43         } else {
44             MPIR_Assert(mark->hlist);
45             if (mark->hlist == hnd) {
46                 /* hnd happens to be the head */
47                 mark->hlist = hnd->next2;
48                 if (mark->hlist != NULL)
49                     mark->hlist->prev2 = mark->hlist;
50             } else {
51                 hnd->prev2->next2 = hnd->next2;
52                 if (hnd->next2 != NULL)
53                     hnd->next2->prev2 = hnd->prev2;
54             }
55         }
56     }
57 
58     MPL_free(hnd);
59     *handle = MPI_T_PVAR_HANDLE_NULL;
60 
61     return mpi_errno;
62 }
63 
64 #endif /* MPICH_MPI_FROM_PMPI */
65 
66 /*@
67 MPI_T_pvar_handle_free - Free an existing handle for a performance variable
68 
69 Input/Output Parameters:
70 + session - identifier of performance experiment session (handle)
71 - handle - handle to be freed (handle)
72 
73 .N ThreadSafe
74 
75 .N Errors
76 .N MPI_SUCCESS
77 .N MPI_T_ERR_NOT_INITIALIZED
78 .N MPI_T_ERR_INVALID_SESSION
79 .N MPI_T_ERR_INVALID_HANDLE
80 @*/
MPI_T_pvar_handle_free(MPI_T_pvar_session session,MPI_T_pvar_handle * handle)81 int MPI_T_pvar_handle_free(MPI_T_pvar_session session, MPI_T_pvar_handle * handle)
82 {
83     int mpi_errno = MPI_SUCCESS;
84 
85     MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_T_PVAR_HANDLE_FREE);
86     MPIR_ERRTEST_MPIT_INITIALIZED(mpi_errno);
87     MPIR_T_THREAD_CS_ENTER();
88     MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_T_PVAR_HANDLE_FREE);
89 
90     /* Validate parameters, especially handles needing to be converted */
91 #ifdef HAVE_ERROR_CHECKING
92     {
93         MPID_BEGIN_ERROR_CHECKS;
94         {
95             MPIR_ERRTEST_ARGNULL(handle, "handle", mpi_errno);
96             if (*handle == MPI_T_PVAR_HANDLE_NULL)      /* free NULL is OK */
97                 goto fn_exit;
98             MPIR_ERRTEST_PVAR_SESSION(session, mpi_errno);
99             MPIR_ERRTEST_PVAR_HANDLE(*handle, mpi_errno);
100 
101             if ((*handle) == MPI_T_PVAR_ALL_HANDLES || (*handle)->session != session) {
102                 mpi_errno = MPI_T_ERR_INVALID_HANDLE;
103                 goto fn_fail;
104             }
105         }
106         MPID_END_ERROR_CHECKS;
107     }
108 #endif /* HAVE_ERROR_CHECKING */
109 
110     /* ... body of routine ...  */
111 
112     mpi_errno = MPIR_T_pvar_handle_free_impl(session, handle);
113     MPIR_ERR_CHECK(mpi_errno);
114 
115     /* ... end of body of routine ... */
116 
117   fn_exit:
118     MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_T_PVAR_HANDLE_FREE);
119     MPIR_T_THREAD_CS_EXIT();
120     return mpi_errno;
121 
122   fn_fail:
123     /* --BEGIN ERROR HANDLING-- */
124 #ifdef HAVE_ERROR_CHECKING
125     {
126         mpi_errno =
127             MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER,
128                                  "**mpi_t_pvar_handle_free", "**mpi_t_pvar_handle_free %p %p",
129                                  session, handle);
130     }
131 #endif
132     mpi_errno = MPIR_Err_return_comm(NULL, __func__, mpi_errno);
133     goto fn_exit;
134     /* --END ERROR HANDLING-- */
135 }
136