ARGOBOTS  36a41b57298ad4e16b5ada8c95c81f00dfed4d3c
rwlock.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 
41 {
42  ABTI_UB_ASSERT(ABTI_initialized());
43  ABTI_UB_ASSERT(newrwlock);
44 
45 #ifndef ABT_CONFIG_ENABLE_VER_20_API
46  /* Argobots 1.x sets newrwlock to NULL on error. */
47  *newrwlock = ABT_RWLOCK_NULL;
48 #endif
49  ABTI_rwlock *p_newrwlock;
50 
51  int abt_errno = ABTU_malloc(sizeof(ABTI_rwlock), (void **)&p_newrwlock);
52  ABTI_CHECK_ERROR(abt_errno);
53 
54  ABTI_mutex_init(&p_newrwlock->mutex);
55  ABTI_cond_init(&p_newrwlock->cond);
56  p_newrwlock->reader_count = 0;
57  p_newrwlock->write_flag = 0;
58 
59  /* Return value */
60  *newrwlock = ABTI_rwlock_get_handle(p_newrwlock);
61  return ABT_SUCCESS;
62 }
63 
91 {
92  ABTI_UB_ASSERT(ABTI_initialized());
93  ABTI_UB_ASSERT(rwlock);
94 
95  ABT_rwlock h_rwlock = *rwlock;
96  ABTI_rwlock *p_rwlock = ABTI_rwlock_get_ptr(h_rwlock);
97  ABTI_CHECK_NULL_RWLOCK_PTR(p_rwlock);
98 
99  ABTI_cond_fini(&p_rwlock->cond);
100  ABTU_free(p_rwlock);
101 
102  /* Return value */
103  *rwlock = ABT_RWLOCK_NULL;
104  return ABT_SUCCESS;
105 }
106 
145 {
146  ABTI_UB_ASSERT(ABTI_initialized());
147 
148  ABTI_local *p_local = ABTI_local_get_local();
149  ABTI_rwlock *p_rwlock = ABTI_rwlock_get_ptr(rwlock);
150  ABTI_CHECK_NULL_RWLOCK_PTR(p_rwlock);
151 
152 #ifndef ABT_CONFIG_ENABLE_VER_20_API
153  /* Calling this routine on a tasklet is not allowed. */
154  if (ABTI_IS_ERROR_CHECK_ENABLED && p_local) {
155  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
156  ABTI_CHECK_TRUE(p_local_xstream->p_thread->type &
157  ABTI_THREAD_TYPE_YIELDABLE,
159  }
160 #endif
161 
162  ABTI_mutex_lock(&p_local, &p_rwlock->mutex);
163  int abt_errno = ABT_SUCCESS;
164  while (p_rwlock->write_flag && abt_errno == ABT_SUCCESS) {
165  abt_errno = ABTI_cond_wait(&p_local, &p_rwlock->cond, &p_rwlock->mutex);
166  }
167  if (abt_errno == ABT_SUCCESS) {
168  p_rwlock->reader_count++;
169  }
170  ABTI_mutex_unlock(p_local, &p_rwlock->mutex);
171  ABTI_CHECK_ERROR(abt_errno);
172  return ABT_SUCCESS;
173 }
174 
208 {
209  ABTI_UB_ASSERT(ABTI_initialized());
210 
211  ABTI_local *p_local = ABTI_local_get_local();
212  ABTI_rwlock *p_rwlock = ABTI_rwlock_get_ptr(rwlock);
213  ABTI_CHECK_NULL_RWLOCK_PTR(p_rwlock);
214 
215 #ifndef ABT_CONFIG_ENABLE_VER_20_API
216  /* Calling this routine on a tasklet is not allowed. */
217  if (ABTI_IS_ERROR_CHECK_ENABLED && p_local) {
218  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
219  ABTI_CHECK_TRUE(p_local_xstream->p_thread->type &
220  ABTI_THREAD_TYPE_YIELDABLE,
222  }
223 #endif
224 
225  ABTI_mutex_lock(&p_local, &p_rwlock->mutex);
226  int abt_errno = ABT_SUCCESS;
227  while ((p_rwlock->write_flag || p_rwlock->reader_count) &&
228  abt_errno == ABT_SUCCESS) {
229  abt_errno = ABTI_cond_wait(&p_local, &p_rwlock->cond, &p_rwlock->mutex);
230  }
231  if (abt_errno == ABT_SUCCESS) {
232  p_rwlock->write_flag = 1;
233  }
234  ABTI_mutex_unlock(p_local, &p_rwlock->mutex);
235  ABTI_CHECK_ERROR(abt_errno);
236  return ABT_SUCCESS;
237 }
238 
264 {
265  ABTI_UB_ASSERT(ABTI_initialized());
266 
267  ABTI_local *p_local = ABTI_local_get_local();
268  ABTI_rwlock *p_rwlock = ABTI_rwlock_get_ptr(rwlock);
269  ABTI_CHECK_NULL_RWLOCK_PTR(p_rwlock);
270 
271  ABTI_mutex_lock(&p_local, &p_rwlock->mutex);
272  if (p_rwlock->write_flag) {
273  p_rwlock->write_flag = 0;
274  } else {
275  ABTI_UB_ASSERT(p_rwlock->reader_count > 0);
276  p_rwlock->reader_count--;
277  }
278  ABTI_cond_broadcast(p_local, &p_rwlock->cond);
279  ABTI_mutex_unlock(p_local, &p_rwlock->mutex);
280  return ABT_SUCCESS;
281 }
ABT_rwlock_free
int ABT_rwlock_free(ABT_rwlock *rwlock)
Free a readers-writer lock.
Definition: rwlock.c:90
ABT_rwlock_rdlock
int ABT_rwlock_rdlock(ABT_rwlock rwlock)
Lock a readers-writer lock as a reader.
Definition: rwlock.c:144
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_ERR_RWLOCK
#define ABT_ERR_RWLOCK
Error code: error related to a readers-writer lock.
Definition: abt.h:345
ABT_rwlock_wrlock
int ABT_rwlock_wrlock(ABT_rwlock rwlock)
Lock a readers-writer lock as a writer.
Definition: rwlock.c:207
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_RWLOCK_NULL
#define ABT_RWLOCK_NULL
Definition: abt.h:1112
ABT_rwlock_unlock
int ABT_rwlock_unlock(ABT_rwlock rwlock)
Unlock a readers-writer lock.
Definition: rwlock.c:263
ABT_rwlock_create
int ABT_rwlock_create(ABT_rwlock *newrwlock)
Create a new readers-writer lock.
Definition: rwlock.c:40
ABT_rwlock
struct ABT_rwlock_opaque * ABT_rwlock
Readers-writer lock handle type.
Definition: abt.h:1008