root/mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/src/mpid_nem_alloc.c @ 4538

Revision 4538, 19.2 KB (checked in by goodell, 6 months ago)

Updating to official openpa v1.0.0 release.

Reviewed by buntinas@.

Line 
1/* -*- Mode: C; c-basic-offset:4 ; -*- */
2/*
3 *  (C) 2006 by Argonne National Laboratory.
4 *      See COPYRIGHT in top-level directory.
5 */
6
7#include "mpid_nem_impl.h"
8#ifdef USE_PMI2_API
9#include "pmi2.h"
10#else
11#include "pmi.h"
12#endif
13
14#include <stdlib.h>
15#ifdef HAVE_UNISTD_H
16    #include <unistd.h>
17#endif
18#include <errno.h>
19
20#if defined (HAVE_SYSV_SHARED_MEM)
21#include <sys/ipc.h>
22#include <sys/shm.h>
23#endif
24
25#if defined( HAVE_MKSTEMP ) && defined( NEEDS_MKSTEMP_DECL )
26extern int mkstemp(char *t);
27#endif
28
29static int check_alloc(int num_local, int local_rank);
30
31typedef struct alloc_elem
32{
33    struct alloc_elem *next;
34    void **ptr_p;
35    size_t len;
36} alloc_elem_t;
37
38static struct { alloc_elem_t *head, *tail; } allocq = {0};
39
40#define ALLOCQ_HEAD() GENERIC_Q_HEAD(allocq)
41#define ALLOCQ_EMPTY() GENERIC_Q_EMPTY(allocq)
42#define ALLOCQ_ENQUEUE(ep) GENERIC_Q_ENQUEUE(&allocq, ep, next)
43#define ALLOCQ_DEQUEUE(epp) GENERIC_Q_DEQUEUE(&allocq, epp, next)
44
45#define ROUND_UP_8(x) (((x) + (size_t)7) & ~(size_t)7) /* rounds up to multiple of 8 */
46
47static size_t segment_len = 0;
48
49typedef struct asym_check_region
50{
51    void *base_ptr;
52    OPA_int_t is_asym;
53} asym_check_region;
54
55static asym_check_region* asym_check_region_p = NULL;
56
57/* MPIDI_CH3I_Seg_alloc(len, ptr_p)
58
59   This function is used to allow the caller to reserve a len sized
60   region in the shared memory segment.  Once the shared memory
61   segment is actually allocated, when MPIDI_CH3I_Seg_commit() is
62   called, the pointer *ptr_p will be set to point to the reserved
63   region in the shared memory segment.
64
65   Note that no shared memory is actually allocated by this function,
66   and the *ptr_p pointer will be valid only after
67   MPIDI_CH3I_Seg_commit() is called.
68*/
69#undef FUNCNAME
70#define FUNCNAME MPIDI_CH3I_Seg_alloc
71#undef FCNAME
72#define FCNAME MPIDI_QUOTE(FUNCNAME)
73int MPIDI_CH3I_Seg_alloc(size_t len, void **ptr_p)
74{
75    int mpi_errno = MPI_SUCCESS;
76    alloc_elem_t *ep;
77    MPIU_CHKPMEM_DECL(1);
78    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SEG_ALLOC);
79
80    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEG_ALLOC);
81
82    /* round up to multiple of 8 to ensure the start of the next
83       region is 64-bit aligned. */
84    len = ROUND_UP_8(len);
85
86    MPIU_Assert(len);
87    MPIU_Assert(ptr_p);
88
89    MPIU_CHKPMEM_MALLOC(ep, alloc_elem_t *, sizeof(alloc_elem_t), mpi_errno, "el");
90   
91    ep->ptr_p = ptr_p;
92    ep->len = len;
93
94    ALLOCQ_ENQUEUE(ep);
95
96    segment_len += len;
97   
98 fn_exit:
99    MPIU_CHKPMEM_COMMIT();
100    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEG_ALLOC);
101    return mpi_errno;
102 fn_fail:
103    MPIU_CHKPMEM_REAP();
104    goto fn_exit;
105}
106
107/* MPIDI_CH3I_Seg_commit(memory, num_local, local_rank)
108
109   This function allocates a shared memory segment large enough to
110   hold all of the regions previously requested by calls to
111   MPIDI_CH3I_Seg_alloc().  For each request, this function sets the
112   associated pointer to point to the reserved region in the allocated
113   shared memory segment.
114
115   If there is only one process local to this node, then a shared
116   memory region is not allocated.  Instead, memory is allocated from
117   the heap.
118
119   At least one call to MPIDI_CH3I_Seg_alloc() must be made before
120   calling MPIDI_CH3I_Seg_commit().
121 */
122#undef FUNCNAME
123#define FUNCNAME MPIDI_CH3I_Seg_commit
124#undef FCNAME
125#define FCNAME MPIDI_QUOTE(FUNCNAME)
126int MPIDI_CH3I_Seg_commit(MPID_nem_seg_ptr_t memory, int num_local, int local_rank)
127{
128    int mpi_errno = MPI_SUCCESS;
129    int pmi_errno;
130#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
131    int ret;
132    int ipc_lock_offset;
133    pthread_mutex_t *ipc_lock;
134#endif
135    int key_max_sz;
136    int val_max_sz;
137    char *key;
138    char *val;
139    char *kvs_name;
140    char *serialized_hnd = NULL;
141    void *current_addr;
142    void *start_addr;
143    size_t size_left;
144    MPIU_CHKPMEM_DECL (1);
145    MPIU_CHKLMEM_DECL (2);
146    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SEG_COMMIT);
147
148    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEG_COMMIT);
149
150    /* MPIDI_CH3I_Seg_alloc() needs to have been called before this function */
151    MPIU_Assert(!ALLOCQ_EMPTY());
152    MPIU_Assert(segment_len > 0);
153
154    /* allocate an area to check if the segment was allocated symmetrically */
155    mpi_errno = MPIDI_CH3I_Seg_alloc(sizeof(asym_check_region), (void **)&asym_check_region_p);
156    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
157
158    mpi_errno = MPIU_SHMW_Hnd_init(&(memory->hnd));
159    if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP (mpi_errno);
160
161    /* Shared memory barrier variables are in the front of the shared
162       memory region.  We do this here explicitly, rather than use the
163       Seg_alloc() function because we need to use the barrier inside
164       this function, before we've assigned the variables to their
165       regions.  To do this, we add extra space to the segment_len,
166       initialize the variables as soon as the shared memory region is
167       allocated/attached, then before we do the assignments of the
168       pointers provided in Seg_alloc(), we make sure to skip the
169       region containing the barrier vars. */
170   
171    /* add space for local barrier region.  Use a whole cacheline. */
172    MPIU_Assert(MPID_NEM_CACHE_LINE_LEN >= sizeof(MPID_nem_barrier_t));
173    segment_len += MPID_NEM_CACHE_LINE_LEN;
174
175#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
176    /* We have a similar bootstrapping problem when using OpenPA in
177     * lock-based emulation mode.  We use OPA_* functions during the
178     * check_alloc function but we were previously initializing OpenPA
179     * after return from this function.  So we put the emulation lock
180     * right after the barrier var space. */
181
182    /* offset from memory->base_addr to the start of ipc_lock */
183    ipc_lock_offset = MPID_NEM_CACHE_LINE_LEN;
184
185    MPIU_Assert(ipc_lock_offset >= sizeof(pthread_mutex_t));
186    segment_len += MPID_NEM_CACHE_LINE_LEN;
187#endif
188
189    memory->segment_len = segment_len;
190
191#ifdef USE_PMI2_API
192    /* if there is only one process on this processor, don't use shared memory */
193    if (num_local == 1)
194    {
195        char *addr;
196
197        MPIU_CHKPMEM_MALLOC (addr, char *, segment_len + MPID_NEM_CACHE_LINE_LEN, mpi_errno, "segment");
198
199        memory->base_addr = addr;
200        current_addr = (char *)(((MPIR_Upint)addr + (MPIR_Upint)MPID_NEM_CACHE_LINE_LEN-1) & (~((MPIR_Upint)MPID_NEM_CACHE_LINE_LEN-1)));
201        memory->symmetrical = 0;
202
203        /* must come before barrier_init since we use OPA in that function */
204#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
205        ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
206        ret = OPA_Interprocess_lock_init(ipc_lock, TRUE/*isLeader*/);
207        MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
208#endif
209
210        mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, TRUE);
211        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
212    }
213    else {
214
215        if (local_rank == 0) {
216            mpi_errno = MPIU_SHMW_Seg_create_and_attach(memory->hnd, memory->segment_len, &(memory->base_addr), 0);
217            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
218
219            /* post name of shared file */
220            MPIU_Assert (MPID_nem_mem_region.local_procs[0] == MPID_nem_mem_region.rank);
221
222            mpi_errno = MPIU_SHMW_Hnd_get_serialized_by_ref(memory->hnd, &serialized_hnd);
223            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
224
225            /* must come before barrier_init since we use OPA in that function */
226#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
227            ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
228            ret = OPA_Interprocess_lock_init(ipc_lock, local_rank == 0);
229            MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
230#endif
231
232            mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, TRUE);
233            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
234
235            /* The opa and nem barrier initializations must come before we (the
236             * leader) put the sharedFilename attribute.  Since this is a
237             * serializing operation with our peers on the local node this
238             * ensures that these initializations have occurred before any peer
239             * attempts to use the resources. */
240            mpi_errno = PMI_Info_PutNodeAttr("sharedFilename", serialized_hnd);
241            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
242        } else {
243            int found = FALSE;
244
245            /* Allocate space for pmi key and val */
246            MPIU_CHKLMEM_MALLOC(val, char *, PMI_MAX_VALLEN, mpi_errno, "val");
247
248            /* get name of shared file */
249            mpi_errno = PMI_Info_GetNodeAttr("sharedFilename", val, PMI_MAX_VALLEN, &found, TRUE);
250            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
251            MPIU_ERR_CHKANDJUMP1(!found, mpi_errno, MPI_ERR_OTHER, "**intern", "**intern %s", "nodeattr not found");
252
253            mpi_errno = MPIU_SHMW_Hnd_deserialize(memory->hnd, val, strlen(val));
254            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
255
256            mpi_errno = MPIU_SHMW_Seg_attach(memory->hnd, memory->segment_len, (char **)&memory->base_addr, 0);
257            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
258
259            /* must come before barrier_init since we use OPA in that function */
260#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
261            ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
262            ret = OPA_Interprocess_lock_init(ipc_lock, local_rank == 0);
263            MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
264
265            /* Right now we rely on the assumption that OPA_Interprocess_lock_init only
266             * needs to be called by the leader and the current process before use by the
267             * current process.  That is, we don't assume that this collective call is
268             * synchronizing and we don't assume that it requires total external
269             * synchronization.  In PMIv2 we don't have a PMI_Barrier operation so we need
270             * this behavior. */
271#endif
272
273            mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, FALSE);
274            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
275        }
276
277        mpi_errno = MPID_nem_barrier(num_local, local_rank);
278        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
279
280        if (local_rank == 0) {
281            mpi_errno = MPIU_SHMW_Seg_remove(memory->hnd);
282            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
283        }
284        current_addr = memory->base_addr;
285        memory->symmetrical = 0 ;
286    }
287#else /* we are using PMIv1 */
288    /* if there is only one process on this processor, don't use shared memory */
289    if (num_local == 1)
290    {
291        char *addr;
292
293        MPIU_CHKPMEM_MALLOC (addr, char *, segment_len + MPID_NEM_CACHE_LINE_LEN, mpi_errno, "segment");
294
295        memory->base_addr = addr;
296        current_addr = (char *)(((MPIR_Upint)addr + (MPIR_Upint)MPID_NEM_CACHE_LINE_LEN-1) & (~((MPIR_Upint)MPID_NEM_CACHE_LINE_LEN-1)));
297        memory->symmetrical = 0 ;
298
299        /* we still need to call barrier */
300        pmi_errno = PMI_Barrier();
301        MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_barrier", "**pmi_barrier %d", pmi_errno);
302
303        /* must come before barrier_init since we use OPA in that function */
304#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
305        ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
306        ret = OPA_Interprocess_lock_init(ipc_lock, TRUE/*isLeader*/);
307        MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
308#endif
309        mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, TRUE);
310        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
311    }
312    else{
313        /* Allocate space for pmi key and val */
314        pmi_errno = PMI_KVS_Get_key_length_max(&key_max_sz);
315        MPIU_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
316        MPIU_CHKLMEM_MALLOC(key, char *, key_max_sz, mpi_errno, "key");
317
318        pmi_errno = PMI_KVS_Get_value_length_max(&val_max_sz);
319        MPIU_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
320        MPIU_CHKLMEM_MALLOC(val, char *, val_max_sz, mpi_errno, "val");
321
322        mpi_errno = MPIDI_PG_GetConnKVSname (&kvs_name);
323        if (mpi_errno) MPIU_ERR_POP (mpi_errno);
324
325        if (local_rank == 0){
326            mpi_errno = MPIU_SHMW_Seg_create_and_attach(memory->hnd, memory->segment_len, &(memory->base_addr), 0);
327            if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP (mpi_errno);
328
329            /* post name of shared file */
330            MPIU_Assert (MPID_nem_mem_region.local_procs[0] == MPID_nem_mem_region.rank);
331            MPIU_Snprintf (key, key_max_sz, "sharedFilename[%i]", MPID_nem_mem_region.rank);
332
333            mpi_errno = MPIU_SHMW_Hnd_get_serialized_by_ref(memory->hnd, &serialized_hnd);
334            if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP (mpi_errno);
335
336            pmi_errno = PMI_KVS_Put (kvs_name, key, serialized_hnd);
337            MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_put", "**pmi_kvs_put %d", pmi_errno);
338
339            pmi_errno = PMI_KVS_Commit (kvs_name);
340            MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_commit", "**pmi_kvs_commit %d", pmi_errno);
341
342            /* must come before barrier_init since we use OPA in that function */
343#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
344            ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
345            ret = OPA_Interprocess_lock_init(ipc_lock, local_rank == 0);
346            MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
347#endif
348
349            mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, TRUE);
350            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
351
352            pmi_errno = PMI_Barrier();
353            MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_barrier", "**pmi_barrier %d", pmi_errno);
354        }
355        else
356        {
357            pmi_errno = PMI_Barrier();
358            MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_barrier", "**pmi_barrier %d", pmi_errno);
359
360            /* get name of shared file */
361            MPIU_Snprintf (key, key_max_sz, "sharedFilename[%i]", MPID_nem_mem_region.local_procs[0]);
362            pmi_errno = PMI_KVS_Get (kvs_name, key, val, val_max_sz);
363            MPIU_ERR_CHKANDJUMP1 (pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_get", "**pmi_kvs_get %d", pmi_errno);
364
365            mpi_errno = MPIU_SHMW_Hnd_deserialize(memory->hnd, val, strlen(val));
366            if(mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
367
368            mpi_errno = MPIU_SHMW_Seg_attach(memory->hnd, memory->segment_len, (char **)&memory->base_addr, 0);
369            if (mpi_errno) MPIU_ERR_POP (mpi_errno);
370
371            /* must come before barrier_init since we use OPA in that function */
372#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
373            ipc_lock = (pthread_mutex_t *)((char *)memory->base_addr + ipc_lock_offset);
374            ret = OPA_Interprocess_lock_init(ipc_lock, local_rank == 0);
375            MPIU_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", ret);
376#endif
377
378            mpi_errno = MPID_nem_barrier_init((MPID_nem_barrier_t *)memory->base_addr, FALSE);
379            if (mpi_errno) MPIU_ERR_POP(mpi_errno);
380        }
381
382        mpi_errno = MPID_nem_barrier(num_local, local_rank);
383        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
384   
385        if (local_rank == 0)
386        {
387            mpi_errno = MPIU_SHMW_Seg_remove(memory->hnd);
388            if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP (mpi_errno);
389        }
390        current_addr = memory->base_addr;
391        memory->symmetrical = 0 ;
392    }
393#endif
394    /* assign sections of the shared memory segment to their pointers */
395
396    start_addr = current_addr;
397    size_left = segment_len;
398
399    /* reserve room for shared mem barrier (We used a whole cacheline) */
400    current_addr = (char *)current_addr + MPID_NEM_CACHE_LINE_LEN;
401    MPIU_Assert(size_left >= MPID_NEM_CACHE_LINE_LEN);
402    size_left -= MPID_NEM_CACHE_LINE_LEN;
403
404#ifdef OPA_USE_LOCK_BASED_PRIMITIVES
405    /* reserve room for the opa emulation lock */
406    current_addr = (char *)current_addr + MPID_NEM_CACHE_LINE_LEN;
407    MPIU_Assert(size_left >= MPID_NEM_CACHE_LINE_LEN);
408    size_left -= MPID_NEM_CACHE_LINE_LEN;
409#endif
410
411    do
412    {
413        alloc_elem_t *ep;
414
415        ALLOCQ_DEQUEUE(&ep);
416
417        *(ep->ptr_p) = current_addr;
418        MPIU_Assert(size_left >= ep->len);
419        size_left -= ep->len;
420        current_addr = (char *)current_addr + ep->len;
421
422        MPIU_Free(ep);
423
424        MPIU_Assert((char *)current_addr <= (char *)start_addr + segment_len);
425    }
426    while (!ALLOCQ_EMPTY());
427
428    mpi_errno = check_alloc(num_local, local_rank);
429    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
430   
431    MPIU_CHKPMEM_COMMIT();
432 fn_exit:
433    MPIU_CHKLMEM_FREEALL();
434    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEG_COMMIT);
435    return mpi_errno;
436 fn_fail:
437    /* --BEGIN ERROR HANDLING-- */
438    MPIU_SHMW_Seg_remove(memory->hnd);
439    MPIU_SHMW_Hnd_finalize(&(memory->hnd));
440    MPIU_CHKPMEM_REAP();
441    goto fn_exit;
442    /* --END ERROR HANDLING-- */
443}
444
445/* MPIDI_CH3I_Seg_destroy() free the shared memory segment */
446#undef FUNCNAME
447#define FUNCNAME MPIDI_CH3I_Seg_destroy
448#undef FCNAME
449#define FCNAME MPIDI_QUOTE(FUNCNAME)
450int MPIDI_CH3I_Seg_destroy()
451{
452    int mpi_errno = MPI_SUCCESS;
453    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SEG_DESTROY);
454
455    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEG_DESTROY);
456
457    if (MPID_nem_mem_region.num_local == 1)
458        MPIU_Free(MPID_nem_mem_region.memory.base_addr);
459    else
460    {
461        mpi_errno = MPIU_SHMW_Seg_detach(MPID_nem_mem_region.memory.hnd, 
462                        &(MPID_nem_mem_region.memory.base_addr), MPID_nem_mem_region.memory.segment_len);
463        if (mpi_errno) MPIU_ERR_POP (mpi_errno);
464    }
465
466 fn_exit:
467    MPIU_SHMW_Hnd_finalize(&(MPID_nem_mem_region.memory.hnd));
468    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEG_DESTROY);
469    return mpi_errno;
470 fn_fail:
471    goto fn_exit;
472}
473
474/* check_alloc() checks to see whether the shared memory segment is
475   allocated at the same virtual memory address at each process.
476*/
477#undef FUNCNAME
478#define FUNCNAME check_alloc
479#undef FCNAME
480#define FCNAME MPIDI_QUOTE(FUNCNAME)
481static int check_alloc(int num_local, int local_rank)
482{
483    int mpi_errno = MPI_SUCCESS;
484    MPIDI_STATE_DECL(MPID_STATE_CHECK_ALLOC);
485
486    MPIDI_FUNC_ENTER(MPID_STATE_CHECK_ALLOC);
487
488    if (local_rank == 0) {
489        asym_check_region_p->base_ptr = MPID_nem_mem_region.memory.base_addr;
490        OPA_store_int(&asym_check_region_p->is_asym, 0);
491    }
492
493    mpi_errno = MPID_nem_barrier(num_local, local_rank);
494    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
495
496    if (asym_check_region_p->base_ptr != MPID_nem_mem_region.memory.base_addr)
497        OPA_store_int(&asym_check_region_p->is_asym, 1);
498
499    OPA_read_write_barrier();
500
501    mpi_errno = MPID_nem_barrier(num_local, local_rank);
502    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
503
504    if (OPA_load_int(&asym_check_region_p->is_asym))
505    {
506        MPID_nem_mem_region.memory.symmetrical = 0;
507        MPID_nem_asymm_base_addr = MPID_nem_mem_region.memory.base_addr;
508#ifdef MPID_NEM_SYMMETRIC_QUEUES
509        MPIU_ERR_SETFATALANDJUMP1(mpi_errno, MPI_ERR_INTERN, "**intern", "**intern %s", "queues are not symmetrically allocated as expected");
510#endif
511    }
512    else
513    {
514        MPID_nem_mem_region.memory.symmetrical = 1;
515        MPID_nem_asymm_base_addr = NULL;
516    }
517     
518 fn_exit:
519    MPIDI_FUNC_EXIT(MPID_STATE_CHECK_ALLOC);
520    return mpi_errno;
521 fn_fail:
522    goto fn_exit;
523}
Note: See TracBrowser for help on using the browser.