1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 *
4 * (C) 2001 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
6 */
7
8 #include "mpiimpl.h"
9 #include "bsendutil.h"
10
11 /* -- Begin Profiling Symbol Block for routine MPI_Buffer_detach */
12 #if defined(HAVE_PRAGMA_WEAK)
13 #pragma weak MPI_Buffer_detach = PMPI_Buffer_detach
14 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
15 #pragma _HP_SECONDARY_DEF PMPI_Buffer_detach MPI_Buffer_detach
16 #elif defined(HAVE_PRAGMA_CRI_DUP)
17 #pragma _CRI duplicate MPI_Buffer_detach as PMPI_Buffer_detach
18 #endif
19 /* -- End Profiling Symbol Block */
20
21 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
22 the MPI routines */
23 #ifndef MPICH_MPI_FROM_PMPI
24 #undef MPI_Buffer_detach
25 #define MPI_Buffer_detach PMPI_Buffer_detach
26
27 #endif
28
29 #undef FUNCNAME
30 #define FUNCNAME MPI_Buffer_detach
31
32 /*@
33 MPI_Buffer_detach - Removes an existing buffer (for use in MPI_Bsend etc)
34
35 Output Parameters:
36 + buffer - initial buffer address (choice)
37 - size - buffer size, in bytes (integer)
38
39 Notes:
40 The reason that 'MPI_Buffer_detach' returns the address and size of the
41 buffer being detached is to allow nested libraries to replace and restore
42 the buffer. For example, consider
43
44 .vb
45 int size, mysize, idummy;
46 void *ptr, *myptr, *dummy;
47 MPI_Buffer_detach( &ptr, &size );
48 MPI_Buffer_attach( myptr, mysize );
49 ...
50 ... library code ...
51 ...
52 MPI_Buffer_detach( &dummy, &idummy );
53 MPI_Buffer_attach( ptr, size );
54 .ve
55
56 This is much like the action of the Unix signal routine and has the same
57 strengths (it is simple) and weaknesses (it only works for nested usages).
58
59 Note that for this approach to work, MPI_Buffer_detach must return MPI_SUCCESS
60 even when there is no buffer to detach. In that case, it returns a size of
61 zero. The MPI 1.1 standard for 'MPI_BUFFER_DETACH' contains the text
62
63 .vb
64 The statements made in this section describe the behavior of MPI for
65 buffered-mode sends. When no buffer is currently associated, MPI behaves
66 as if a zero-sized buffer is associated with the process.
67 .ve
68
69 This could be read as applying only to the various Bsend routines. This
70 implementation takes the position that this applies to 'MPI_BUFFER_DETACH'
71 as well.
72
73 .N NotThreadSafe
74 Because the buffer for buffered sends (e.g., 'MPI_Bsend') is shared by all
75 threads in a process, the user is responsible for ensuring that only
76 one thread at a time calls this routine or 'MPI_Buffer_attach'.
77
78 .N Fortran
79
80 The Fortran binding for this routine is different. Because Fortran
81 does not have pointers, it is impossible to provide a way to use the
82 output of this routine to exchange buffers. In this case, only the
83 size field is set.
84
85 Notes for C:
86 Even though the 'bufferptr' argument is declared as 'void *', it is
87 really the address of a void pointer. See the rationale in the
88 standard for more details.
89
90 .seealso: MPI_Buffer_attach
91 @*/
MPI_Buffer_detach(void * buffer,int * size)92 int MPI_Buffer_detach(void *buffer, int *size)
93 {
94 static const char FCNAME[] = "MPI_Buffer_detach";
95 int mpi_errno = MPI_SUCCESS;
96 MPID_MPI_STATE_DECL(MPID_STATE_MPI_BUFFER_DETACH);
97
98 MPIR_ERRTEST_INITIALIZED_ORDIE();
99
100 MPIU_THREAD_CS_ENTER(ALLFUNC,);
101 MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_BUFFER_DETACH);
102
103 # ifdef HAVE_ERROR_CHECKING
104 {
105 MPID_BEGIN_ERROR_CHECKS;
106 {
107 MPIR_ERRTEST_ARGNULL(size,"size",mpi_errno);
108 }
109 MPID_END_ERROR_CHECKS;
110 }
111 # endif /* HAVE_ERROR_CHECKING */
112
113 /* ... body of routine ... */
114
115 mpi_errno = MPIR_Bsend_detach( buffer, size );
116 if (mpi_errno != MPI_SUCCESS) goto fn_fail;
117
118 /* ... end of body of routine ... */
119
120 fn_exit:
121 MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_BUFFER_DETACH);
122 MPIU_THREAD_CS_EXIT(ALLFUNC,);
123 return mpi_errno;
124
125 fn_fail:
126 /* --BEGIN ERROR HANDLING-- */
127 # ifdef HAVE_ERROR_CHECKING
128 {
129 mpi_errno = MPIR_Err_create_code(
130 mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_buffer_detach",
131 "**mpi_buffer_detach %p %p", buffer, size);
132 }
133 # endif
134 mpi_errno = MPIR_Err_return_comm( 0, FCNAME, mpi_errno );
135 goto fn_exit;
136 /* --END ERROR HANDLING-- */
137 }
138
139