1 /* begin_generated_IBM_copyright_prolog */
2 /* */
3 /* This is an automatically generated copyright prolog. */
4 /* After initializing, DO NOT MODIFY OR MOVE */
5 /* --------------------------------------------------------------- */
6 /* Licensed Materials - Property of IBM */
7 /* Blue Gene/Q 5765-PER 5765-PRP */
8 /* */
9 /* (C) Copyright IBM Corp. 2011, 2012 All Rights Reserved */
10 /* US Government Users Restricted Rights - */
11 /* Use, duplication, or disclosure restricted */
12 /* by GSA ADP Schedule Contract with IBM Corp. */
13 /* */
14 /* --------------------------------------------------------------- */
15 /* */
16 /* end_generated_IBM_copyright_prolog */
17 /* (C)Copyright IBM Corp. 2007, 2011 */
18 /**
19 * \file src/mpid_request.h
20 * \brief ???
21 */
22
23 #ifndef __src_mpid_request_h__
24 #define __src_mpid_request_h__
25
26 #include "mpid_datatype.h"
27
28 /**
29 * \addtogroup MPID_REQUEST
30 * \{
31 */
32
33 #define MPID_Request_create MPID_Request_create_inline
34 #define MPID_Request_release MPID_Request_release_inline
35 #define MPIDI_Request_complete MPIDI_Request_complete_inline
36 #define MPIDI_Request_complete_norelease MPIDI_Request_complete_norelease_inline
37 #define MPID_Request_discard MPID_Request_discard_inline
38
39
40 extern MPIU_Object_alloc_t MPID_Request_mem;
41
42
43 void MPIDI_Request_uncomplete(MPID_Request *req);
44 #if (MPIU_HANDLE_ALLOCATION_METHOD == MPIU_HANDLE_ALLOCATION_THREAD_LOCAL) && defined(__BGQ__)
45 void MPIDI_Request_allocate_pool();
46 #endif
47
48 #define MPIDI_Request_getCA(_req) ({ (_req)->mpid.ca; })
49 #define MPIDI_Request_getPeerRank_pami(_req) ({ (_req)->mpid.peer_pami; })
50 #define MPIDI_Request_getPeerRank_comm(_req) ({ (_req)->mpid.peer_comm; })
51 #define MPIDI_Request_getPType(_req) ({ (_req)->mpid.ptype; })
52 #define MPIDI_Request_getControl(_req) ({ (_req)->mpid.envelope.msginfo.control; })
53 #define MPIDI_Request_isSync(_req) ({ (_req)->mpid.envelope.msginfo.isSync; })
54 #define MPIDI_Request_isRzv(_req) ({ (_req)->mpid.envelope.msginfo.isRzv; })
55 #define MPIDI_Request_getMatchTag(_req) ({ (_req)->mpid.envelope.msginfo.MPItag; })
56 #define MPIDI_Request_getMatchRank(_req) ({ (_req)->mpid.envelope.msginfo.MPIrank; })
57 #define MPIDI_Request_getMatchCtxt(_req) ({ (_req)->mpid.envelope.msginfo.MPIctxt; })
58
59 #define MPIDI_Request_setCA(_req, _ca) ({ (_req)->mpid.ca = (_ca); })
60 #define MPIDI_Request_setPeerRank_pami(_req,_r) ({ (_req)->mpid.peer_pami = (_r); })
61 #define MPIDI_Request_setPeerRank_comm(_req,_r) ({ (_req)->mpid.peer_comm = (_r); })
62 #define MPIDI_Request_setPType(_req,_t) ({ (_req)->mpid.ptype = (_t); })
63 #define MPIDI_Request_setControl(_req,_t) ({ (_req)->mpid.envelope.msginfo.control = (_t); })
64 #define MPIDI_Request_setSync(_req,_t) ({ (_req)->mpid.envelope.msginfo.isSync = (_t); })
65 #define MPIDI_Request_setRzv(_req,_t) ({ (_req)->mpid.envelope.msginfo.isRzv = (_t); })
66 #ifdef OUT_OF_ORDER_HANDLING
67 #define MPIDI_Request_getMatchSeq(_req) ({ (_req)->mpid.envelope.msginfo.MPIseqno; })
68 #define MPIDI_Request_setMatchSeq(_req,_sq) ({ (_req)->mpid.envelope.msginfo.MPIseqno = (_sq); })
69 #endif
70 #define MPIDI_Request_setMatch(_req,_tag,_rank,_ctxtid) \
71 ({ \
72 (_req)->mpid.envelope.msginfo.MPItag=(_tag); \
73 (_req)->mpid.envelope.msginfo.MPIrank=(_rank); \
74 (_req)->mpid.envelope.msginfo.MPIctxt=(_ctxtid); \
75 })
76
77 #define MPIDI_Msginfo_getPeerRequest(_msg) ({ MPID_Request *req=NULL; MPID_Request_get_ptr((_msg)->req, req); MPID_assert(req != NULL); req; })
78 #define MPIDI_Msginfo_getPeerRequestH(_msg) ({ (_msg)->req; })
79 #define MPIDI_Msginfo_cpyPeerRequestH(_dst,_src) ({ (_dst)->req = (_src)->req; MPI_SUCCESS; })
80 #define MPIDI_Request_getPeerRequest(_req) MPIDI_Msginfo_getPeerRequest(&(_req)->mpid.envelope.msginfo)
81 #define MPIDI_Request_getPeerRequestH(_req) ({ (_req)->mpid.envelope.msginfo.req; })
82 #define MPIDI_Request_setPeerRequestH(_req) ({ (_req)->mpid.envelope.msginfo.req = (_req)->handle; MPI_SUCCESS; })
83 #define MPIDI_Request_cpyPeerRequestH(_dst,_src) MPIDI_Msginfo_cpyPeerRequestH(&(_dst)->mpid.envelope.msginfo,_src)
84
85
86 #define MPIU_HANDLE_ALLOCATION_MUTEX 0
87 #define MPIU_HANDLE_ALLOCATION_THREAD_LOCAL 1
88
89 /* XXX DJG for TLS hack */
90 #define MPID_REQUEST_TLS_MAX 128
91
92 #if (MPIU_HANDLE_ALLOCATION_METHOD == MPIU_HANDLE_ALLOCATION_THREAD_LOCAL) && defined(__BGQ__)
93
94 # define MPIDI_Request_tls_alloc(req) \
95 ({ \
96 size_t tid = MPIDI_THREAD_ID(); \
97 MPIDI_RequestHandle_t *rh = &MPIDI_Process.request_handles[tid]; \
98 if (unlikely(rh->head == NULL)) \
99 MPIDI_Request_allocate_pool(); \
100 (req) = rh->head; \
101 rh->head = req->mpid.next; \
102 rh->count --; \
103 })
104
105 # define MPIDI_Request_tls_free(req) \
106 ({ \
107 size_t tid = MPIDI_THREAD_ID(); \
108 MPIDI_RequestHandle_t *rh = &MPIDI_Process.request_handles[tid]; \
109 if (likely(rh->count < MPID_REQUEST_TLS_MAX)) \
110 { \
111 /* push request onto the top of the stack */ \
112 req->mpid.next = rh->head; \
113 rh->head = req; \
114 rh->count ++; \
115 } \
116 else \
117 { \
118 MPIU_Handle_obj_free(&MPID_Request_mem, req); \
119 } \
120 })
121
122 #else
123
124 # define MPIDI_Request_tls_alloc(req) \
125 ({ \
126 (req) = MPIU_Handle_obj_alloc(&MPID_Request_mem); \
127 if (req == NULL) \
128 MPID_Abort(NULL, MPI_ERR_NO_SPACE, -1, "Cannot allocate Request"); \
129 })
130
131 # define MPIDI_Request_tls_free(req) MPIU_Handle_obj_free(&MPID_Request_mem, (req))
132
133 #endif
134
135
136 /**
137 * \brief Create a very generic request
138 * \note This should only ever be called by more specific allocators
139 */
140 static inline MPID_Request *
MPIDI_Request_create_basic()141 MPIDI_Request_create_basic()
142 {
143 MPID_Request * req = NULL;
144
145 MPIDI_Request_tls_alloc(req);
146 MPID_assert(req != NULL);
147 MPID_assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);
148 MPID_cc_set(&req->cc, 1);
149 req->cc_ptr = &req->cc;
150
151 #if 0
152 /* This will destroy the MPID part of the request. Use this to
153 check for fields that are not being correctly initialized. */
154 memset(&req->mpid, 0xFFFFFFFF, sizeof(struct MPIDI_Request));
155 #endif
156 req->mpid.next = NULL;
157
158 return req;
159 }
160
161
162 /**
163 * \brief Create new request without initalizing
164 */
165 static inline MPID_Request *
MPIDI_Request_create2_fast()166 MPIDI_Request_create2_fast()
167 {
168 MPID_Request * req;
169 req = MPIDI_Request_create_basic();
170 MPIU_Object_set_ref(req, 2);
171
172 return req;
173 }
174
175
176 /**
177 * \brief Create and initialize a new request
178 */
179 static inline void
MPIDI_Request_initialize(MPID_Request * req)180 MPIDI_Request_initialize(MPID_Request * req)
181 {
182 req->greq_fns = NULL;
183
184 req->status.count = 0;
185 req->status.cancelled = FALSE;
186 req->status.MPI_SOURCE = MPI_UNDEFINED;
187 req->status.MPI_TAG = MPI_UNDEFINED;
188 req->status.MPI_ERROR = MPI_SUCCESS;
189
190 struct MPIDI_Request* mpid = &req->mpid;
191 mpid->envelope.msginfo.flags = 0;
192 mpid->cancel_pending = FALSE;
193 mpid->datatype_ptr = NULL;
194 mpid->uebuf = NULL;
195 mpid->uebuflen = 0;
196 mpid->uebuf_malloc = 0;
197 #ifdef OUT_OF_ORDER_HANDLING
198 mpid->prev = NULL;
199 mpid->prevR = NULL;
200 mpid->nextR = NULL;
201 mpid->oo_peer = NULL;
202 #endif
203 MPIDI_Request_setCA(req, MPIDI_CA_COMPLETE);
204 }
205
206
207 /**
208 * \brief Create and initialize a new request
209 */
210 static inline MPID_Request *
MPID_Request_create_inline()211 MPID_Request_create_inline()
212 {
213 MPID_Request * req;
214 req = MPIDI_Request_create_basic();
215 MPIU_Object_set_ref(req, 1);
216
217 MPIDI_Request_initialize(req);
218 req->comm=NULL;
219
220 return req;
221 }
222
223
224 /**
225 * \brief Create and initialize a new request
226 */
227 static inline MPID_Request *
MPIDI_Request_create2()228 MPIDI_Request_create2()
229 {
230 MPID_Request * req;
231 req = MPID_Request_create();
232 MPIU_Object_set_ref(req, 2);
233
234 return req;
235 }
236
237
238 /**
239 * \brief Mark a request as cancel-pending
240 * \param[in] _req The request to cancel
241 * \return The previous state
242 */
243 #define MPIDI_Request_cancel_pending(_req) \
244 ({ \
245 int _flag = (_req)->mpid.cancel_pending; \
246 (_req)->mpid.cancel_pending = TRUE; \
247 _flag; \
248 })
249
250
251 static inline void
MPID_Request_release_inline(MPID_Request * req)252 MPID_Request_release_inline(MPID_Request *req)
253 {
254 int count;
255 MPID_assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);
256 MPIU_Object_release_ref(req, &count);
257 MPID_assert(count >= 0);
258
259 if (count == 0)
260 {
261 MPID_assert(MPID_cc_is_complete(&req->cc));
262
263 if (req->comm) MPIR_Comm_release(req->comm, 0);
264 if (req->greq_fns) MPIU_Free(req->greq_fns);
265 if (req->mpid.datatype_ptr) MPID_Datatype_release(req->mpid.datatype_ptr);
266 if (req->mpid.uebuf_malloc) MPIU_Free(req->mpid.uebuf);
267 MPIDI_Request_tls_free(req);
268 }
269 }
270
271
272 /* This request was never used, at most had uebuf allocated. */
273 static inline void
MPID_Request_discard_inline(MPID_Request * req)274 MPID_Request_discard_inline(MPID_Request *req)
275 {
276 if (req->mpid.uebuf_malloc) MPIU_Free(req->mpid.uebuf);
277 MPIDI_Request_tls_free(req);
278 }
279
280 #define MPID_REQUEST_SET_COMPLETED(req_) \
281 MPIDI_Request_complete_inline(req_)
282
283 static inline void
MPIDI_Request_complete_inline(MPID_Request * req)284 MPIDI_Request_complete_inline(MPID_Request *req)
285 {
286 int count;
287 MPID_cc_decr(req->cc_ptr, &count);
288 MPID_assert(count >= 0);
289
290 MPID_Request_release(req);
291 if (count == 0) /* decrement completion count; if 0, signal progress engine */
292 {
293 MPIDI_Progress_signal();
294 }
295 }
296
297
298 static inline void
MPIDI_Request_complete_norelease_inline(MPID_Request * req)299 MPIDI_Request_complete_norelease_inline(MPID_Request *req)
300 {
301 int count;
302 MPID_cc_decr(req->cc_ptr, &count);
303 MPID_assert(count >= 0);
304
305 if (count == 0) /* decrement completion count; if 0, signal progress engine */
306 {
307 MPIDI_Progress_signal();
308 }
309 }
310
311
312 /** \} */
313
314
315 #endif
316