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 {
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 {
93  ABTI_UB_ASSERT(rwlock);
94 
95  ABT_rwlock h_rwlock = *rwlock;
96  ABTI_rwlock *p_rwlock = ABTI_rwlock_get_ptr(h_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 {
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 &
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 {
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 &
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 {
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 }
ABTI_mutex_lock
static void ABTI_mutex_lock(ABTI_local **pp_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:99
ABTI_cond_fini
static void ABTI_cond_fini(ABTI_cond *p_cond)
Definition: abti_cond.h:20
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:136
ABTI_rwlock::reader_count
size_t reader_count
Definition: abti.h:492
ABT_rwlock_free
int ABT_rwlock_free(ABT_rwlock *rwlock)
Free a readers-writer lock.
Definition: rwlock.c:90
ABTI_xstream::type
ABTI_xstream_type type
Definition: abti.h:300
ABTI_THREAD_TYPE_YIELDABLE
#define ABTI_THREAD_TYPE_YIELDABLE
Definition: abti.h:87
ABT_rwlock_rdlock
int ABT_rwlock_rdlock(ABT_rwlock rwlock)
Lock a readers-writer lock as a reader.
Definition: rwlock.c:144
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTI_xstream
Definition: abti.h:294
ABTI_mutex_unlock
static void ABTI_mutex_unlock(ABTI_local *p_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:187
ABTI_CHECK_NULL_RWLOCK_PTR
#define ABTI_CHECK_NULL_RWLOCK_PTR(p)
Definition: abti_error.h:301
abti.h
ABTI_rwlock::write_flag
int write_flag
Definition: abti.h:493
ABTI_rwlock
Definition: abti.h:489
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABTI_rwlock::cond
ABTI_cond cond
Definition: abti.h:491
ABTI_initialized
ABT_bool ABTI_initialized(void)
Definition: global.c:187
ABTI_local_get_local
static ABTI_local * ABTI_local_get_local(void)
Definition: abti_local.h:41
ABTI_cond_init
static void ABTI_cond_init(ABTI_cond *p_cond)
Definition: abti_cond.h:13
ABTI_rwlock_get_ptr
static ABTI_rwlock * ABTI_rwlock_get_ptr(ABT_rwlock rwlock)
Definition: abti_rwlock.h:14
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABTI_cond_wait
static ABTU_ret_err int ABTI_cond_wait(ABTI_local **pp_local, ABTI_cond *p_cond, ABTI_mutex *p_mutex)
Definition: abti_cond.h:60
ABT_ERR_RWLOCK
#define ABT_ERR_RWLOCK
Error code: error related to a readers-writer lock.
Definition: abt.h:345
ABTI_UB_ASSERT
#define ABTI_UB_ASSERT(cond)
Definition: abti_error.h:19
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
ABTI_rwlock::mutex
ABTI_mutex mutex
Definition: abti.h:490
ABT_rwlock_unlock
int ABT_rwlock_unlock(ABT_rwlock rwlock)
Unlock a readers-writer lock.
Definition: rwlock.c:263
ABTI_local
struct ABTI_local ABTI_local
Definition: abti.h:132
ABTI_cond_broadcast
static void ABTI_cond_broadcast(ABTI_local *p_local, ABTI_cond *p_cond)
Definition: abti_cond.h:81
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:146
ABTI_mutex_init
static void ABTI_mutex_init(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:39
ABT_rwlock_create
int ABT_rwlock_create(ABT_rwlock *newrwlock)
Create a new readers-writer lock.
Definition: rwlock.c:40
ABTI_local_get_xstream
static ABTI_xstream * ABTI_local_get_xstream(ABTI_local *p_local)
Definition: abti_local.h:86
ABT_rwlock
struct ABT_rwlock_opaque * ABT_rwlock
Readers-writer lock handle type.
Definition: abt.h:1008
ABTI_rwlock_get_handle
static ABT_rwlock ABTI_rwlock_get_handle(ABTI_rwlock *p_rwlock)
Definition: abti_rwlock.h:29