OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

btl_vader_fifo.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2009 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2006-2007 Voltaire. All rights reserved.
14 * Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved.
15 * Copyright (c) 2010-2012 Los Alamos National Security, LLC.
16 * All rights reserved.
17 * $COPYRIGHT$
18 *
19 * Additional copyrights may follow
20 *
21 * $HEADER$
22 */
23 /**
24 * @file
25 */
26 #ifndef MCA_BTL_VADER_FIFO_H
27 #define MCA_BTL_VADER_FIFO_H
28
29 #include "btl_vader.h"
30 #include "btl_vader_endpoint.h"
31 #include "btl_vader_frag.h"
32
33 #define VADER_FIFO_FREE ((intptr_t)-2)
34
35 /*
36 * Shared Memory FIFOs
37 *
38 * The FIFO is implemented as a linked list of frag headers. The fifo has multiple
39 * producers and a single consumer (in the single thread case) so the tail needs
40 * to be modified by an atomic or protected by a atomic lock.
41 *
42 * Since the frags live in shared memory that is mapped differently into
43 * each address space, the head and tail pointers are relative (each process must
44 * add its own offset).
45 *
46 * We introduce some padding at the end of the structure but it is probably unnecessary.
47 */
48
49 /* lock free fifo */
50 typedef struct vader_fifo_t {
51 volatile intptr_t fifo_head;
52 volatile intptr_t fifo_tail;
53 char pad[VADER_CACHE_LINE_PAD - 2 * sizeof (intptr_t)];
54 } vader_fifo_t;
55
56 static inline int vader_fifo_init (vader_fifo_t *fifo)
57 {
58 fifo->fifo_head = fifo->fifo_tail = VADER_FIFO_FREE;
59
60 return OMPI_SUCCESS;
61 }
62
63 static inline void vader_fifo_write (mca_btl_vader_hdr_t *hdr, int rank)
64 {
65 vader_fifo_t *fifo = mca_btl_vader_component.fifo[rank];
66 intptr_t prev, value = VIRTUAL2RELATIVE(hdr);
67
68 hdr->next = VADER_FIFO_FREE;
69
70 opal_atomic_wmb ();
71 prev = opal_atomic_swap_ptr (&fifo->fifo_tail, value);
72 opal_atomic_rmb ();
73
74 if (OPAL_LIKELY(VADER_FIFO_FREE != prev)) {
75 hdr = (mca_btl_vader_hdr_t *) RELATIVE2VIRTUAL(prev);
76 hdr->next = value;
77 } else {
78 fifo->fifo_head = value;
79 }
80
81 opal_atomic_wmb ();
82 }
83
84 static inline mca_btl_vader_hdr_t *vader_fifo_read (vader_fifo_t *fifo)
85 {
86 mca_btl_vader_hdr_t *hdr;
87 intptr_t value;
88
89 opal_atomic_rmb ();
90
91 value = opal_atomic_swap_ptr (&fifo->fifo_head, VADER_FIFO_FREE);
92 if (VADER_FIFO_FREE == value) {
93 /* fifo is empty or we lost the race with another thread */
94 return NULL;
95 }
96
97 hdr = (mca_btl_vader_hdr_t *) RELATIVE2VIRTUAL(value);
98
99 if (OPAL_UNLIKELY(VADER_FIFO_FREE == hdr->next)) {
100 opal_atomic_rmb();
101
102 if (!opal_atomic_cmpset_ptr (&fifo->fifo_tail, (void *)value,
103 (void *)VADER_FIFO_FREE)) {
104 while (VADER_FIFO_FREE == hdr->next) {
105 opal_atomic_rmb ();
106 }
107
108 fifo->fifo_head = hdr->next;
109 }
110 } else {
111 fifo->fifo_head = hdr->next;
112 }
113
114 opal_atomic_wmb ();
115
116 return hdr;
117 }
118
119 #endif /* MCA_BTL_VADER_FIFO_H */
btl_vader_endpoint.h
opal_atomic_rmb
void opal_atomic_rmb(void)
Read memory barrier.
btl_vader.h
mca_btl_vader_hdr_t
Definition: btl_vader_frag.h:33
mca_btl_vader_component_t::fifo
struct vader_fifo_t ** fifo
cached copy of the pointer to the 2D fifo array.
Definition: btl_vader.h:106
opal_atomic_wmb
void opal_atomic_wmb(void)
Write memory barrier.
vader_fifo_t
Definition: btl_vader_fifo.h:50