ARGOBOTS  36a41b57298ad4e16b5ada8c95c81f00dfed4d3c
stream_barrier.c
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #include "abti.h"
7 
44 int ABT_xstream_barrier_create(uint32_t num_waiters,
45  ABT_xstream_barrier *newbarrier)
46 {
47  ABTI_UB_ASSERT(ABTI_initialized());
48  ABTI_UB_ASSERT(newbarrier);
49 
50 #ifndef ABT_CONFIG_ENABLE_VER_20_API
51  /* Argobots 1.x sets newbarrier to NULL on error. */
52  *newbarrier = ABT_XSTREAM_BARRIER_NULL;
53 #endif
54  int abt_errno;
55  ABTI_xstream_barrier *p_newbarrier;
56  ABTI_CHECK_TRUE(num_waiters != 0, ABT_ERR_INV_ARG);
57 
58  abt_errno =
59  ABTU_malloc(sizeof(ABTI_xstream_barrier), (void **)&p_newbarrier);
60  ABTI_CHECK_ERROR(abt_errno);
61 
62  p_newbarrier->num_waiters = num_waiters;
63 #ifdef HAVE_PTHREAD_BARRIER_INIT
64  abt_errno = ABTD_xstream_barrier_init(num_waiters, &p_newbarrier->bar);
65  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
66  ABTU_free(p_newbarrier);
67  ABTI_HANDLE_ERROR(abt_errno);
68  }
69 #else
70  ABTD_spinlock_clear(&p_newbarrier->lock);
71  p_newbarrier->counter = 0;
72  ABTD_atomic_relaxed_store_uint64(&p_newbarrier->tag, 0);
73 #endif
74 
75  /* Return value */
76  *newbarrier = ABTI_xstream_barrier_get_handle(p_newbarrier);
77  return ABT_SUCCESS;
78 }
79 
105 {
106  ABTI_UB_ASSERT(ABTI_initialized());
107  ABTI_UB_ASSERT(barrier);
108 
109  ABT_xstream_barrier h_barrier = *barrier;
110  ABTI_xstream_barrier *p_barrier = ABTI_xstream_barrier_get_ptr(h_barrier);
111  ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR(p_barrier);
112 
113 #ifdef HAVE_PTHREAD_BARRIER_INIT
114  ABTD_xstream_barrier_destroy(&p_barrier->bar);
115 #endif
116  ABTU_free(p_barrier);
117 
118  /* Return value */
119  *barrier = ABT_XSTREAM_BARRIER_NULL;
120  return ABT_SUCCESS;
121 }
122 
147 {
148  ABTI_UB_ASSERT(ABTI_initialized());
149 
150  ABTI_xstream_barrier *p_barrier = ABTI_xstream_barrier_get_ptr(barrier);
151  ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR(p_barrier);
152 
153  if (p_barrier->num_waiters > 1) {
154 #ifdef HAVE_PTHREAD_BARRIER_INIT
155  ABTD_xstream_barrier_wait(&p_barrier->bar);
156 #else
157  /* The following implementation is a simple sense-reversal barrier
158  * implementation while it uses uint64_t instead of boolean to prevent
159  * a sense variable from wrapping around. */
160  ABTD_spinlock_acquire(&p_barrier->lock);
161  p_barrier->counter++;
162  if (p_barrier->counter == p_barrier->num_waiters) {
163  /* Wake up the other waiters. */
164  p_barrier->counter = 0;
165  /* Updating tag wakes up other waiters. Note that this tag is
166  * sufficiently large, so it will not wrap around. */
167  uint64_t cur_tag = ABTD_atomic_relaxed_load_uint64(&p_barrier->tag);
168  uint64_t new_tag = (cur_tag + 1) & (UINT64_MAX >> 1);
169  ABTD_atomic_release_store_uint64(&p_barrier->tag, new_tag);
170  ABTD_spinlock_release(&p_barrier->lock);
171  } else {
172  /* Wait until the tag is updated by the last waiter */
173  uint64_t cur_tag = ABTD_atomic_relaxed_load_uint64(&p_barrier->tag);
174  ABTD_spinlock_release(&p_barrier->lock);
175  while (cur_tag == ABTD_atomic_acquire_load_uint64(&p_barrier->tag))
176  ABTD_atomic_pause();
177  }
178 #endif
179  }
180  return ABT_SUCCESS;
181 }
ABT_xstream_barrier_free
int ABT_xstream_barrier_free(ABT_xstream_barrier *barrier)
Free an execution-stream barrier.
Definition: stream_barrier.c:104
ABT_xstream_barrier_wait
int ABT_xstream_barrier_wait(ABT_xstream_barrier barrier)
Wait on an execution-stream barrier.
Definition: stream_barrier.c:146
abti.h
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABT_XSTREAM_BARRIER_NULL
#define ABT_XSTREAM_BARRIER_NULL
Definition: abt.h:1099
ABT_xstream_barrier
struct ABT_xstream_barrier_opaque * ABT_xstream_barrier
Execution-stream barrier handle type.
Definition: abt.h:838
ABT_ERR_INV_ARG
#define ABT_ERR_INV_ARG
Error code: invalid user argument.
Definition: abt.h:260
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_xstream_barrier_create
int ABT_xstream_barrier_create(uint32_t num_waiters, ABT_xstream_barrier *newbarrier)
Create a new execution-stream barrier.
Definition: stream_barrier.c:44