ARGOBOTS  36a41b57298ad4e16b5ada8c95c81f00dfed4d3c
cond.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 #include <sys/time.h>
8 
9 static inline double convert_timespec_to_sec(const struct timespec *p_ts);
10 
43 {
45  ABTI_UB_ASSERT(newcond);
46 
47  /* Check if the size of ABT_cond_memory is okay. */
48  ABTI_STATIC_ASSERT(sizeof(ABTI_cond) <= sizeof(ABT_cond_memory));
49 
50 #ifndef ABT_CONFIG_ENABLE_VER_20_API
51  /* Argobots 1.x sets newcond to NULL on error. */
52  *newcond = ABT_COND_NULL;
53 #endif
54  ABTI_cond *p_newcond;
55  int abt_errno = ABTU_malloc(sizeof(ABTI_cond), (void **)&p_newcond);
56  ABTI_CHECK_ERROR(abt_errno);
57 
58  ABTI_cond_init(p_newcond);
59  /* Return value */
60  *newcond = ABTI_cond_get_handle(p_newcond);
61  return ABT_SUCCESS;
62 }
63 
93 {
95  ABTI_UB_ASSERT(cond);
96 
97  ABT_cond h_cond = *cond;
98  ABTI_cond *p_cond = ABTI_cond_get_ptr(h_cond);
100 #ifndef ABT_CONFIG_ENABLE_VER_20_API
101  /* This check will be removed in Argobots 2.0 */
103 #else
105 #endif
106 
107  ABTI_cond_fini(p_cond);
108  ABTU_free(p_cond);
109  /* Return value */
110  *cond = ABT_COND_NULL;
111  return ABT_SUCCESS;
112 }
113 
160 {
161  ABTI_local *p_local = ABTI_local_get_local();
162 #ifndef ABT_CONFIG_ENABLE_VER_20_API
163  /* Argobots 1.x does not allow a tasklet to call this routine. */
164  if (ABTI_IS_ERROR_CHECK_ENABLED && p_local) {
165  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
166  ABTI_CHECK_TRUE(p_local_xstream->p_thread->type &
168  ABT_ERR_COND);
169  }
170 #endif
171  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
172  ABTI_CHECK_NULL_COND_PTR(p_cond);
173  ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex);
174  ABTI_CHECK_NULL_MUTEX_PTR(p_mutex);
175 
176  /* Check if a given mutex is valid. */
177  /* p_mutex must be locked. */
179  /* If p_mutex is recursive, the caller of this function must be an owner. */
181  p_mutex->owner_id != ABTI_self_get_thread_id(p_local)));
182  /* If p_mutex is recursive, p_mutex must not be locked more than once. */
184  p_mutex->nesting_cnt > 1));
185 
186  int abt_errno = ABTI_cond_wait(&p_local, p_cond, p_mutex);
187  ABTI_CHECK_ERROR(abt_errno);
188  return ABT_SUCCESS;
189 }
190 
246  const struct timespec *abstime)
247 {
248  ABTI_UB_ASSERT(abstime);
249 
250  ABTI_local *p_local = ABTI_local_get_local();
251  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
252  ABTI_CHECK_NULL_COND_PTR(p_cond);
253  ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex);
254  ABTI_CHECK_NULL_MUTEX_PTR(p_mutex);
255 
256  /* Check if a given mutex is valid. */
257  /* p_mutex must be locked. */
259  /* If p_mutex is recursive, the caller of this function must be an owner. */
261  p_mutex->owner_id != ABTI_self_get_thread_id(p_local)));
262  /* If p_mutex is recursive, p_mutex must not be locked more than once. */
264  p_mutex->nesting_cnt > 1));
265 
266  double tar_time = convert_timespec_to_sec(abstime);
267 
268  ABTI_thread thread;
269  thread.type = ABTI_THREAD_TYPE_EXT;
271 
272  ABTD_spinlock_acquire(&p_cond->lock);
273 
274  if (p_cond->p_waiter_mutex == NULL) {
275  p_cond->p_waiter_mutex = p_mutex;
276  } else {
277  if (p_cond->p_waiter_mutex != p_mutex) {
278  ABTD_spinlock_release(&p_cond->lock);
280  }
281  }
282 
283  /* Unlock the mutex that the calling ULT is holding */
284  ABTI_mutex_unlock(p_local, p_mutex);
285  ABT_bool is_timedout =
287  &p_cond->lock, tar_time,
289  (void *)p_cond);
290  /* Lock the mutex again */
291  ABTI_mutex_lock(&p_local, p_mutex);
292  return is_timedout ? ABT_ERR_COND_TIMEDOUT : ABT_SUCCESS;
293 }
294 
315 {
316  ABTI_local *p_local = ABTI_local_get_local();
317  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
318  ABTI_CHECK_NULL_COND_PTR(p_cond);
319 
320  ABTD_spinlock_acquire(&p_cond->lock);
321  ABTI_waitlist_signal(p_local, &p_cond->waitlist);
322  ABTD_spinlock_release(&p_cond->lock);
323 
324  return ABT_SUCCESS;
325 }
326 
347 {
348  ABTI_local *p_local = ABTI_local_get_local();
349  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
350  ABTI_CHECK_NULL_COND_PTR(p_cond);
351 
352  ABTI_cond_broadcast(p_local, p_cond);
353  return ABT_SUCCESS;
354 }
355 
356 /*****************************************************************************/
357 /* Internal static functions */
358 /*****************************************************************************/
359 
360 static inline double convert_timespec_to_sec(const struct timespec *p_ts)
361 {
362  double secs;
363  secs = ((double)p_ts->tv_sec) + 1.0e-9 * ((double)p_ts->tv_nsec);
364  return secs;
365 }
ABTI_mutex_get_ptr
static ABTI_mutex * ABTI_mutex_get_ptr(ABT_mutex mutex)
Definition: abti_mutex.h:9
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
ABTI_waitlist_wait_timedout_and_unlock
static ABT_bool ABTI_waitlist_wait_timedout_and_unlock(ABTI_local **pp_local, ABTI_waitlist *p_waitlist, ABTD_spinlock *p_lock, double target_time, ABT_sync_event_type sync_event_type, void *p_sync)
Definition: abti_waitlist.h:91
ABTI_mutex_is_locked
static ABT_bool ABTI_mutex_is_locked(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:117
ABTI_mutex_lock
static void ABTI_mutex_lock(ABTI_local **pp_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:99
ABT_cond_free
int ABT_cond_free(ABT_cond *cond)
Free a condition variable.
Definition: cond.c:92
ABT_cond_timedwait
int ABT_cond_timedwait(ABT_cond cond, ABT_mutex mutex, const struct timespec *abstime)
Wait on a condition variable with a timeout limit.
Definition: cond.c:245
ABT_COND_NULL
#define ABT_COND_NULL
Definition: abt.h:1111
ABT_ERR_COND
#define ABT_ERR_COND
Error code: error related to a condition variable.
Definition: abt.h:333
ABTI_thread::type
ABTI_thread_type type
Definition: abti.h:426
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_MUTEX_ATTR_RECURSIVE
#define ABTI_MUTEX_ATTR_RECURSIVE
Definition: abti.h:125
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_mutex
struct ABT_mutex_opaque * ABT_mutex
Mutex handle type.
Definition: abt.h:987
ABT_cond_memory
A struct that can be converted to ABT_cond.
Definition: abt.h:1216
ABTI_CHECK_NULL_COND_PTR
#define ABTI_CHECK_NULL_COND_PTR(p)
Definition: abti_error.h:292
ABTI_thread
Definition: abti.h:422
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTI_xstream
Definition: abti.h:294
ABT_ERR_INV_MUTEX
#define ABT_ERR_INV_MUTEX
Error code: invalid mutex.
Definition: abt.h:210
ABTI_THREAD_TYPE_EXT
#define ABTI_THREAD_TYPE_EXT
Definition: abti.h:82
ABTI_mutex::attrs
int attrs
Definition: abti.h:202
ABTI_mutex_unlock
static void ABTI_mutex_unlock(ABTI_local *p_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:187
ABTI_waitlist_is_empty
static ABT_bool ABTI_waitlist_is_empty(ABTI_waitlist *p_waitlist)
Definition: abti_waitlist.h:282
ABTI_cond
Definition: abti.h:483
ABTI_CHECK_NULL_MUTEX_PTR
#define ABTI_CHECK_NULL_MUTEX_PTR(p)
Definition: abti_error.h:274
ABT_THREAD_STATE_BLOCKED
@ ABT_THREAD_STATE_BLOCKED
Definition: abt.h:431
abti.h
ABTI_thread::state
ABTD_atomic_int state
Definition: abti.h:432
ABTD_spinlock_acquire
static void ABTD_spinlock_acquire(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:28
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:130
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABTD_atomic_relaxed_store_int
static void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:996
ABTI_initialized
ABT_bool ABTI_initialized(void)
Definition: global.c:187
ABTI_cond::p_waiter_mutex
ABTI_mutex * p_waiter_mutex
Definition: abti.h:485
ABT_SYNC_EVENT_TYPE_COND
@ ABT_SYNC_EVENT_TYPE_COND
Definition: abt.h:710
ABTI_local_get_local
static ABTI_local * ABTI_local_get_local(void)
Definition: abti_local.h:41
ABT_cond_create
int ABT_cond_create(ABT_cond *newcond)
Create a new condition variable.
Definition: cond.c:42
ABTI_cond_init
static void ABTI_cond_init(ABTI_cond *p_cond)
Definition: abti_cond.h:13
ABTI_STATIC_ASSERT
#define ABTI_STATIC_ASSERT(cond)
Definition: abti_error.h:35
ABTI_cond_get_handle
static ABT_cond ABTI_cond_get_handle(ABTI_cond *p_cond)
Definition: abti_cond.h:44
ABTI_mutex::nesting_cnt
int nesting_cnt
Definition: abti.h:206
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_cond_broadcast
int ABT_cond_broadcast(ABT_cond cond)
Broadcast a condition.
Definition: cond.c:346
convert_timespec_to_sec
static double convert_timespec_to_sec(const struct timespec *p_ts)
Definition: cond.c:360
ABTI_self_get_thread_id
static ABTI_thread_id ABTI_self_get_thread_id(ABTI_local *p_local)
Definition: abti_self.h:22
ABT_cond_wait
int ABT_cond_wait(ABT_cond cond, ABT_mutex mutex)
Wait on a condition variable.
Definition: cond.c:159
ABT_ERR_COND_TIMEDOUT
#define ABT_ERR_COND_TIMEDOUT
Error code: a return value when a condition variable is timed out.
Definition: abt.h:340
ABTI_UB_ASSERT
#define ABTI_UB_ASSERT(cond)
Definition: abti_error.h:19
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_cond::lock
ABTD_spinlock lock
Definition: abti.h:484
ABT_cond
struct ABT_cond_opaque * ABT_cond
Condition variable handle type.
Definition: abt.h:1001
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_waitlist_signal
static void ABTI_waitlist_signal(ABTI_local *p_local, ABTI_waitlist *p_waitlist)
Definition: abti_waitlist.h:216
ABTI_local_get_xstream
static ABTI_xstream * ABTI_local_get_xstream(ABTI_local *p_local)
Definition: abti_local.h:86
ABTI_cond_get_ptr
static ABTI_cond * ABTI_cond_get_ptr(ABT_cond cond)
Definition: abti_cond.h:29
ABTI_cond::waitlist
ABTI_waitlist waitlist
Definition: abti.h:486
ABT_cond_signal
int ABT_cond_signal(ABT_cond cond)
Signal a condition.
Definition: cond.c:314
ABTI_mutex::owner_id
ABTI_thread_id owner_id
Definition: abti.h:207
ABTI_mutex
Definition: abti.h:201