ARGOBOTS  1.1
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 {
44  /* Check if the size of ABT_cond_memory is okay. */
45  ABTI_STATIC_ASSERT(sizeof(ABTI_cond) <= sizeof(ABT_cond_memory));
46 
47 #ifndef ABT_CONFIG_ENABLE_VER_20_API
48  /* Argobots 1.x sets newcond to NULL on error. */
49  *newcond = ABT_COND_NULL;
50 #endif
51  ABTI_cond *p_newcond;
52  int abt_errno = ABTU_malloc(sizeof(ABTI_cond), (void **)&p_newcond);
53  ABTI_CHECK_ERROR(abt_errno);
54 
55  ABTI_cond_init(p_newcond);
56  /* Return value */
57  *newcond = ABTI_cond_get_handle(p_newcond);
58  return ABT_SUCCESS;
59 }
60 
90 {
91  ABT_cond h_cond = *cond;
92  ABTI_cond *p_cond = ABTI_cond_get_ptr(h_cond);
94 #ifndef ABT_CONFIG_ENABLE_VER_20_API
95  /* This check will be removed in Argobots 2.0 */
97 #endif
98 
99  ABTI_cond_fini(p_cond);
100  ABTU_free(p_cond);
101  /* Return value */
102  *cond = ABT_COND_NULL;
103  return ABT_SUCCESS;
104 }
105 
152 {
153  ABTI_local *p_local = ABTI_local_get_local();
154 #ifndef ABT_CONFIG_ENABLE_VER_20_API
155  /* Argobots 1.x does not allow a tasklet to call this routine. */
156  if (ABTI_IS_ERROR_CHECK_ENABLED && p_local) {
157  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
158  ABTI_CHECK_TRUE(p_local_xstream->p_thread->type &
160  ABT_ERR_COND);
161  }
162 #endif
163  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
164  ABTI_CHECK_NULL_COND_PTR(p_cond);
165  ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex);
166  ABTI_CHECK_NULL_MUTEX_PTR(p_mutex);
167 
168  int abt_errno = ABTI_cond_wait(&p_local, p_cond, p_mutex);
169  ABTI_CHECK_ERROR(abt_errno);
170  return ABT_SUCCESS;
171 }
172 
228  const struct timespec *abstime)
229 {
230  ABTI_local *p_local = ABTI_local_get_local();
231  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
232  ABTI_CHECK_NULL_COND_PTR(p_cond);
233  ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex);
234  ABTI_CHECK_NULL_MUTEX_PTR(p_mutex);
235 
236  double tar_time = convert_timespec_to_sec(abstime);
237 
238  ABTI_thread thread;
239  thread.type = ABTI_THREAD_TYPE_EXT;
241 
242  ABTD_spinlock_acquire(&p_cond->lock);
243 
244  if (p_cond->p_waiter_mutex == NULL) {
245  p_cond->p_waiter_mutex = p_mutex;
246  } else {
247  if (p_cond->p_waiter_mutex != p_mutex) {
248  ABTD_spinlock_release(&p_cond->lock);
250  }
251  }
252 
253  /* Unlock the mutex that the calling ULT is holding */
254  ABTI_mutex_unlock(p_local, p_mutex);
255  ABT_bool is_timedout =
257  &p_cond->lock, tar_time,
259  (void *)p_cond);
260  /* Lock the mutex again */
261  ABTI_mutex_lock(&p_local, p_mutex);
262  return is_timedout ? ABT_ERR_COND_TIMEDOUT : ABT_SUCCESS;
263 }
264 
285 {
286  ABTI_local *p_local = ABTI_local_get_local();
287  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
288  ABTI_CHECK_NULL_COND_PTR(p_cond);
289 
290  ABTD_spinlock_acquire(&p_cond->lock);
291  ABTI_waitlist_signal(p_local, &p_cond->waitlist);
292  ABTD_spinlock_release(&p_cond->lock);
293 
294  return ABT_SUCCESS;
295 }
296 
317 {
318  ABTI_local *p_local = ABTI_local_get_local();
319  ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
320  ABTI_CHECK_NULL_COND_PTR(p_cond);
321 
322  ABTI_cond_broadcast(p_local, p_cond);
323  return ABT_SUCCESS;
324 }
325 
326 /*****************************************************************************/
327 /* Internal static functions */
328 /*****************************************************************************/
329 
330 static inline double convert_timespec_to_sec(const struct timespec *p_ts)
331 {
332  double secs;
333  secs = ((double)p_ts->tv_sec) + 1.0e-9 * ((double)p_ts->tv_nsec);
334  return secs;
335 }
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:1001
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:93
ABTI_mutex_lock
static void ABTI_mutex_lock(ABTI_local **pp_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:98
ABT_cond_free
int ABT_cond_free(ABT_cond *cond)
Free a condition variable.
Definition: cond.c:89
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:227
ABT_COND_NULL
#define ABT_COND_NULL
Definition: abt.h:1068
ABT_ERR_COND
#define ABT_ERR_COND
Error code: error related to a condition variable.
Definition: abt.h:323
ABTI_thread::type
ABTI_thread_type type
Definition: abti.h:375
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:120
ABTI_xstream::type
ABTI_xstream_type type
Definition: abti.h:270
ABTI_THREAD_TYPE_YIELDABLE
#define ABTI_THREAD_TYPE_YIELDABLE
Definition: abti.h:86
ABT_mutex
struct ABT_mutex_opaque * ABT_mutex
Mutex handle type.
Definition: abt.h:945
ABT_cond_memory
A struct that can be converted to ABT_cond.
Definition: abt.h:1172
ABTI_CHECK_NULL_COND_PTR
#define ABTI_CHECK_NULL_COND_PTR(p)
Definition: abti_error.h:258
ABTI_thread
Definition: abti.h:371
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTI_xstream
Definition: abti.h:264
ABT_ERR_INV_MUTEX
#define ABT_ERR_INV_MUTEX
Error code: invalid mutex.
Definition: abt.h:200
ABTI_THREAD_TYPE_EXT
#define ABTI_THREAD_TYPE_EXT
Definition: abti.h:81
ABTI_mutex_unlock
static void ABTI_mutex_unlock(ABTI_local *p_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:181
ABTI_waitlist_is_empty
static ABT_bool ABTI_waitlist_is_empty(ABTI_waitlist *p_waitlist)
Definition: abti_waitlist.h:283
ABTI_cond
Definition: abti.h:435
ABTI_CHECK_NULL_MUTEX_PTR
#define ABTI_CHECK_NULL_MUTEX_PTR(p)
Definition: abti_error.h:240
ABT_THREAD_STATE_BLOCKED
@ ABT_THREAD_STATE_BLOCKED
Definition: abt.h:421
abti.h
ABTI_thread::state
ABTD_atomic_int state
Definition: abti.h:381
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:114
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:262
ABTD_atomic_relaxed_store_int
static void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:996
ABTI_cond::p_waiter_mutex
ABTI_mutex * p_waiter_mutex
Definition: abti.h:437
ABT_SYNC_EVENT_TYPE_COND
@ ABT_SYNC_EVENT_TYPE_COND
Definition: abt.h:674
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:19
ABTI_cond_get_handle
static ABT_cond ABTI_cond_get_handle(ABTI_cond *p_cond)
Definition: abti_cond.h:43
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:59
ABT_cond_broadcast
int ABT_cond_broadcast(ABT_cond cond)
Broadcast a condition.
Definition: cond.c:316
convert_timespec_to_sec
static double convert_timespec_to_sec(const struct timespec *p_ts)
Definition: cond.c:330
ABT_cond_wait
int ABT_cond_wait(ABT_cond cond, ABT_mutex mutex)
Wait on a condition variable.
Definition: cond.c:151
ABT_ERR_COND_TIMEDOUT
#define ABT_ERR_COND_TIMEDOUT
Error code: a return value when a condition variable is timed out.
Definition: abt.h:330
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:217
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:436
ABT_cond
struct ABT_cond_opaque * ABT_cond
Condition variable handle type.
Definition: abt.h:959
ABTI_local
struct ABTI_local ABTI_local
Definition: abti.h:110
ABTI_cond_broadcast
static void ABTI_cond_broadcast(ABTI_local *p_local, ABTI_cond *p_cond)
Definition: abti_cond.h:80
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:130
ABTI_waitlist_signal
static void ABTI_waitlist_signal(ABTI_local *p_local, ABTI_waitlist *p_waitlist)
Definition: abti_waitlist.h:217
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:28
ABTI_cond::waitlist
ABTI_waitlist waitlist
Definition: abti.h:438
ABT_cond_signal
int ABT_cond_signal(ABT_cond cond)
Signal a condition.
Definition: cond.c:284
ABTI_mutex
Definition: abti.h:174