ARGOBOTS  2d670346af9c36fec097ec5ab659205198ec061b
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 {
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 {
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);
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 {
149 
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))
177  }
178 #endif
179  }
180  return ABT_SUCCESS;
181 }
ABTD_atomic_relaxed_load_uint64
static uint64_t ABTD_atomic_relaxed_load_uint64(const ABTD_atomic_uint64 *ptr)
Definition: abtd_atomic.h:832
ABT_xstream_barrier_free
int ABT_xstream_barrier_free(ABT_xstream_barrier *barrier)
Free an execution-stream barrier.
Definition: stream_barrier.c:104
ABTD_atomic_relaxed_store_uint64
static void ABTD_atomic_relaxed_store_uint64(ABTD_atomic_uint64 *ptr, uint64_t val)
Definition: abtd_atomic.h:1045
ABTI_xstream_barrier_get_ptr
static ABTI_xstream_barrier * ABTI_xstream_barrier_get_ptr(ABT_xstream_barrier barrier)
Definition: abti_stream_barrier.h:10
ABTI_xstream_barrier
Definition: abti.h:500
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:136
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_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTD_atomic_acquire_load_uint64
static uint64_t ABTD_atomic_acquire_load_uint64(const ABTD_atomic_uint64 *ptr)
Definition: abtd_atomic.h:962
ABTI_xstream_barrier_get_handle
static ABT_xstream_barrier ABTI_xstream_barrier_get_handle(ABTI_xstream_barrier *p_barrier)
Definition: abti_stream_barrier.h:26
ABTI_xstream_barrier::num_waiters
uint32_t num_waiters
Definition: abti.h:501
ABTD_atomic_release_store_uint64
static void ABTD_atomic_release_store_uint64(ABTD_atomic_uint64 *ptr, uint64_t val)
Definition: abtd_atomic.h:1124
abti.h
ABTD_spinlock_acquire
static void ABTD_spinlock_acquire(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:28
ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR
#define ABTI_CHECK_NULL_XSTREAM_BARRIER_PTR(p)
Definition: abti_error.h:337
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:130
ABTD_atomic_pause
static void ABTD_atomic_pause(void)
Definition: abtd_atomic.h:1257
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABTI_initialized
ABT_bool ABTI_initialized(void)
Definition: global.c:187
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:1073
ABT_xstream_barrier
struct ABT_xstream_barrier_opaque * ABT_xstream_barrier
Execution-stream barrier handle type.
Definition: abt.h:812
ABTD_spinlock_clear
static void ABTD_spinlock_clear(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:23
ABTI_UB_ASSERT
#define ABTI_UB_ASSERT(cond)
Definition: abti_error.h:19
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
ABTD_spinlock_release
static void ABTD_spinlock_release(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:42
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:146
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
ABTI_xstream_barrier::bar
ABTD_xstream_barrier bar
Definition: abti.h:503