1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #include "mpiimpl.h"
7 #include "mpir_info.h"
8
9 #include <string.h>
10
11 /* -- Begin Profiling Symbol Block for routine MPI_Info_dup */
12 #if defined(HAVE_PRAGMA_WEAK)
13 #pragma weak MPI_Info_dup = PMPI_Info_dup
14 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
15 #pragma _HP_SECONDARY_DEF PMPI_Info_dup MPI_Info_dup
16 #elif defined(HAVE_PRAGMA_CRI_DUP)
17 #pragma _CRI duplicate MPI_Info_dup as PMPI_Info_dup
18 #elif defined(HAVE_WEAK_ATTRIBUTE)
19 int MPI_Info_dup(MPI_Info info, MPI_Info * newinfo) __attribute__ ((weak, alias("PMPI_Info_dup")));
20 #endif
21 /* -- End Profiling Symbol Block */
22
23 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
24 the MPI routines */
25 #ifndef MPICH_MPI_FROM_PMPI
26 #undef MPI_Info_dup
27 #define MPI_Info_dup PMPI_Info_dup
28
MPIR_Info_dup_impl(MPIR_Info * info_ptr,MPIR_Info ** new_info_ptr)29 int MPIR_Info_dup_impl(MPIR_Info * info_ptr, MPIR_Info ** new_info_ptr)
30 {
31 int mpi_errno = MPI_SUCCESS;
32 MPIR_Info *curr_old, *curr_new;
33
34 *new_info_ptr = NULL;
35 if (!info_ptr)
36 goto fn_exit;
37
38 /* Note that this routine allocates info elements one at a time.
39 * In the multithreaded case, each allocation may need to acquire
40 * and release the allocation lock. If that is ever a problem, we
41 * may want to add an "allocate n elements" routine and execute this
42 * it two steps: count and then allocate */
43 /* FIXME : multithreaded */
44 mpi_errno = MPIR_Info_alloc(&curr_new);
45 MPIR_ERR_CHECK(mpi_errno);
46 *new_info_ptr = curr_new;
47
48 curr_old = info_ptr->next;
49 while (curr_old) {
50 mpi_errno = MPIR_Info_alloc(&curr_new->next);
51 MPIR_ERR_CHECK(mpi_errno);
52
53 curr_new = curr_new->next;
54 curr_new->key = MPL_strdup(curr_old->key);
55 curr_new->value = MPL_strdup(curr_old->value);
56
57 curr_old = curr_old->next;
58 }
59
60 fn_exit:
61 return mpi_errno;
62 fn_fail:
63 goto fn_exit;
64 }
65
66 #endif
67
68 /*@
69 MPI_Info_dup - Returns a duplicate of the info object
70
71 Input Parameters:
72 . info - info object (handle)
73
74 Output Parameters:
75 . newinfo - duplicate of info object (handle)
76
77 .N ThreadSafeInfoRead
78
79 .N Fortran
80
81 .N Errors
82 .N MPI_SUCCESS
83 .N MPI_ERR_OTHER
84 @*/
MPI_Info_dup(MPI_Info info,MPI_Info * newinfo)85 int MPI_Info_dup(MPI_Info info, MPI_Info * newinfo)
86 {
87 MPIR_Info *info_ptr = 0, *new_info_ptr;
88 int mpi_errno = MPI_SUCCESS;
89 MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_INFO_DUP);
90
91 MPIR_ERRTEST_INITIALIZED_ORDIE();
92
93 MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
94 MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_INFO_DUP);
95
96 /* Validate parameters, especially handles needing to be converted */
97 #ifdef HAVE_ERROR_CHECKING
98 {
99 MPID_BEGIN_ERROR_CHECKS;
100 {
101 MPIR_ERRTEST_INFO(info, mpi_errno);
102 }
103 MPID_END_ERROR_CHECKS;
104 }
105 #endif /* HAVE_ERROR_CHECKING */
106
107 /* Convert MPI object handles to object pointers */
108 MPIR_Info_get_ptr(info, info_ptr);
109
110 /* Validate parameters and objects (post conversion) */
111 #ifdef HAVE_ERROR_CHECKING
112 {
113 MPID_BEGIN_ERROR_CHECKS;
114 {
115 /* Validate info_ptr */
116 MPIR_Info_valid_ptr(info_ptr, mpi_errno);
117 MPIR_ERRTEST_ARGNULL(newinfo, "newinfo", mpi_errno);
118 }
119 MPID_END_ERROR_CHECKS;
120 }
121 #endif /* HAVE_ERROR_CHECKING */
122
123 /* ... body of routine ... */
124
125 mpi_errno = MPIR_Info_dup_impl(info_ptr, &new_info_ptr);
126 if (mpi_errno != MPI_SUCCESS)
127 goto fn_fail;
128
129 *newinfo = new_info_ptr->handle;
130
131 /* ... end of body of routine ... */
132
133 fn_exit:
134 MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_INFO_DUP);
135 MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
136 return mpi_errno;
137
138 fn_fail:
139 /* --BEGIN ERROR HANDLING-- */
140 #ifdef HAVE_ERROR_CHECKING
141 {
142 mpi_errno =
143 MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER,
144 "**mpi_info_dup", "**mpi_info_dup %I %p", info, newinfo);
145 }
146 #endif
147 mpi_errno = MPIR_Err_return_comm(NULL, __func__, mpi_errno);
148 goto fn_exit;
149 /* --END ERROR HANDLING-- */
150 }
151