ARGOBOTS  7a09f9f632d87ed4f43aec50889983fa897fba10
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 #ifndef ABT_CONFIG_ENABLE_VER_20_API
48  /* Argobots 1.x sets newbarrier to NULL on error. */
49  *newbarrier = ABT_XSTREAM_BARRIER_NULL;
50 #endif
51  int abt_errno;
52  ABTI_xstream_barrier *p_newbarrier;
53  ABTI_CHECK_TRUE(num_waiters != 0, ABT_ERR_INV_ARG);
54 
55  abt_errno =
56  ABTU_malloc(sizeof(ABTI_xstream_barrier), (void **)&p_newbarrier);
57  ABTI_CHECK_ERROR(abt_errno);
58 
59  p_newbarrier->num_waiters = num_waiters;
60 #ifdef HAVE_PTHREAD_BARRIER_INIT
61  abt_errno = ABTD_xstream_barrier_init(num_waiters, &p_newbarrier->bar);
62  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
63  ABTU_free(p_newbarrier);
64  ABTI_HANDLE_ERROR(abt_errno);
65  }
66 #else
67  ABTD_spinlock_clear(&p_newbarrier->lock);
68  p_newbarrier->counter = 0;
69  ABTD_atomic_relaxed_store_uint64(&p_newbarrier->tag, 0);
70 #endif
71 
72  /* Return value */
73  *newbarrier = ABTI_xstream_barrier_get_handle(p_newbarrier);
74  return ABT_SUCCESS;
75 }
76 
102 {
103  ABT_xstream_barrier h_barrier = *barrier;
104  ABTI_xstream_barrier *p_barrier = ABTI_xstream_barrier_get_ptr(h_barrier);
105  ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR(p_barrier);
106 
107 #ifdef HAVE_PTHREAD_BARRIER_INIT
108  ABTD_xstream_barrier_destroy(&p_barrier->bar);
109 #endif
110  ABTU_free(p_barrier);
111 
112  /* Return value */
113  *barrier = ABT_XSTREAM_BARRIER_NULL;
114  return ABT_SUCCESS;
115 }
116 
141 {
142  ABTI_xstream_barrier *p_barrier = ABTI_xstream_barrier_get_ptr(barrier);
143  ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR(p_barrier);
144 
145  if (p_barrier->num_waiters > 1) {
146 #ifdef HAVE_PTHREAD_BARRIER_INIT
147  ABTD_xstream_barrier_wait(&p_barrier->bar);
148 #else
149  /* The following implementation is a simple sense-reversal barrier
150  * implementation while it uses uint64_t instead of boolean to prevent
151  * a sense variable from wrapping around. */
152  ABTD_spinlock_acquire(&p_barrier->lock);
153  p_barrier->counter++;
154  if (p_barrier->counter == p_barrier->num_waiters) {
155  /* Wake up the other waiters. */
156  p_barrier->counter = 0;
157  /* Updating tag wakes up other waiters. Note that this tag is
158  * sufficiently large, so it will not wrap around. */
159  uint64_t cur_tag = ABTD_atomic_relaxed_load_uint64(&p_barrier->tag);
160  uint64_t new_tag = (cur_tag + 1) & (UINT64_MAX >> 1);
161  ABTD_atomic_release_store_uint64(&p_barrier->tag, new_tag);
162  ABTD_spinlock_release(&p_barrier->lock);
163  } else {
164  /* Wait until the tag is updated by the last waiter */
165  uint64_t cur_tag = ABTD_atomic_relaxed_load_uint64(&p_barrier->tag);
166  ABTD_spinlock_release(&p_barrier->lock);
167  while (cur_tag == ABTD_atomic_acquire_load_uint64(&p_barrier->tag))
168  ABTD_atomic_pause();
169  }
170 #endif
171  }
172  return ABT_SUCCESS;
173 }
ABT_xstream_barrier_free
int ABT_xstream_barrier_free(ABT_xstream_barrier *barrier)
Free an execution-stream barrier.
Definition: stream_barrier.c:101
ABT_xstream_barrier_wait
int ABT_xstream_barrier_wait(ABT_xstream_barrier barrier)
Wait on an execution-stream barrier.
Definition: stream_barrier.c:140
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:1056
ABT_xstream_barrier
struct ABT_xstream_barrier_opaque * ABT_xstream_barrier
Execution-stream barrier handle type.
Definition: abt.h:801
ABT_ERR_INV_ARG
#define ABT_ERR_INV_ARG
Error code: invalid user argument.
Definition: abt.h:250
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